Recursive function outputs a wrong value - c++

In this code the output is 'r' instead of 'r0'
Instead of doing the operations it outputs me the first 'r' (equals 100) and does not do the process.
I´m trying to program an operation like (x_0 = x + (nt²/(2(x+(n(t-1)²/2(x+(n(t-3)²/2(x + (n(t-4)²...)²)²)²)²)²)²)²)²) in where the process is repeated until the variable 't' is '0'(because each time the operation is done 't' get a '-1').
#include <iostream>
#include "math.h"
using namespace std;
int operation(float r,
float r0,
float recursiva,
float operacion,
float recursivaPrincipal2,
float recursivaPrincipal,
float p,
float n,
long long t,
float q,
float potenciaQ,
float c,
float potenciaC,
float t2,
float division);
float r = 100;
float t = 10000;
float r0;
float recursiva;
float operacion;
float recursivaPrincipal2;
float recursivaPrincipal;
float p;
float n;
float q;
float potenciaQ;
float c;
float potenciaC;
float t2;
float division;
int main() {
r0 = r + operacion;
potenciaQ = pow(10,10);
q = 6 * potenciaQ;
potenciaC = pow(10,2);
c = 5 * potenciaC;
while (t = 10000, t = t - 1, t > 0) {
t2 = t * t;
n = q * t2;
operacion = n / recursivaPrincipal;
recursivaPrincipal2 = recursiva * recursiva;
recursivaPrincipal = 2 * recursivaPrincipal2;
recursiva = r + operacion;
if (t == 0) {
system("pause");
return 0;
}
cout << "Solucion: " << r0 << endl;
}
}
i want to do something like this
I'm so sorry if this code offended you (comments look like it) but I'm not very good, this is my first c++ code (and last I think)

The answer is based on what i get from your question
Please do expand your mathematical expression for t=3 and append an image of it
by far what i got from your expression you need this
float func(int t,int n,int x)
{
if (t==1)
{
return (x + (n/2)*(n/2)) * (x + (n/2)*(n/2));
}
return x + (n*t*t)/(2*func(t-1,n,x)) ;
}
According to the picture you have uploaded this is my code
Don't use 0 for n
#include<iostream>
using namespace std;
double partSolver(int x,int p, int n)
{
if(n==0) return 2*x*x;
double val = x - ( (p*n*n) / partSolver(x,p,n-1) );
return 2*val*val ;
}
double solver(int x,int p,int n)
{
return (n*n * 2) / partSolver(x,p,n-1);
}
int main()
{
cout<<"The Solution is: "<<solver(3,2,1)<<endl;
return 0;
}

Related

power series tayllor arrest criteria problem

