Recursion on Integration Approximation Function - c++

I am attempting to approximate integrals using an adaptive Trapezoidal Rule.
I have a coarse integral approximation:
//Approximates the integral of f across the interval [a,b]
double coarse_app(double(*f)(double x), double a, double b) {
return (b - a) * (f(a) + f(b)) / 2.0;
}
I have a fine integral approximation:
//Approximates the integral of f across the interval [a,b]
double fine_app(double(*f)(double x), double a, double b) {
double m = (a + b) / 2.0;
return (b - a) / 4.0 * (f(a) + 2.0 * f(m) + f(b));
}
This is made adaptive by summing the approximation across decreasing portions of the given interval until either the recursion level is too high or the coarse and fine approximation are very close to one another:
//Adaptively approximates the integral of f across the interval [a,b] with
// tolerance tol.
double trap(double(*f)(double x), double a, double b, double tol) {
double q = fine_app(f, a, b);
double r = coarse_app(f, a, b);
if ((currentLevel >= minLevel) && (abs(q - r) <= 3.0 * tol)) {
return q;
} else if (currentLevel >= maxLevel) {
return q;
} else {
++currentLevel;
return (trap(f, a, b / 2.0, tol / 2.0) + trap(f, a + (b / 2.0), b, tol / 2.0));
}
}
If I manually calculate an integral by breaking it up into sections and using fine_app on it, I get a very good approximation. However, when I use the trap function, which should do this for me, all of my results are far too small.
For example, trap(square, 0, 2.0, 1.0e-2) gives the output 0.0424107, where the square function is defined as x^2. However, the output should be around 2.667. This is far worse than doing a single run of fine_app on the entire interval, which gives a value of 3.
Conceptually, I believe I have it implemented correctly, but there is something about C++ recursion which is not doing what I expect it to.
First time programming in C++, so all improvements are welcome.

I'm assuming you have currentLevel defined somewhere else. You don't want to do that. You also calculate your midpoints incorrectly.
Take a = 3, b = 5:
[a, b / 2.0] = [3, 2.5]
[a + b / 2.0, b] = 2.5, 3]
The correct points should be [3, 4] and [4, 5]
The code should look like this:
double trap(double(*f)(double x), double a, double b, double tol, int currentLevel) {
double q = fine_app(f, a, b);
double r = coarse_app(f, a, b);
if ((currentLevel >= minLevel) && (abs(q - r) <= 3.0 * tol)) {
return q;
} else if (currentLevel >= maxLevel) {
return q;
} else {
++currentLevel;
return (trap(f, a, (a + b) / 2.0, tol / 2, currentLevel) + trap(f, (a + b) / 2.0, b, tol / 2, currentLevel));
}
}
You can add a helper function so you don't have to specify currentLevel:
double integrate(double (*f)(double x), double a, double b, double tol)
{
return trap(f, a, b, tol, 1);
}
If I call this as integrate(square, 0, 2, 0.01) I get the answer of 2.6875, which means you need an even lower tolerance to converge to the correct result of 8/3 = 2.6666...7. You can check the exact error bound on this by using the error terms for Simpson's method.

Related

How does this algorithm to calculate square root work?

I have found a piece of mathematical code to compute the square root of a real value. I obviously understand the code itself, but I must say that I badly understand the math logic of that algorithm. How does it work exactly?
inline
double _recurse(const double &_, const double &_x, const double &_y)
{ double _result;
if(std::fabs(_y - _x) > 0.001)
_result = _recurse(_, _y, 0.5 * (_y + _ / _y));
else
_result = _y;
return _result;
}
inline
double sqrt(const double &_)
{ return _recurse(_, 1.0, 0.5 * (1.0 + _)); }
Assume that you want to compute √a and have found an approxmation x. You want to improve that approximation by adding some correction δ to x. In other terms, you want to establish
x + δ = √a
or
(x + δ)² = x² + 2xδ + δ² = a
If you neglect the small term δ², you can solve for δ and get
δ ~ (a - x²)/(2x)
and finally
x + δ ~ (a + x²)/(2x) = (a/x + x)/2.
This process can be iterated and converges very quickly to √a.
E.g. for a=2 and the initial value x=1, we get the approximations
1, 3/2, 17/12, 577/408, 665857/470832, ...
and the corresponding squares,
1, 2.25, 2.00694444..., 2.0000060073049..., 2.0000000000045...

