I have to calculate the value of arctan(x) . I have calculated the value of this by evaluating the following series :
Arctan (x) = x – x^3/3 + x^5/5 – x^7/7 + x^9/9 - …
But the following code can not calculate the actual value. For example, calculate_angle(1) returns 38.34 . Why?
const double DEGREES_PER_RADIAN = 57.296;
double calculate_angle(double x)
{
int power=5,count=3;
double term,result,prev_res;
prev_res = x;
result= x-pow(x,3)/3;
while(abs(result-prev_res)<1e-10)
{
term = pow(x,power)/power;
if(count%2==0)
term = term*(-1);
prev_res=result;
result=result+term;
++count;
power+=2;
// if(count=99)
// break;
}
return result*DEGREES_PER_RADIAN;
}
EDIT: I found the culprit. You forgot to include stdlib.h, where the function abs resides. You must have ignored the warning about abs being implicitly declared. I checked that removing the include yields the result 38.19 and including it yields the result ~45.
The compiler is not required to stop compilation when an undeclared function is being used (in this case abs). Instead, it is allowed to make assumptions on how the function is declared (in this case, wrong one.)
Besides, like other posters already stated, your use of abs is inappropriate as it returns an int, not a double or float. The condition in the while should be >1e-100 not <1e-100. The 1e-100 is also too small.
--
You forgot to increase count and power after calculating the first two summands:
prev_res = x;
result= x-pow(x,3)/3;
count = 4; <<<<<<
power = 5; <<<<<<
while(abs(result-prev_res)<1e-100)
{
term = pow(x,power)/power;
if(count%2==1)
term = term*(-1);
Also I consider your use of the count variable counterintuitive: it is intialized with 3 like if it denotes the last used power; but then, loop iterations increase it by 1 instead of 2 and you decide the sign by count%2 == 1 as opposed to power%4 == 3
The series converges to tan^{-1} x, but not very fast. Consider the series when x=1:
1 - 1/3 + 1/5 - 1/7 + 1/9 - ...
What is the error when truncating at the 1/9 term? It's around 1/9. To get 10^{-100} accuracy, you would need to have 10^{100} terms. The universe would end before you'd get that. And, catastrophic round-off error and truncation error would make the answer utterly unreliable. You only have 14 digits to play with for doubles.
Look at reference works like Abramowitz and Stegun [AMS 55] or the new NIST Digital Library of Mathematical Functions at http://dlmf.nist.gov to see how these are done in practice. Often, one uses Padé approximants instead of Taylor series. Even when you stick with Taylor series, you often use Chebyshev approximation to cut down on the total error.
I also recommend Numerical Methods that [Usually] Work, by Forman Acton. Or the Numerical Recipes in ... series.
Your sign is the wrong way around after the first two terms. It should be:
if(count%2==0)
term = term*(-1);
Your comparison is the wrong way around in the while condition. Also, you're expecting an unrealistically high level of precision. I would suggest something more like this:
while(fabs(result-prev_res)>1e-8)
Finally, you'll get a more accurate result with a better value for DEGREES_PER_RADIAN. Why not something like this:
const double DEGREES_PER_RADIAN = 180/M_PI;
Related
So i like to make my life hard, i've got a task to calculate the sum of
1 + 1/2 + 1/3 + 1/4 +.... + 1/n.
The conditions is to not use iterations but a closed formula. On this post : https://math.stackexchange.com/questions/3367037/sum-of-1-1-2-1-3-1-n
I've found a pretty neat looking solution: 1+1/2+1/3+⋯+1/n=γ+ψ(n+1)
where γ is Euler's constant and ψ is the digamma function.
For digamma I'm using the boost c++ libraries and I calculate the Euler's constant using exp(1.0).
The problem is that I don't get the right answer. Here is my code:
#include <iostream>
#include <cmath>
#include <boost/math/special_functions/digamma.hpp>
int main(){
int x;
const double g = std::exp(1.0);
std::cin >> x;
std::cout<<g + boost::math::digamma(x+1);
return 0;
}
Thanks in advance) !
Euler is known for having a lot of things named for him.
That can easily become confusing, as seems to be case here.
What you are adding to the digamma function result is Euler's number. You are supposed to add Euler's constant, which is a different number named after Euler.
You can find the correct number in boost as boost::math::constants::euler, e.g.:
const double g = boost::math::constants::euler<double>();
(Thanks #Eljay)
For some context on such how much is named after Leonhard Euler and how confusing it can get, here is the Wikipedia page's section on just numbers named after him, counting 11 different items: https://en.wikipedia.org/wiki/List_of_things_named_after_Leonhard_Euler#Numbers
Goal: perform rolling window calculations on panel data in Stata with variables PanelVar, TimeVar, and Var1, where the window can change within a loop over different window sizes.
Problem: no access to SSC for the packages that would take care of this (like rangestat)
I know that
by PanelVar: gen Var1_1 = Var1[_n]
produces a copy of Var1 in Var1_1. So I thought it would make sense to try
by PanelVar: gen Var1SumLag = sum(Var1[(_n-3)/_n])
to produce a rolling window calculation for _n-3 to _n for the whole variable. But it fails to produce the results I want, it just produces zeros.
You could use sum(Var1) - sum(Var1[_n-3]), but I also want to be able to make the rolling window left justified (summing future observations) as well as right justified (summing past observations).
Essentially I would like to replicate Python's ".rolling().agg()" functionality.
In Stata _n is the index of the current observation. The expression (_n - 3) / _n yields -2 when _n is 1 and increases slowly with _n but is always less than 1. As a subscript applied to extract values from observations of a variable it always yields missing values given an extra rule that Stata rounds down expressions so supplied. Hence it reduces to -2, -1 or 0: in each case it yields missing values when given as a subscript. Experiment will show you that given any numeric variable say numvar references to numvar[-2] or numvar[-1] or numvar[0] all yield missing values. Otherwise put, you seem to be hoping that the / yields a set of subscripts that return a sequence you can sum over, but that is a long way from what Stata will do in that context: the / is just interpreted as division. (The running sum of missings is always returned as 0, which is an expression of missings being ignored in that calculation: just as 2 + 3 + . + 4 is returned as 9 so also . + . + . + . is returned as 0.)
A fairly general way to do what you want is to use time series operators, and this is strongly preferable to subscripts as (1) doing the right thing with gaps (2) automatically working for panels too. Thus after a tsset or xtset
L0.numvar + L1.numvar + L2.numvar + L3.numvar
yields the sum of the current value and the three previous and
L0.numvar + F1.numvar + F2.numvar + F3.numvar
yields the sum of the current value and the three next. If any of these terms is missing, the sum will be too; a work-around for that is to return say
cond(missing(L3.numvar), 0, L3.numvar)
More general code will require some kind of loop.
Given a desire to loop over lags (negative) and leads (positive) some code might look like this, given a range of subscripts as local macros i <= j
* example i and j
local i = -3
local j = 0
gen double wanted = 0
forval k = `i'/`j' {
if `k' < 0 {
local k1 = -(`k')
replace wanted = wanted + L`k1'.numvar
}
else replace wanted = wanted + F`k'.numvar
}
Alternatively, use Mata.
EDIT There's a simpler method, to use tssmooth ma to get moving averages and then multiply up by the number of terms.
tssmooth ma wanted1=numvar, w(3 1)
tssmooth ma wanted2=numvar, w(0 1 3)
replace wanted1 = 4 * wanted1
replace wanted2 = 4 * wanted2
Note that in contrast to the method above tssmooth ma uses whatever is available at the beginning and end of each panel. So, the first moving average, the average of the first value and the three previous, is returned as just the first value at the beginning of each panel (when the three previous values are unknown).
#include<iostream>
using namespace std;
double log(double x,int n)
{
static double p = x ;
double s;
if(n==1)
return x;
else
{
s=log(x,n-1);
p*=x;
if(n%2==0)
return s - (p/n);
else
return s + (p/n);
}
}
int main()
{
double r = log(1,15);
cout << r;
return 0;
}
I tried writing the above function for evaluating the log(1+x) function using its taylor series with recursion. But it didn't gave the result as I expected.
Eg :
ln(2) = 0.693 whereas my code gave 0.725. In the above code, n represents the number of terms.
Also I am new to this platform, so can I say that the above question is complete or does it need some additional information for further explanation?
There is nothing wrong with that piece of code: this has obviously got to do with the rate of convergence of the Taylor series.
If you take n = 200 instead of n = 15 in your code, the approximation error will be low enough that the first two decimals of the exact solution ln(2) = 0.693147... will be the correct ones.
The more you increase the n parameter, the better approximation you will get of ln(2).
Your program does converge to the right number, just very slowly...
log(1,15) returns 0.725, as you noticed, log(1,50) is 0.683, log(1,100) is 0.688, and log(1,200) is 0.691. That's getting close to the number you expected, but still a long way to go...
So there is no C++ or recursion bug in your code - you just need to find a better Taylor series to calculate log(X). Don't look for a Taylor series for log(1+x) - these will typically assume x is small, and converge quickly for small x, not for x=1.
I the following code
f = lambda x: 2**(x+1)
f_sym = f(sympy.symbol.symbols('x'))
print f_sym.args
The output is (2, x+1).
Why the output is not x?
I have some functions composed with functions like the previous one and the final expressions do not simplify:
f = lambda x, y: (x/y)**.5
f_sym = f(sympy.symbol.symbols('x'), sympy.symbol.symbols('y'))
symbols = f_sym.free_symbols
aux = np.asarray([sympy.derive_by_array(f_sym, symbol) for symbol in [symbols]])
uc_matrix = np.diag(sympy.symbols(','.join(['u_{%s}'%symbol for symbol in symbols])))**2
uf = ((np.dot(np.dot(aux,uc_matrix), aux.T))**.5)[0][0]
y = uf/f_sym
print (y**2).expand().simplify()
In SymPy terms, f_sym is the expression
Pow(Integer(2), Add(Symbol('x'), Integer(1)))
as you can find from srepr(f_sym). So, the function is "raising to power" and the arguments of that function are 2 and x+1.
If you want specifically the exponent, f_sym.args[1] will return that.
It's important to recognize that f_sym is not a function. It does not take any arguments and does not return anything. It's a SymPy expression. There is no special meaning of x+1 within this expression: it's just one of its parts, like the number 2 is.
To answer your follow-up question: the expression will simplify to
u_{x}**2/(4*x**2) + u_{y}**2/(4*y**2)
if you use the rational number sympy.Rational(1, 2) instead of floating-point number .5 in the exponent. Floating point numbers are poison for SymPy. Other ways to achieve the same effect, with less to type:
use sympy.sqrt function instead of raising to power 1/2.
write sympy.S(1)/2 which creates the same Rational object because 1 is turned into a SymPy object prior to division.
Reference: Python numbers vs. SymPy Numbers
What would be the most efficient algorithm to solve a linear equation in one variable given as a string input to a function? For example, for input string:
"x + 9 – 2 - 4 + x = – x + 5 – 1 + 3 – x"
The output should be 1.
I am considering using a stack and pushing each string token onto it as I encounter spaces in the string. If the input was in polish notation then it would have been easier to pop numbers off the stack to get to a result, but I am not sure what approach to take here.
It is an interview question.
Solving the linear equation is (I hope) extremely easy for you once you've worked out the coefficients a and b in the equation a * x + b = 0.
So, the difficult part of the problem is parsing the expression and "evaluating" it to find the coefficients. Your example expression is extremely simple, it uses only the operators unary -, binary -, binary +. And =, which you could handle specially.
It is not clear from the question whether the solution should also handle expressions involving binary * and /, or parentheses. I'm wondering whether the interview question is intended:
to make you write some simple code, or
to make you ask what the real scope of the problem is before you write anything.
Both are important skills :-)
It could even be that the question is intended:
to separate those with lots of experience writing parsers (who will solve it as fast as they can write/type) from those with none (who might struggle to solve it at all within a few minutes, at least without some hints).
Anyway, to allow for future more complicated requirements, there are two common approaches to parsing arithmetic expressions: recursive descent or Dijkstra's shunting-yard algorithm. You can look these up, and if you only need the simple expressions in version 1.0 then you can use a simplified form of Dijkstra's algorithm. Then once you've parsed the expression, you need to evaluate it: use values that are linear expressions in x and interpret = as an operator with lowest possible precedence that means "subtract". The result is a linear expression in x that is equal to 0.
If you don't need complicated expressions then you can evaluate that simple example pretty much directly from left-to-right once you've tokenised it[*]:
x
x + 9
// set the "we've found minus sign" bit to negate the first thing that follows
x + 7 // and clear the negative bit
x + 3
2 * x + 3
// set the "we've found the equals sign" bit to negate everything that follows
3 * x + 3
3 * x - 2
3 * x - 1
3 * x - 4
4 * x - 4
Finally, solve a * x + b = 0 as x = - b/a.
[*] example tokenisation code, in Python:
acc = None
for idx, ch in enumerate(input):
if ch in '1234567890':
if acc is None: acc = 0
acc = 10 * acc + int(ch)
continue
if acc != None:
yield acc
acc = None
if ch in '+-=x':
yield ch
elif ch == ' ':
pass
else:
raise ValueError('illegal character "%s" at %d' % (ch, idx))
Alternative example tokenisation code, also in Python, assuming there will always be spaces between tokens as in the example. This leaves token validation to the parser:
return input.split()
ok some simple psuedo code that you could use to solve this problem
function(stinrgToParse){
arrayoftokens = stringToParse.match(RegexMatching);
foreach(arrayoftokens as token)
{
//now step through the tokens and determine what they are
//and store the neccesary information.
}
//Use the above information to do the arithmetic.
//count the number of times a variable appears positive and negative
//do the arithmetic.
//add up the numbers both positive and negative.
//return the result.
}
The first thing is to parse the string, to identify the various tokens (numbers, variables and operators), so that an expression tree can be formed by giving operator proper precedences.
Regular expressions can help, but that's not the only method (grammar parsers like boost::spirit are good too, and you can even run your own: its all a "find and recourse").
The tree can then be manipulated reducing the nodes executing those operation that deals with constants and by grouping variables related operations, executing them accordingly.
This goes on recursively until you remain with a variable related node and a constant node.
At the point the solution is calculated trivially.
They are basically the same principles that leads to the production of an interpreter or a compiler.
Consider:
from operator import add, sub
def ab(expr):
a, b, op = 0, 0, add
for t in expr.split():
if t == '+': op = add
elif t == '-': op = sub
elif t == 'x': a = op(a, 1)
else : b = op(b, int(t))
return a, b
Given an expression like 1 + x - 2 - x... this converts it to a canonical form ax+b and returns a pair of coefficients (a,b).
Now, let's obtain the coefficients from both parts of the equation:
le, ri = equation.split('=')
a1, b1 = ab(le)
a2, b2 = ab(ri)
and finally solve the trivial equation a1*x + b1 = a2*x + b2:
x = (b2 - b1) / (a1 - a2)
Of course, this only solves this particular example, without operator precedence or parentheses. To support the latter you'll need a parser, presumable a recursive descent one, which would be simper to code by hand.