Hi guys i created a c program to confront taylor taylor series of cosine and interpolation but i have a problem . The problem is about the function cosine (calculated by using taylor method) because the programme always gives me a degree of 3 , or 1 . My teacher said that i should use this arrest criteria
x^(2k)/(2k!)<t where t is tau in my code , the tolerance. Really thanks to anyone who can help me!
#include<stdio.h>
#include<math.h>
double read_tolerance();
double put_x();
void cosine(double,double,int &,double,double);
double Li(int,int,double[],double);
double Pn(int,double[],double[],double);
void interpo_Lagrange(int);
int main()
{
int k=1;
double cos_initial=1,a=1;
double tau=read_tolerance();
double x=put_x();
cosine (cos_initial,a,k,x,tau);
interpo_Lagrange(k+1);
return 0;
}
double read_tolerance()
{
double t;
printf("\n choose the value of tolerance: ");
scanf("%lf", &t);
return t;
}
double put_x()
{
double x;
printf("\nput value of x: ");
scanf("%lf",&x);
return x;
}
void cosine(double coseno,double a,int &k,double x,double tau)
{
do {
a *= pow(-1,k)*((x*x) / (2*k));
coseno += a;
k=k+2;
}while (a> tau);
printf("value of cosine of %lf is %lf\n",x,coseno);
printf("degree with taylor is ' %d\n",k);
return ;
}
double Li(int i, int n, double x[], double X){
int j;
double prod=1;
for(j=0;j<=n;j++){
if(j!=i)
prod=prod*(X-x[j])/(x[i]-x[j]);
}
return prod;
}
double Pn(int n, double x[], double y[], double X){
double sum=0;
int i;
for(i=0;i<=n;i++){
sum=sum+Li(i,n,x,X)*y[i];
}
return sum;
}
void interpo_Lagrange(int n)
{
int i;
printf("the number of data-points are %d:\n",n);
double x[n];
double y[n];
printf("Enter the x data-points:\n");
for(i=1;i<=n;i++){
x[i]=Pi*i/(8);
printf("%lf\n",x[i]);
}
printf("Enter the y data-points:\n");
for(i=1;i<=n;i++){
y[i]=cos(Pi*i/(8));
printf("%lf\n",y[i]);
}
double X;
printf("Enter the value of x for which you want the interpolated value of y(x):\n");
scanf("%lf",&X);
printf("The interpolated value is %lf",Pn(n,x,y,X));
}
The implementation of tayllor series is incorrect and here is the right one
do {
a *= -((x * x) / ((2 * k - 1) * (2 * k)));
coseno += a;
k = k + 1;
} while (fabs(a) > tau);
i hope this fixes your problem
The first issue is that the term can be negative. So the stopping criteria
must used the absolute value of it.
Another issue is that the used formula is not correct. The calculation of the denominator (fatorial) was not correct.
A last issue is that is is better a little bit that the function return the calculated value: more clear.
Output:
cos calculated = 0.707107
Error = -1.14623e-010
#include <iostream>
#include <cmath>
double cosine (double x, double tolerance) {
double x2 = x*x;
double term = 1;
double y = 1;
int sign = -1;
int k = 2;
do {
term *= x2/(k*(k-1));
y += sign * term;
k += 2;
sign = -sign;
} while (term > tolerance);
return y;
}
int main() {
double tolerance = 1.0e-6;
double angle = 3.141592/4;
double calculated = cosine (angle, tolerance);
double exact = cos(angle);
double err = calculated - exact;
std::cout << "cos calculated = " << calculated << std::endl;
std::cout << "Error = " << err << std::endl;
return 0;
}

Unknown error using the c++ eigen library