NTRUEncrypt: can't properly find GCD of two polynomials using decribed in open source standard algorithms, fail to define if inverse of poly exists

I've implemented algorithms for finding an inverse of a polynomial as described at onboard security resourses, but these algorithms imply that GCD of poly that I want to invert and X^N - 1 is 1.
For proper NTRU implementation I need to randomly generate small polynomials and define if their inverse exist, for now I don't have such functionality.
In order to get it work i tried to implement Euclidean algorithm as described in documentation for NTRU Open Source project. But I found some things very inconsistent which bugs me off.
Division and Euclidean algorithms can be found on page 19 of named document.
So, in division algorithm the inputs are polynomials a and b. It is stated that polynomial b must be of degree N-1.
Pseudocode for division algorithm (taken from this answer):
a) Set r := a and q := 0
b) Set u := (b_N)^–1 mod p
c) While deg r >= N do
1) Set d := deg r(X)
2) Set v := u × r_d × X^(d–N)
3) Set r := r – v × b
4) Set q := q + v
d) Return q, r
In order to find GCD of two polynomials, one must call Euclidean algorithm with inputs a (some polynomial) and X^N-1. These inputs are then passed to division algorighm.
Question is: how can X^N - 1 be passed into division algorithm if it is clearly stated that second parameter should be poly with degree N-1 ?
Ignoring this issue, there's still things I do not understand:
what is N in division algorithm? Is it N from NTRU parameters or is it degree of polynomial b?
either way, how can condition c) ever be true? NTRU operates with polynomials of degree less than N
For the greater context, here is my C++ implementation of Euclidean and Division algorithms. Given the inputs a = {-1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1}, b = {-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1}, p = 3 and N = 11 it enters endless loop inside division algorithm
using tPoly = std::deque<int>;
std::pair<tPoly, tPoly> divisionAlg(tPoly a, tPoly b, int p, int N)
{
tPoly r = a;
tPoly q{0};
int b_degree = degree(b);
int u = Helper::getInverseNumber(b[b_degree], p);
while (degree(r) >= N)
{
int d = degree(r);
tPoly v = genXDegreePoly(d-N); // X^(d-N)
v[d-N] = u*r[d]; // coefficient of v
r -= multiply(v, b, N);
q += v;
}
return {q, r};
}
struct sEucl
{
sEucl(int U=0, int V=0, int D=0)
: u{U}
, v{V}
, d{D}
{}
tPoly u;
tPoly v;
tPoly d;
};
sEucl euclidean(tPoly a, tPoly b, int p, int N)
{
sEucl res;
if ((degree(b) == 0) && (b[0] == 0))
{
res = sEucl(1, 0);
res.d = a;
Helper::printPoly(res.d);
return res;
}
tPoly u{1};
tPoly d = a;
tPoly v1{0};
tPoly v3 = b;
while ((0 != degree(v3)) && (0 != v3[0]))
{
std::pair<tPoly, tPoly> division = divisionAlg(d, v3, p, N);
tPoly q = division.first;
tPoly t3 = division.second;
tPoly t1 = u;
t1 -= PolyMath::multiply(q, v1, N);
u = v1;
d = v3;
v1 = t1;
v3 = t3;
}
d -= multiply(a, u, N);
tPoly v = divide(d, b).first;
res.u = u;
res.v = v;
res.d = d;
return res;
}
Additionally, polynomial operations used in this listing may be found at github page
I accidentally googled the answer. I don't really need to calculate GCD to pick a random invertable polynomial, I just need to choose the right amount of 1 and 0 (for binary) or -1, 0 and 1 (for ternary) for my random poly.
Please, consider this question solved.

Recursive algorithm for cos taylor series expansion c++

