I am to write a function that attempts to find the zero of a function using Newton's Method.
I have my function and derivative of x^7-1000
double function(double x) {
return pow(x, 7) - 1000;
}
double derivative(double x) {
return 7 * pow(x, 6);
}
I also have Newton's function
using fx = double(*)(double);
double newtons( fx f, fx df, double x0, double e )
{
double x1{};
while( true ) {
x1 = x0 - f( x0 ) / df( x0 );
if( std::abs( x1 - x0 ) <= e ) break;
x0 = x1;
}
return x1;
}
How do I call the functions to my int main?
That's easy:
#include <iostream>
#include "my_functions.h"
int main(){
std::cout << newtons(function, derivative, 10.5, 1.0e-5) << std::endl;
}
Note (tx #martinbonner): using templates and the stl, you can make it even more generic: using lambda expressions, existing functions, ... anything 'invokeable'.
template<typename F>
double newtons(F f, F df, double x0, double e) {
... // same as your code
}
// usage:
auto x = newtons(std::sin, std::cos, 0.5, 1e-5);
auto x2 = newtons(
[](double d){ return d*d + 2*d - 1; },
[](double d){ return 2*d + 2; },
0,
1.0e-5);
Trivially as follows (assuming everything is in scope)
int main() {
std::cout << newtons(function, derivative,
10.5 /* Start point */, 0.00001 /* Error delta */);
}
Live example
Related
I am trying to use this library for some work. In the example, which is given on their website, they use an operator for defining gradient calculation. I want to use a method,i.e., getGradient, instead of an operator. I have tried several ways, including std::bind(), &Rosenbrock::getGradient. None of them works fine. Any idea how this can be done? I don't need a full answer, just hint will be enough.
#include <Eigen/Core>
#include <iostream>
#include <LBFGS.h>
using Eigen::VectorXd;
using namespace LBFGSpp;
class Rosenbrock
{
private:
int n;
public:
Rosenbrock(int n_) : n(n_) {}
double operator()(const VectorXd& x, VectorXd& grad);
double getGradient(const VectorXd& x, VectorXd& grad);
};
double Rosenbrock::operator()(const VectorXd& x, VectorXd& grad){
double fx = 0.0;
for(int i = 0; i < n; i += 2)
{
double t1 = 1.0 - x[i];
double t2 = 10 * (x[i + 1] - x[i] * x[i]);
grad[i + 1] = 20 * t2;
grad[i] = -2.0 * (x[i] * grad[i + 1] + t1);
fx += t1 * t1 + t2 * t2;
}
return fx;
}
double Rosenbrock::getGradient(const VectorXd& x, VectorXd& grad){
double fx = 0.0;
for(int i = 0; i < n; i += 2)
{
double t1 = 1.0 - x[i];
double t2 = 10 * (x[i + 1] - x[i] * x[i]);
grad[i + 1] = 20 * t2;
grad[i] = -2.0 * (x[i] * grad[i + 1] + t1);
fx += t1 * t1 + t2 * t2;
}
return fx;
}
int main(int argc, char** argv){
const int n = 10;
// Set up parameters
LBFGSParam<double> param;
param.epsilon = 1e-6;
param.max_iterations = 100;
// Create solver and function object
LBFGSSolver<double> solver(param);
Rosenbrock fun(n);
// Initial guess
VectorXd x = VectorXd::Zero(n);
double fx;
//int niter = solver.minimize(fun, x, fx);
int niter = solver.minimize(std::bind(Rosenbrock::getGradient, fun, _1, _2), x, fx);
// I want to do something similar to this
std::cout << niter << " iterations" << std::endl;
std::cout << "x = \n" << x.transpose() << std::endl;
std::cout << "f(x) = " << fx << std::endl;
return 0;
}
What about:
struct Bind
{
Rosenbrock & impl;
template <typename X, typename Y> // Template here because I'm lazy writing the full type
double operator () (X x, Y y) { return impl.getGradient(x, y); }
Bind(Rosenbrock & impl) : impl(impl) {}
};
// Then use Bind with your solver:
Bind b(fun);
int niter = solver.minimize(b);
// Example with a template (replace X, Y by the argument signature of the method you are binding)
template <typename T, double (T::*Func)(X, Y)>
struct Bind
{
T & impl;
double operator()(X x, Y y) { return (impl.*Func)(x, y); }
Bind(T & ref) : impl(ref) {}
};
// Using like
Bind<Rosenbrock, &Rosenbrock::getGradient> b(fun);
The above Bind class can be a template. It can be a lambda. You're just redirecting the operator() to the method in the binder's operator ().
I have issues with memory leaks on a C++ function that I have sourced into R through Rcpp. This result in a sudden abortion of my R session, without returning any specific error message.
What is weird to me is that if in function_test I move double lower =1; and double upper = value2; inside the for loop and edited them by also adding 'i': double lower =1 + i; and double upper = value2 + i; the function works without aborting my R session.
The code below is sourced in R using the function sourceCpp from Rcpp R package. I run the function with the following values:
R function:
function_test(value1=4000, value2=4000, alpha = 5e-04)
C++ code sourced in R:
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
#define EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
#include <Eigen/Eigen>
#include <RcppNumerical.h>
#include <Rcpp.h>
using namespace Rcpp;
using namespace Numer;
// [[Rcpp::export]]
double func1(double t, double alpha, double beta){
double term1 = (( 2.0 * log(t - 0.5)) + 1) / 25.0;
int N;
if (t == 1 || t == 2) {
N = 2;
}else{
if (t <= 44) {
N = t;
}else{
N = 44;
}
}
NumericVector term_up(N);
term_up[0] = 0;
term_up[1] = term1;
double res = std::accumulate(term_up.begin(), term_up.end(), 0.0);
double int_final = (1/(25.0*t)) * (1 - (0.96)*res);
return int_final;
}
class Func1PDF: public Func
{
private:
double alpha;
double beta;
public:
Func1PDF(double alpha_, double beta_) : alpha(alpha_), beta(beta_) {}
double operator()(const double& t) const{
return func1(t, alpha, beta);
}
};
// [[Rcpp::export]]
double integrate_func(double lower, double upper, double alpha, double beta)
{
Func1PDF f(alpha, beta);
double err_est;
int err_code;
const double res = integrate(f, lower, upper, err_est, err_code);
return res;
}
// [[Rcpp::export]]
NumericVector function_test(double value1, double value2, double alpha) {
NumericVector res(value1);
double lower = 1;
double upper = value2;
for(int i=1;i<=value1;i++){
double beta = i;
res[i-1] = integrate_func(lower, upper, alpha, beta);
}
return res;
}
The idea is to call similar Runge-Kutta function templates in a loop instead of doing it one by one. I've looked at similar solutions, I also tried void*, but was not able to apply to my problem due to conversion errors.
EDIT: these function templates are supposed to be used with fixed types, it's an overkill, but I would like to see whether there is an elegant solution.
Here is the full code:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <functional>
template <typename X, typename F, typename H = double>
X runge_kutta1(const X &x, const F &f, H h)
{
return x + h * f(x);
}
template <typename X, typename F, typename H = double>
X runge_kutta2(const X &x, const F &f, H h)
{
X k1 = f(x);
return x + 0.5 * h * (k1 + f(x + h * k1));
}
struct pair
{
double v;
double w;
pair(double v, double w)
: v{v}, w{w}
{
}
};
inline pair operator*(double h, pair p)
{
return {h * p.v, h * p.w};
}
inline pair operator+(pair p1, pair p2)
{
return {p1.v + p2.v, p1.w + p2.w};
}
inline std::ostream &operator<<(std::ostream &stream, const pair &p)
{
stream << p.v << ", " << p.w;
return stream;
}
int main() {
{
double x = 0.0;
double x1 = 1.0;
double lambda = 2;
double h = 1.0E-3;
pair p{1.0 / lambda, 0.0};
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
while (x + h < x1)
{
p = runge_kutta1(p, cat, h);
x = x + h;
}
p = runge_kutta1(p, cat, x1 - x);
pair expected = {cosh(lambda * x1) / lambda, sinh(lambda * x1)};
pair error = p + -1.0 * expected;
std::cout << std::setprecision(18) << "runge_kutta1:\nFinal result: " << p << "\n";
std::cout << "Error: " << error << "\n\n";
}
{
double x = 0.0;
double x1 = 1.0;
double lambda = 2;
double h = 1.0E-3;
pair p{1.0 / lambda, 0.0};
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
while (x + h < x1)
{
p = runge_kutta2(p, cat, h);
x = x + h;
}
p = runge_kutta2(p, cat, x1 - x);
pair expected = {cosh(lambda * x1) / lambda, sinh(lambda * x1)};
pair error = p + -1.0 * expected;
std::cout << "runge_kutta2:\nFinal result: " << p << "\n";
std::cout << "Error: " << error << "\n";
}
}
What I would like to have (the actual algorithm is simplified for the sake of readability):
std::vector<?> functions{runge_kutta1, runge_kutta2}; // two just as an example
double p = 1.0;
double h = 1.0E-3;
double lambda = 2;
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
for (const auto& func : functions) {
double t = func(p, cat, h);
std::cout << t << "\n";
}
You can not have a pointer to a function template. You can only have a pointer to specific instantiation of the template. In a same manner, you can't pack a template into std::function - only a specific instantiation of it.
And you can only put objects of the same type in the container - so your pointers will have to be of the same type (i.e. the function they point to should accept the same type of arguments and return the same type).
std::function will have the same limitation - all std::functions inside the container must be of the same type, in terms of return value and arguments.
When I compile the following:
#include "stdafx.h"
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
using namespace std;
#define A 10
double psi(double x);
double qgaus(double(*func)(double), double a, double b);
double normalize();
double psi(double x) {
return pow(sin(M_PI_2*x/ A), 2);
}
double qgaus(double(*func)(double), double a, double b) {
double xr, xm, dx, s;
static double x[] = { 0.0, 0.1488743389, 0.4333953941, 0.6794095682,0.8650633666,0.9739065285 };
static double w[] = { 0.0, 0.2955242247, 0.2692667193, 0.2190863625,0.1494513491,0.0666713443 };
xm = 0.5*(b + a);
xr = 0.5*(b - a);
s = 0;
for (int j = 1; j <= 5; j++) {
dx = xr*x[j];
s += w[j] * ((*func)(xm + dx) + (*func)(xm - dx));
}
return s *= xr;
}
double normalize() {
double N;
N = 1 / sqrt(qgaus(psi, 0.0, A));
return N;
}
int main()
{
double Norm = normalize();
cout << Norm << endl;
return 0;
}
This code compiles without an error. However when I try to put two of the routines into a class as shown here with the changes.
class PsiC {
public:
double psi(double x);
double normalize();
};
double PsiC::normalize() {
PsiC my_psi;
double N;
N = 1 / sqrt(qgaus(my_psi.psi, 0.0, A));
return N;
}
Now using the following in main:
PsiC my_psi;
double Norm = my_psi.normalize();
cout << Norm << endl;
The statement N = 1 / sqrt(qgaus(my_psi.psi, 0.0, A)); gives the compiler error:
'func': function call missing argument list; use '&func' to create a pointer to member.
Note: I only have two member in this class now; however, I intend to add more member later.
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.