I am a graduate student at Florida State University studying financial mathematics. I am still a bit of a novice with C++ but I am trying to implement the Longstaff-Schwartz method for pricing of American options. Although, the algorithm in the journal is a bit daunting thus I am trying to convert the code that was written in Matlab and change it into C++. Essentially I am using the Matlab code as a guide.
I was referred by some stackexchange users to use the Eigen library which contains a good matrix class. Unfortunately the website here does not show me how to make my own function from the class. What I am stuck on is making a C++ function for the function in Matlab that does this:
Say t = 0:1/2:1 then in Matlab the output will be t = 0 0.500 1
So using the Eigen class I created a function called range to achieve the latter above. The function looks like this:
MatrixXd range(double min, double max, double N){
MatrixXd m(N,1);
double delta = (max-min)/N;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
m(i,j) = min + i*delta;
}
}
return m;
}
I do not have any errors on my IDE (Ecclipse) but when I run my code and test this function I get this error message:
c:\mingw\include\c++\6.2.0\eigen\src/Core/PlainObjectBase.h:736:7:
error: static assertion failed:
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED
I am not sure what is wrong. Any suggestions on achieving what I am trying to do or any suggestions at all are greatly appreciated.
Taking the suggestion by Martijn Courteaux, I changed $N$ into an int now but I now receive a new error that I do not understand:
c:\mingw\include\c++\6.2.0\eigen\src/Core/Matrix.h:350:7: error: static
assertion failed: THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
For sake of completeness I will post my whole code below:
#include <iostream>
#include <cmath>
#include <limits>
#include <algorithm>
#include <Eigen/Dense>
#include <Eigen/Geometry>
using namespace Eigen;
using namespace std;
double LaguerreExplicit(int R, double x); // Generates the (weighted) laguerre value
double payoff_Call(double S, double K); // Pay off of a call option
double generateGaussianNoise(double mu, double sigma); // Generates Normally distributed random numbers
double LSM(int T, double r, double sigma, double K, double S0, int N, int M, int R);
// T Expiration time
// r Riskless interest rate
// sigma Volatility
// K Strike price
// S0 Initial asset price
// N Number of time steps
// M Number of paths
// R Number of basis functions
MatrixXd range(double min, double max, int N);
int main(){
MatrixXd range(0, 1, 2);
}
double payoff_Call(double S, double K){
double payoff;
if((S - K) > 0)
{
payoff = S - K;
}else
{
payoff = 0.0;
}
return payoff;
}
double LaguerreExplicit(int R, double x){
double value;
if(R==0)
{
value = 1;
}
else if(R==1)
{
value = 0.5*(pow(x,2) - 4.0*x + 2);
}
else if(R==3)
{
value = (1.0/6.0)*(-1*pow(x,3) + 9*pow(x,2) - 18*x + 6);
}
else if(R==4)
{
value = (1.0/24.0)*(pow(x,4) - 16*pow(x,3) + 72*pow(x,2) - 96*x + 24);
}
else if(R==5)
{
value = (1.0/120.0)*(-1*pow(x,5) + 25*pow(x,4) - 200*pow(x,3) + 600*pow(x,2) - 600*x + 120);
}
else if (R==6)
{
value = (1.0/720.0)*(pow(x,6) - 36*pow(x,5) + 450*pow(x,4) - 2400*pow(x,3) + 5400*pow(x,2) - 4320*x + 720);
}
else{
cout << "Error!, R is out of range" << endl;
value = 0;
}
value = exp(-0.5*x)*value; // Weighted used in Longstaff-Scwartz
return value;
}
double generateGaussianNoise(double mu, double sigma)
{
const double epsilon = std::numeric_limits<double>::min();
const double two_pi = 2.0*M_PI;
static double z0, z1;
static bool generate;
generate = !generate;
if (!generate)
return z1 * sigma + mu;
double u1, u2;
do
{
u1 = rand() * (1.0 / RAND_MAX);
u2 = rand() * (1.0 / RAND_MAX);
}
while ( u1 <= epsilon );
z0 = sqrt(-2.0 * log(u1)) * cos(two_pi * u2);
z1 = sqrt(-2.0 * log(u1)) * sin(two_pi * u2);
return z0 * sigma + mu;
}
MatrixXd range(double min, double max, int N){
MatrixXd m(N,1);
double delta = (max-min)/N;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
m(i,j) = min + i*delta;
}
}
return m;
}
double LSM(int T, double r, double sigma, double K, double S0, int N, int M, int R){
double dt = T/N;
MatrixXd m(T,1);
return 0;
}
Here is the corrected function code that I fixed:
VectorXd range(double min, double max, int N){
VectorXd m(N + 1);
double delta = (max-min)/N;
for(int i = 0; i <= N; i++){
m(i) = min + i*delta;
}
return m;
}
Mistake is here:
MatrixXd range(double min, double max, double N){
MatrixXd m(N,1);
N is a double. The arguments of MatrixXd::MatrixXd(int, int) are int.
You presumably want to make N an int.
In regard to your edit:
Second mistake is here:
MatrixXd range(0, 1, 2);
in the main() function. Not sure what you are trying to do here, but that constructor is not valid. EDIT: Ah I believe I have an idea. You are trying to call your function named range. Do this like this:
MatrixXd result = range(0.0, 1.0, 2);

How do I express this?

I'm trying to work out how to write the following:
total = (value * 0.95 ^ 0) + (value * 0.95 ^ 1) + (value * 0.95 ^ 2) ...
or:
x = (y * z ^ 0) + (y * z ^ 1) + (y * z ^ 2) + (y * z ^ 3) ...
This expresses how to calculate x for 4 iterations, but how can I express this to work with a variable number of iterations? Obviously I could create a loop and add the values together, but I'd really like to find a single equation that solves this.
I'm using c++ but I guess this isn't really a language specific problem (sorry I literally don't know where else to ask this question!).
Any ideas?
Thanks,
Chris.
There is no need for a loop here, you "just" need to employ some maths.
Note that you can rewrite that as
y * (z0 + z1 + ... + zn)
Now, the series
z0 + z1 + ... + zn
sums to
(z(n+1) - 1) / (z - 1)
so your equation would be
x = y * (z(n+1) - 1) / (z - 1)
Equation-wise solving, this is a geometric series and can therefore be calculated with
double geometric_series(double y, double z, int N) {
return y * (std::pow(z, N) - 1.0) / (z - 1.0);
}
but the same result can be obtained with some fun C++ metaprogramming: if you know the number of iterations in advanced and you're allowed to use C++17 features and fold expressions you could do as follows
template<std::size_t... N>
double calculate_x(double y, double z, std::index_sequence<N...>) { // [0;N[
auto f = [](double y_p, double z_p, double exp) {
return y_p * std::pow(z_p, exp);
};
return (f(y, z, N) + ...);
}
template <std::size_t N>
auto calculate_x(double y, double z) {
return calculate_x(y, z, std::make_index_sequence<N>{});
}
Alternatively this can also be done with pre-C++17 templates
template <int N>
double calculate_x(double y, double z) {
return calculate_x<N-1>(y, z) + (y * std::pow(z, N - 1));
}
template <>
double calculate_x<0>(double, double) {
return 0;
}
Otherwise a simpler solution would be to just use a loop
double calculate_x_simple(double y, double z, int N) {
double ret = 0.0;
for (int i = 0 ; i < N ; ++i)
ret += y * std::pow(z, i);
return ret;
}
Driver for the code above
int main() {
// x = (y * z ^ 0) + (y * z ^ 1) + (y * z ^ 2) + (y * z ^ 3)
double y = 42.0;
double z = 44.5;
std::cout << (calculate_x<3>(y, z) == calculate_x_simple(y, z, 3)); // 1
}
As you mentioned, it seems reasonable to use a loop. But if you know the amount of iterations at compile time, you could use templates like this:
template <int n>
double foo(double y, double z)
{
return foo<n-1>(y, z) + y * std::pow(z, n);
}
template <>
double foo<-1>(double, double)
{
return 0;
}
With just a little bit of optimisation this will unfold to a single equation.
Example:
#include <iostream>
#include <cmath>
template <int n>
double foo(double y, double z)
{
return foo<n-1>(y, z) + y * std::pow(z, n);
}
template <>
double foo<-1>(double, double)
{
return 0;
}
int main()
{
std::cout << foo<2>(2,3) << std::endl;
}
Output: 26
If a loop would be the only option:
double x = 0;
int n = 5;
for(int exponent = 0; exponent <= n; ++exponent)
x += y*pow(z, exponent);
you can just use math.pow function with a for loop
#include <stdio.h>
#include <math.h>
int main(void) {
int i;
int n = 5;
double y = 0.5;
double z = 0.3;
double answer = 0;
for (i = 0 ; i < n ; i++)
answer += y * pow(z,i);
printf("%f", answer);
return 0;
}
It can be expressed as a sum from n=0 to m. It can be expressed in a single formula, according to wolframalpha.
Don't know if this fulfills your purpose, but you can use recursion(which in real terms is a loop only :) )
int x = evaluate(y, z, count);
int evaluate(y,z, count)
{
if (count <= 0)
return 0;
return (evaluate(y, z, count-1) + y*z^count);
}
Using n as the number of iterations,
#include <cmath>
double foo(double y, double z, int n)
{
double x =0;
for(int i = 0 ; i<n; ++i){
x+=y*std::pow(z,i);
}
return x;
}
Where std::pow is the power function.

terminated by signal SIGSEGV (Address boundary error) in recursive function

I'm trying to implement Karatsuba algorithm for multiplication. I'm kinda follow the pseudocode in this wiki page. But I'm always getting this error:
terminated by signal SIGSEGV (Address boundary error)
When I replaced the lines that cause the recursion to happen with something else:
z0 = multiply(a, c);
z1 = multiply(b, d);
z2 = multiply(a+b, c+d);
the error disappeared.
Here's my code:
#include <iostream>
#include <math.h>
long int multiply(int x, int y);
int get_length(int val);
int main()
{
int x = 0, y = 0;
long int result = 0;
std::cout << "Enter x: ";
std::cin >> x;
std::cout << "Enter y: ";
std::cin >> y;
result = multiply(x, y);
std::cout << "Result: " << result << std::endl;
return 0;
}
long int multiply(int x, int y)
{
if(x < 10 || y < 10) {
return x * y;
}
int x_len = get_length(x);
int y_len = get_length(y);
long int z0 = 0 , z1 = 0, z2 = 0;
int a = 0, b = 0, c = 0, d = 0;
a = x / pow(10, x_len);
b = x - (a * pow(10, x_len));
c = y / pow(10, y_len);
d = y - (c * pow(10, y_len));
z0 = multiply(a, c);
z1 = multiply(b, d);
z2 = multiply(a+b, c+d);
return (pow(10, x_len) * z0) + (pow(10, x_len/2) * (z2 - z1 - z0)) + z1;
}
int get_length(int val)
{
int count = 0;
while(val > 0) {
count++;
val /= 10;
}
return count;
}
I found the problem cause.
It was because of these lines:
a = x / pow(10, x_len);
b = x - (a * pow(10, x_len));
c = y / pow(10, y_len);
d = y - (c * pow(10, y_len));
It should be x_len / 2 instead of x_len and the same with y_len. Since it causes the recursion to be infinite.
You are using the pow function to do integer powers. It is not an integer function. Code your own pow function that's suitable for your application. For example:
int pow(int v, int q)
{
int ret = 1;
while (q > 1)
{
ret*=v;
q--;
}
return ret;
}
Make sure to put an int pow(int, int); at the top.

AltiVec vec_msum equivalent for float values

Is anybody aware of a method to achieve vec_msum functionality against a vector of float values?
I'm quite new to SIMD, and although I think I'm starting to make sense of it - there are still a few puzzles.
My end goal is to rewrite the function "convolve_altivec" (as found in the accepted answer for this question) such that it accepts input parameters as float values, instead of short's.
That is, the prototype should be
float convolve_altivec(const float *a, const float *b, int n)
I'm trying to match the functionality provided by the original non-optimised function below:
float convolve(const float *a, const float *b, int n)
{
float out = 0.f;
while (n --)
out += (*(a ++)) * (*(b ++));
return out;
}
My initial efforts have seen me trying to port an existing SSE version of this same function to altivec instructions.
For a float version you need vec_madd.
Here's a float version of the previous 16 bit int version and test harness I posted in response to your earlier question:
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <altivec.h>
static float convolve_ref(const float *a, const float *b, int n)
{
float sum = 0.0f;
int i;
for (i = 0; i < n; ++i)
{
sum += a[i] * b[i];
}
return sum;
}
static inline float convolve_altivec(const float *a, const float *b, int n)
{
float sum = 0.0f;
vector float vsum = { 0.0f, 0.0f, 0.0f, 0.0f };
union {
vector float v;
float a[4];
} usum;
vector float *pa = (vector float *)a;
vector float *pb = (vector float *)b;
assert(((unsigned long)a & 15) == 0);
assert(((unsigned long)b & 15) == 0);
while (n >= 4)
{
vsum = vec_madd(*pa, *pb, vsum);
pa++;
pb++;
n -= 4;
}
usum.v = vsum;
sum = usum.a[0] + usum.a[1] + usum.a[2] + usum.a[3];
a = (float *)pa;
b = (float *)pb;
while (n --)
{
sum += (*a++ * *b++);
}
return sum;
}
int main(void)
{
const int n = 1002;
vector float _a[n / 4 + 1];
vector float _b[n / 4 + 1];
float *a = (float *)_a;
float *b = (float *)_b;
float sum_ref, sum_test;
int i;
for (i = 0; i < n; ++i)
{
a[i] = (float)rand();
b[i] = (float)rand();
}
sum_ref = convolve_ref(a, b, n);
sum_test = convolve_altivec(a, b, n);
printf("sum_ref = %g\n", sum_ref);
printf("sum_test = %g\n", sum_test);
printf("%s\n", fabsf((sum_ref - sum_test) / sum_ref) < 1.0e-6 ? "PASS" : "FAIL");
return 0;
}