I recently wrote a Computer Science exam where they asked us to give a recursive definition for the cos taylor series expansion. This is the series
cos(x) = 1 - x^2/2! + x^4/4! + x^6/6! ...
and the function signature looks as follows
float cos(int n , float x)
where n represents the number in the series the user would like to calculate till and x represents the value of x in the cos function
I obviously did not get that question correct and I have been trying to figure it out for the past few days but I have hit a brick wall
Would anyone be able to help out getting me started somewhere ?
All answers so far recompute the factorial every time. I surely wouldn't do that. Instead you can write :
float cos(int n, float x)
{
if (n > MAX)
return 1;
return 1 - x*x / ((2 * n - 1) * (2 * n)) * cos(n + 1, x);
}
Consider that cos returns the following (sorry for the dots position) :
You can see that this is true for n>MAX, n=MAX, and so on. The sign alternating and powers of x are easy to see.
Finally, at n=1 you get 0! = 1, so calling cos(1, x) gets you the first MAX terms of the Taylor expansion of cos.
By developing (easier to see when it has few terms), you can see the first formula is equivalent to the following :
For n > 0, you do in cos(n-1, x) a division by (2n-3)(2n-2) of the previous result, and a multiplication by x². You can see that when n=MAX+1 this formula is 1, with n=MAX then it is 1-x²/((2MAX-1)2MAX) and so on.
If you allow yourself helper functions, then you should change the signature of the above to float cos_helper(int n, float x, int MAX) and call it like so :
float cos(int n, float x) { return cos_helper(1, x, n); }
Edit : To reverse the meaning of n from degree of the evaluated term (as in this answer so far) to number of terms (as in the question, and below), but still not recompute the total factorial every time, I would suggest using a two-term relation.
Let us define trivially cos(0,x) = 0 and cos(1,x) = 1, and try to achieve generally cos(n,x) the sum of the n first terms of the Taylor series.
Then for each n > 0, we can write, cos(n,x) from cos(n-1,x) :
cos(n,x) = cos(n-1,x) + x2n / (2n)!
now for n > 1, we try to make the last term of cos(n-1,x) appear (because it is the closest term to the one we want to add) :
cos(n,x) = cos(n-1,x) + x² / ((2n-1)2n) * ( x2n-2 / (2n-2)! )
By combining this formula with the previous one (adapting it to n-1 instead of n) :
cos(n,x) = cos(n-1,x) + x² / ((2n-1)2n) * ( cos(n-1,x) - cos(n-2,x) )
We now have a purely recursive definition of cos(n,x), without helper function, without recomputing the factorial, and with n the number of terms in the sum of the Taylor decomposition.
However, I must stress that the following code will perform terribly :
performance wise, unless some optimization allows to not re-evaluate a cos(n-1,x) that was evaluated at the previous step as cos( (n-1) - 1, x)
precision wise, because of cancellation effects : the precision with which we get x2n-2 / (2n-2)! is very bad
Now this disclaimer is in place, here comes the code :
float cos(int n, float x)
{
if (n < 2)
return n;
float c = x * x / (2 * (n - 1) * 2 * n);
return (1-c) * cos(n-1, x) + c * cos(n-2, x);
}
cos(x)=1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!.....
=1-x^2/2 (1 - x^2/3*4 + x^4/3*4*5*6 -x^6/3*4*5*6*7*8)
=1 - x^2/2 {1- x^2/3*4 (1- x^2/5*6 + x^4/5*6*7*8)}
=1 - x^2/2 [1- x^2/3*4 {1- x^2/5*6 ( 1- x^2/7*8)}]
double cos_series_recursion(double x, int n, double r=1){
if(n>0){
r=1-((x*x*r)/(n*(n-1)));
return cos_series_recursion(x,n-2,r);
}else return r;
}
A simple approach that makes use of static variables:
double cos(double x, int n) {
static double p = 1, f = 1;
double r;
if(n == 0)
return 1;
r = cos(x, n-1);
p = (p*x)*x;
f = f*(2*n-1)*2*n;
if(n%2==0) {
return r+p/f;
} else {
return r-p/f;
}
}
Notice that I'm multiplying 2*n in the operation to get the next factorial.
Having n align to the factorial we need makes this easy to do in 2 operations: f = f * (n - 1) then f = f * n.
when n = 1, we need 2!
when n = 2, we need 4!
when n = 3, we need 6!
So we can safely double n and work from there. We could write:
n = 2*n;
f = f*(n-1);
f = f*n;
If we did this, we would need to update our even/odd check to if((n/2)%2==0) since we're doubling the value of n.
This can instead be written as f = f*(2*n-1)*2*n; and now we don't have to divide n when checking if it's even/odd, since n is not being altered.
You can use a loop or recursion, but I would recommend a loop. Anyway, if you must use recursion you could use something like the code below
#include <iostream>
using namespace std;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
float Cos(int n, float x) {
if (n == 0) return 1;
return Cos(n-1, x) + (n%2 ? -1 : 1) * pow (x, 2*n) / (fact(2*n));
}
int main()
{
cout << Cos(6, 3.14/6);
}
Just do it like the sum.
The parameter n in float cos(int n , float x) is the l and now just do it...
Some pseudocode:
float cos(int n , float x)
{
//the sum-part
float sum = pow(-1, n) * (pow(x, 2*n))/faculty(2*n);
if(n <= /*Some predefined maximum*/)
return sum + cos(n + 1, x);
return sum;
}
The usual technique when you want to recurse but the function arguments don't carry the information that you need, is to introduce a helper function to do the recursion.
I have the impression that in the Lisp world the convention is to name such a function something-aux (short for auxiliary), but that may have been just a limited group in the old days.
Anyway, the main problem here is that n represents the natural ending point for the recursion, the base case, and that you then also need some index that works itself up to n. So, that's one good candidate for extra argument for the auxiliary function. Another candidate stems from considering how one term of the series relates to the previous one.

