I have created a function that runs Newton's Method for approximating the solution to a function (defined as f). My function returns the better approximation for the root just fine, however it will not display the number of iterates performed in the function properly.
Here is my code:
#include <stdio.h>
#include <math.h>
#include <cstdlib>
#include <iostream>
double newton(double x_0, double newtonaccuracy);
double f(double x);
double f_prime(double x);
int main()
{
double x_0;
double newtonaccuracy;
int converged;
int iter;
printf("Enter the initial estimate for x : ");
scanf("%lf", &x_0);
_flushall();
printf("\n\nEnter the accuracy required : ");
scanf("%lf", &newtonaccuracy);
_flushall();
if (converged == 1)
{
printf("\n\nNewton's Method required %d iterations for accuracy to %lf.\n", iter, newtonaccuracy);
printf("\n\nThe root using Newton's Method is x = %.16lf\n", newton(x_0, newtonaccuracy));
}
else
{
printf("Newton algorithm didn't converge after %d steps.\n", iter);
}
system("PAUSE");
}
double newton(double x_0, double newtonaccuracy)
{
double x = x_0;
double x_prev;
int iter = 0;
do
{
iter++;
x_prev = x;
x = x_prev - f(x_prev)/f_prime(x_prev);
}
while (fabs(x - x_prev) > newtonaccuracy && iter < 100);
if (fabs(x - x_prev) <= newtonaccuracy)
{
int converged = 1;
}
else
{
int converged = 0;
}
return x;
}
double f(double x) {
return ( cos(2*x) - x );
}
double f_prime(double x)
{
return ( -2*sin(2*x)-1 );
}
To be as specific as possible, it is the line:
printf("\n\nNewton's Method required %d iterations for accuracy to %lf.\n", iter, newtonaccuracy);
that is giving me trouble. Every time I run this program it says "Newton's Method required 2686764 iterations..." however this can't be true, provided I have coded correctly (the max number of iterations my code allows is 100).
The variable iter used in main is not initialized or used in the newton function, where you use a local variable iter. You need to either pass iter to newton by reference or find a way to return it from the function.
Here is an example of a function taking some parameters by reference and modifying them:
double foo(double& initial_value, int& iterations)
{
initial_value *= 3.14159;
iterations = 42;
return initial_value/2.;
}
From the caller side:
double x + 12345.;
int iter = 0;
double y = foo(initial_value, iter);
Related
2nd task:
For a function f : R^n → R the gradient at a point ~x ∈ R^n is to be calculated:
- Implement a function
CMyVector gradient(CMyVector x, double (*function)(CMyVector x)),
which is given in the first parameter the location ~x and in the second parameter the function f as function pointer in the second parameter, and which calculates the gradient ~g = grad f(~x) numerically
by
gi = f(x1, . . . , xi-1, xi + h, xi+1 . . . , xn) - f(x1, . . . , xn)/h
to fixed h = 10^-8.
My currently written program:
Header
#pragma once
#include <vector>
#include <math.h>
class CMyVektor
{
private:
/* data */
int Dimension = 0;
std::vector<double>Vector;
public:
CMyVektor();
~CMyVektor();
//Public Method
void set_Dimension(int Dimension /* Aktuelle Dim*/);
void set_specified_Value(int index, int Value);
double get_specified_Value(int key);
int get_Vector_Dimension();
int get_length_Vektor();
double& operator [](int index);
string umwandlung()
};
CMyVektor::CMyVektor(/* args */)
{
Vector.resize(0, 0);
}
CMyVektor::~CMyVektor()
{
for (size_t i = 0; i < Vector.size(); i++)
{
delete Vector[i];
}
}
void CMyVektor::set_Dimension(int Dimension /* Aktuelle Dim*/)
{
Vector.resize(Dimension);
};
void CMyVektor::set_specified_Value(int index, int Value)
{
if (Vector.empty())
{
Vector.push_back(Value);
}
else {
Vector[index] = Value;
}
};
double CMyVektor::get_specified_Value(int key)
{
// vom intervall anfang - ende des Vectors
for (unsigned i = 0; i < Vector.size(); i++)
{
if (Vector[i] == key) {
return Vector[i];
}
}
};
int CMyVektor::get_Vector_Dimension()
{
return Vector.size();
};
// Berechnet den Betrag "länge" eines Vectors.
int CMyVektor::get_length_Vektor()
{
int length = 0;
for (size_t i = 0; i < Vector.size(); i++)
{
length += Vector[i]^2
}
return sqrt(length);
}
// [] Operator überladen
double& CMyVektor::operator [](int index)
{
return Vector[index];
}
main.cpp
#include <iostream>
#include "ClassVektor.h"
using namespace std;
CMyVektor operator+(CMyVektor a, CMyVektor b);
CMyVektor operator*(double lambda, CMyVektor a);
CMyVektor gradient(CMyVektor x, double (*funktion)(CMyVektor x));
int main() {
CMyVektor V1;
CMyVektor V2;
CMyVektor C;
C.set_Dimension(V1.get_length_Vector());
C= V1 + V2;
std::cout << "Addition : "<< "(";;
for (int i = 0; i < C.get_length_Vector(); i++)
{
std::cout << C[i] << " ";
}
std::cout << ")" << endl;
C = lamda * C;
std::cout << "Skalarprodukt: "<< C[0]<< " ";
}
// Vector Addition
CMyVektor operator+(CMyVektor a, CMyVektor b)
{
int ai = 0, bi = 0;
int counter = 0;
CMyVektor c;
c.set_Dimension(a.get_length_Vector());
// Wenn Dimension Gleich dann addition
if (a.get_length_Vector() == b.get_length_Vector())
{
while (counter < a.get_length_Vector())
{
c[counter] = a[ai] + b[bi];
counter++;
}
return c;
}
}
//Berechnet das Skalarprodukt
CMyVektor operator*(double lambda, CMyVektor a)
{
CMyVektor c;
c.set_Dimension(1);
for (unsigned i = 0; i < a.get_length_Vector(); i++)
{
c[0] += lambda * a[i];
}
return c;
}
/*
* Differenzenquotient : (F(x0+h)+F'(x0)) / h
* Erster Parameter die Stelle X - Zweiter Parameter die Funktion
* Bestimmt numerisch den Gradienten.
*/
CMyVektor gradient(CMyVektor x, double (*funktion)(CMyVektor x))
{
}
My problem now is that I don't quite know how to deal with the
CMyVector gradient(CMyVector x, double (*function)(CMyVector x))
function and how to define a function that corresponds to it.
I hope that it is enough information. Many thanks.
The function parameter is the f in the difference formula. It takes a CMyVector parameter x and returns a double value. You need to supply a function parameter name. I'll assume func for now.
I don't see a parameter for h. Are you going to pass a single small value into the gradient function or assume a constant?
The parameter x is a vector. Will you add a constant h to each element?
This function specification is a mess.
Function returns a double. How do you plan to turn that into a vector?
No wonder you're confused. I am.
Are you trying to do something like this?
You are given a function signature
CMyVector gradient(CMyVector x, double (*function)(CMyVector x))
Without knowing the exact definition I will assume, that at least the basic numerical vector operations are defined. That means, that the following statements compile:
CMyVector x {2.,5.,7.};
CMyVector y {1.,7.,4.};
CMyVector z {0.,0.,0.};
double a = 0.;
// vector addition and assigment
z = x + y;
// vector scalar multiplication and division
z = z * a;
z = x / 0.1;
Also we need to know the dimension of the CMyVector class. I assumed and will continue to do so that it is three dimensional.
The next step is to understand the function signature. You get two parameters. The first one denotes the point, at which you are supposed to calculate the gradient. The second is a pointer to the function f in your formula. You do not know it, but can call it on a vector from within your gradient function definition. That means, inside of the definition you can do something like
double f_at_x = function(x);
and the f_at_x will hold the value f(x) after that operation.
Armed with this, we can try to implement the formula, that you mentioned in the question title:
CMyVector gradient(CMyVector x, double (*function)(CMyVector x)) {
double h = 0.001;
// calculate first element of the gradient
CMyVector e1 {1.0, 0.0, 0.0};
double result1 = ( function(x + e1*h) - function(x) )/h;
// calculate second element of the gradient
CMyVector e2 {0.0, 1.0, 0.0};
double result2 = ( function(x + e2*h) - function(x) )/h;
// calculate third element of the gradient
CMyVector e3 {0.0, 0.0, 1.0};
double result3 = ( function(x + e3*h) - function(x) )/h;
// return the result
return CMyVector {result1, result2, result3};
}
There are several thing worth to mention in this code. First and most important I have chosen h = 0.001. This may like a very arbitrary choice, but the choice of the step size will very much impact the precision of your result. You can find a whole lot of discussion about that topic here. I took the same value that according to that wikipedia page a lot of handheld calculators use internally. That might not be the best choice for the floating point precision of your processor, but should be a fair one to start with.
Secondly the code looks very ugly for an advanced programmer. We are doing almost the same thing for each of the three dimensions. Ususally you would like to do that in a for loop. The exact way of how this is done depends on how the CMyVector type is defined.
Since the CMyVektor is just rewritting the valarray container, I will directly use the valarray:
#include <iostream>
#include <valarray>
using namespace std;
using CMyVektor = valarray<double>;
CMyVektor gradient(CMyVektor x, double (*funktion)(CMyVektor x));
const double h = 0.00000001;
int main()
{
// sum(x_i^2 + x_i)--> gradient: 2*x_i + 1
auto fun = [](CMyVektor x) {return (x*x + x).sum();};
CMyVektor d = gradient(CMyVektor{1,2,3,4,5}, fun);
for (auto i: d) cout << i<<' ';
return 0;
}
CMyVektor gradient(CMyVektor x, double (*funktion)(CMyVektor x)){
CMyVektor grads(x.size());
CMyVektor pos(x.size());
for (int i = 0; i<x.size(); i++){
pos[i] = 1;
grads[i] = (funktion(x + h * pos) - funktion(x))/ h;
pos[i] = 0;
}
return grads;
}
The prints out 3 5 7 9 11 which is what is expected from the given function and the given location
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
if (argc != 2) {
printf("Too many arguments.\n", argc );
return 1;
}
double n;
n = atof(argv[1]);
if (n<0) {
printf("Negative argument.\n");
return 1;
}
double r;
r = n;
int iteration;
iteration = 0;
while(calcError(n,r)<1e-6) {
iteration = iteration +1;
r = (r + n/r)/2;
printf(" %d. sqrt(%f)~= %f,error=%e\n",iteration,n,r,calcError(r,n));
}
printf("sqrt(%f)=%f to six places\n",n,r);
return 0;
}
int calcError (double n, double r) {
double delta;
delta = n-r*r;
delta = delta > 0 ? delta : -delta;
return 0;
}
Running this code generates an infinite while loop. I also get a warning stating: format '%e' expects argument of type 'double', but argument 5 has type 'int' [-Wformat]. Why is this?
calcError always returns 0, so
while(calcError(n,r)<1e-6)
is as good as
while(0 < 1e-6)
or
while(true)
As for the warning, the compiler says exactly what's wrong: calcError returns an int, but the format string provided by you (%e) need a double. This will yield Undefined Behavior. Changing the return type as below will fix this issue.
Looking at your code, I think you wanted to loop as long as the error was larger than 1e-6. If that's correct, you might want to modify your calcError to be as follows:
int calcError (double n, double r)
{
double delta;
delta = n-r*r;
delta = delta > 0 ? delta : -delta;
return delta;
}
which can be shortened to
double calcError(double n, double r)
{
return fabs(n-r*r);
}
and change the condition of your loop to loop until it's smaller:
while(calcError(n,r) > 1e-6)
In your calcError() function, you have,
return 0;
So in your expression, calcError() will always be zero.
and, (0 < 1e-6) is always true.
You have while(calcError(n,r)<1e-6) and calcError always returns 0, so of course your loop will go on forever. I think you meant to have calcError return delta instead of 0.
#include<iostream>
#include<cmath>
using namespace std;
int e=0.001;
double yk(int k,double x){
if(k==0) return 1;
return 0.5*(yk(k-1,x) + x/yk(k-1,x));
}
double square(double x,int k)
{
if(fabs(yk(k,x)*yk(k,x) - x)<e) return yk;
return square(x,k+1);
}
int main()
{
cout<<yk(5,2);
return 0;
}
I need to calculate the square root of a number with Newton's formula which calculates y[k] till fabs(y[k] * y[k] -x)>e (a small number like 0.0001);
So if sqrt (2)= 1.41421356237 and e=0.0001 my function must back 1.4142 .
..This is the program I wrote.. I know that it is buggy, so i will be very thankful if sb help me :)))
The variable e should be float or double.
The error you get is not because of the fabs function, it is because you are trying to return a pointer to the yk function, but square returns a double
#include <iostream>
#include <cmath>
using namespace std;
double e=0.001;
double yk(int k,double x){
if(k==0) return 1;
return 0.5*(yk(k-1,x) + x/yk(k-1,x));
}
double square(double x,int k)
{
double res = yk(k, x);
if (fabs(res*res - x) < e) return res;
return square(x,k+1);
}
int main()
{
cout << yk(5,2); // Actually you don't call square....
// it works even if you do square(2, 5), this way you get the root of two
// doing at least 5 iterations, and if it is not enough (error > e) the
// computer goes on until it gets an error < e
return 0;
}
I am trying to write a block of codes in C++ that calculates sinX value with Taylor's series.
#include <iostream>
using namespace std;
// exp example
#include <cstdio> // printf
#include <cmath> // exp
double toRadians(double angdeg) //convert to radians to degree
{ //x is in radians
const double PI = 3.14159265358979323846;
return angdeg / 180.0 * PI;
}
double fact(double x) //factorial function
{ //Simply calculates factorial for denominator
if(x==0 || x==1)
return 1;
else
x * fact(x - 1);
}
double mySin(double x) //mySin function
{
double sum = 0.0;
for(int i = 0; i < 9; i++)
{
double top = pow(-1, i) * pow(x, 2 * i + 1); //calculation for nominator
double bottom = fact(2 * i + 1); //calculation for denominator
sum = sum + top / bottom; //1 - x^2/2! + x^4/4! - x^6/6!
}
return sum;
}
int main()
{
double param = 45, result;
result = mySin(toRadians(param)); //This is my sin value
cout << "Here is my homemade sin : " << result << endl;
result = sin(param); //This is library value
cout << "Here is the API sin : " << result << endl;
return 0;
}
So my program works without any error. My output is exactly:
Here is my homemade sin : nan
Here is the API sin:0.850904
I know I am making a big logic mistake but I couldn't find it out. It is my second week with C++. I am more familiar with Java. I coded the same thing and It worked absolutely perfect. The answers matched each other.
Thanks for your time and attention!
in fact, you miss the return: x*fact(x-1); should be return x*fact(x-1);. You can see the compiler complaining if you turn the warnings on. For example, with GCC, calling g++ -Wall program.cpp gives Warning: control reaches end of non-void function for the factorial function.
The API sin also needs the angle in radians, so change result=sin(param); into result=sin(toRadians(param));. Generally, if in doubt about the API, consult the docs, like here.
Your codes seems to have some logical mistakes. Here is my corrected one:
#include <iostream>
using namespace std;
double radians(double degrees) // converts degrees to radians
{
double radians;
double const pi = 3.14159265358979323846;
radians = (pi/180)*degrees;
return radians;
}
double factorial(int x) //calculates the factorial
{
double fact = 1;
for(; x >= 1 ; x--)
{
fact = x * fact;
}
return fact;
}
double power(double x,double n) //calculates the power of x
{
double output = 1;
while(n>0)
{
output =( x*output);
n--;
}
return output;
}
float sin(double radians) //value of sine by Taylors series
{
double a,b,c;
float result = 0;
for(int y=0 ; y!=9 ; y++)
{
a= power(-1,y);
b= power(radians,(2*y)+1);
c= factorial((2*y)+1);
result = result+ (a*b)/c;
}
return result;
}
double n,output;
int main()
{
cout<<"enter the value\t";
cin>>n;
n = radians(n);
cout<< "\nthe value in radians is\t"<< n << "\n";
output = sin(n);
cout<< "\nsine of the given value is\t"<< output;
return 0;
}
The intention of this program was to use custom functions instead of libraries to make learning for others easy.
There are four user defined functions in this program.The first three user defined functions 'radians()', 'factorial()','power()', are apparently simple functions that perform operations as their name suggests.
The fourth function 'sin()' takes input in radians given by the function 'radians()'. The sin function uses Taylors series iterated term wise in the function's 'for(int y= 0;y!=9;y++)' loop till nine iterations to calculate the output.The 'for()' loop iterates the general mathematical expression: Term(n)=((-1)^n).(x^(2n+1))/(2n+1)!
sin(x)= x- x^3/3! + x^5/5! -x^7/7! + x^9/9!
=x-x^3/2*3 (1- x^2/4*5 + x^4/4*5*6*7 + x^6/4*5*6*7*8*9)
=x - x^3/2*3 {1- x^2/4*5(1- x^2/6*7 + x^4/6*7*8*9)}
=x - x^3/2*3 [{1- x^2/4*5 ( 1- x^2/6*7 (1- x^2/8*9))}]
=x(1 - x^2/2*3 [{1- x^2/4*5 ( 1- x^2/6*7 (1- x^2/8*9))}])
double sin_series_recursion(double x, int n){
static double r=1;
if(n>1){
r=1-((x*x*r)/(n*(n-1)));
return sin_series_recursion(x,n-2);
}else return r*x;
}
long time browser, first time asker here. I've written a number of scripts for doing various 1D numerical integration methods and compiled them into a library. I would like that library to be as flexible as possible regarding what it is capable of integrating.
Here I include an example: a very simple trapezoidal rule example where I pass a pointer to the function to be integrated.
// Numerically integrate (*f) from a to b
// using the trapezoidal rule.
double trap(double (*f)(double), double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += (*f)(xi); }
else { s += 2*(*f)(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works great for simple functions that only take one argument. Example:
double a = trap(sin,0,1);
However, sometimes I may want to integrate something that has more parameters, like a quadratic polynomial. In this example, the coefficients would be defined by the user before the integration. Example code:
// arbitrary quadratic polynomial
double quad(double A, double B, double C, double x) {
return (A*pow(x,2) + B*x + C);
}
Ideally, I would be able to do something like this to integrate it:
double b = trap(quad(1,2,3),0,1);
But clearly that doesn't work. I have gotten around this problem by defining a class that has the coefficients as members and the function of interest as a member function:
class Model {
double A,B,C;
public:
Model() { A = 0; B = 0; C = 0; }
Model(double x, double y, double z) { A = x; B = y; C = z; }
double func(double x) { return (A*pow(x,2)+B*x+C); }
};
However, then my integration function needs to change to take an object as input instead of a function pointer:
// Numerically integrate model.func from a to b
// using the trapezoidal rule.
double trap(Model poly, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += poly.func(xi); }
else { s += 2*poly.func(xi); }
}
s *= (b-a)/(2*N);
return s;
}
This works fine, but the resulting library is not very independent, since it needs the class Model to be defined somewhere. Also, ideally the Model should be able to change from user-to-user so I wouldn't want to fix it in a header file. I have tried to use function templates and functors to get this to work but it is not very independent since again, the template should be defined in a header file (unless you want to explicitly instantiate, which I don't).
So, to sum up: is there any way I can get my integration functions to accept arbitrary 1D functions with a variable number of input parameters while still remaining independent enough that they can be compiled into a stand-alone library? Thanks in advance for the suggestions.
What you need is templates and std::bind() (or its boost::bind() counterpart if you can't afford C++11). For instance, this is what your trap() function would become:
template<typename F>
double trap(F&& f, double a, double b) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi); }
// ^
else { s += 2* f(xi); }
// ^
}
s *= (b-a)/(2*N);
return s;
}
Notice, that we are generalizing from function pointers and allow any type of callable objects (including a C++11 lambda, for instance) to be passed in. Therefore, the syntax for invoking the user-provided function is not *f(param) (which only works for function pointers), but just f(param).
Concerning the flexibility, let's consider two hardcoded functions (and pretend them to be meaningful):
double foo(double x)
{
return x * 2;
}
double bar(double x, double y, double z, double t)
{
return x + y * (z - t);
}
You can now provide both the first function directly in input to trap(), or the result of binding the last three arguments of the second function to some particular value (you have free choice on which arguments to bind):
#include <functional>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
}
Of course, you can get even more flexibility with lambdas:
#include <functional>
#include <iostream>
int main()
{
trap(foo, 0, 42);
trap(std::bind(bar, std::placeholders::_1, 42, 1729, 0), 0, 42);
int x = 1729; // Or the result of some computation...
int y = 42; // Or some particular state information...
trap([&] (double d) -> double
{
x += 42 * d; // Or some meaningful computation...
y = 1; // Or some meaningful operation...
return x;
}, 0, 42);
std::cout << y; // Prints 1
}
And you can also pass your own stateful functors tp trap(), or some callable objects wrapped in an std::function object (or boost::function if you can't afford C++11). The choice is pretty wide.
Here is a live example.
What you trying to do is to make this possible
trap( quad, 1, 2, 3, 0, 1 );
With C++11 we have alias template and variadic template
template< typename... Ts >
using custom_function_t = double (*f) ( double, Ts... );
above define a custom_function_t that take a double and variable numbers of arguments.
so your trap function becomes
template< typename... Ts >
double trap( custom_function_t<Ts...> f, Ts... args, double a, double b ) {
int N = 10000;
double step = (b-a)/N;
double s = 0;
for (int i=0; i<=N; i++) {
double xi = a + i*step;
if (i == 0 || i == N) { s += f(xi, args...); }
else { s += 2*f(xi, args...); }
}
s *= (b-a)/(2*N);
return s;
}
Usage:
double foo ( double X ) {
return X;
}
double quad( double X, double A, double B, double C ) {
return(A*pow(x,2) + B*x + C);
}
int main() {
double result_foo = trap( foo, 0, 1 );
double result_quad = trap( quad, 1, 2, 3, 0, 1 ); // 1, 2, 3 == A, B, C respectively
}
Tested on Apple LLVM 4.2 compiler.