Discrete binary search

Can someone please explain discrete binary search with an example?
I read about it on the above link, and got a basic idea about what it is, but I still don't understand the code part and how it is practically implemented.
Basically, assume that
You have a function f(x) which is monotonically increasing
(decreasing) on the interval [a, b].
f(a) < C < f(b)
You want to find x such that f(x) = C.
Then you can use binary search to find x. Essentially, you half the possible interval for the variable x each time.
To implement it, do something along the lines of:
#define EPS 1E-9
double f(double x)
{
///some monotonically increasing function on [a, b], for example f(x) = x^3:
return x*x*x;
}
double binarySearch(double C, double a, double b)
{
double low = a, high = b;
double mid;
while(abs(low-high) > EPS)
{
mid = low + (high - low) / 2;
if f(mid) < C
low = mid;
else
high = mid;
}
return mid;
}

"double" does not print decimals

i was wondering why in this program, "pi_estimated" wouldn't print out as a number with decimal places although the variable was declared as a "double". However, it prints out an integer.
double get_pi(double required_accuracy)
{
double pi_estimation=0.0;
int x,y;
double p=0.0,q=0.0,r=0.0;
int D=0;
for(int N=1;N<=1e2;N++)
{
x = rand()%100;
p = (x/50.0 - 1.0)/100.0;
y = rand()%100;
q = (y/50.0 - 1.0)/100.0;
r = p*p + q*q;
if((sqrt(r))<1.0)
{
D++;
pi_estimation = 4.0*(double (D/N));
}
if(double (4/(N+1)) < (required_accuracy*pi_estimation/100.0))
{
cout<<pi_estimation<<endl;
return (pi_estimation);
}
}
}
int main()
{
double pi_approx=0.0, a, actual_accuracy=0.0;
for(a=0.1;a>=1e-14;a/=10)
{
pi_approx = get_pi(a);
actual_accuracy = (fabs((pi_approx - M_PI)/(M_PI)))*100.0;
cout<<actual_accuracy<<endl;
}
}
This line is the culprit:
pi_estimation = 4.0*(double (D/N));
Since D and N are both ints, D/N is an int. Casting the int to a double cannot magically make decimals appear out of nowhere.
Here's the line, fixed:
pi_estimation = 4.0 * (((double) D) / N));
You could also multiply first, so you don't need so many parens:
pi_estimation = 4.0 * D / N;
D is being multiplied by 4.0, so it becomes a double because double * int = double. Then it's divided by N. Since (x * y) / z === x * (y / z) (associative property), the expressions are equivalent.
The problem is here:
pi_estimation = 4.0*(double (D/N));
D and N are both integers, so D/N is an integer that you are casting to a double and then multiplying by 4.0.
You want to do this:
pi_estimation = 4.0 * (static_cast<double>(D) / N));
Since D and N are both integral types, D/N is performed in integer arithmetic; the cast to double happens too late as precision is lost prior to the cast.
One fix is to write 4.0 * D / N. This will ensure that everything is calculated in floating point. (Since * and / have the same precedence, you don't need to write (double).)