Two apparently similar functions give a different result. Why? - c++

I am using Rcpp to integrate a piece of C++ code in R. I am implementing a function in C++ in two ways:
// [[Rcpp::export]]
double rhobiweight(double x,double k = 2.0){
double rho = 1.0;
if(abs(x)<k){
rho = 1.0-pow((1.0-pow(x/k,2)),3);
}
return rho/Erho(k) ;
}
// [[Rcpp::export]]
double rhobiweight2(double x,double k = 2.0){
double rho = 1.0-pow((1.0-pow(x/k,2)),3);
if(abs(x)>k){
rho = 1.0;
}
return rho/Erho(k) ;
}
If the x-value is between 2 and 3, I get different results of these functions. I can't figure out why.
> set.seed(1)
> x = 3*rnorm(10^5)
> c = x
> c2 = x
> for(i in 1:length(x)){
+ c[i] = rhobiweight(x[i])
+ c2[i] = rhobiweight2(x[i])
+ }
> print(sum(c-c2))
[1] -18564.31

The problem comes from your if statement inside the function. The negative of < is >=. so you should either replace < with <= in one function or > with >= in the other, depending on the expected behaviour.
Your problem happens for value between 2.0 and 2.9 inclusive because the abs(int) will always return 2 for this range.
abs(x) takes an int an return an int. Your double x is implicitly conversion to an int in your case.

Related

Representation of Fourier series depends on tabulation points

Well, I had task to create function that does Fourier series with some mathematical function, so I found all the formulas, but the main problem is when I change count of point on some interval to draw those series I have very strange artifact:
This is Fourier series of sin(x) on interavl (-3.14; 314) with 100 point for tabulation
And this is same function with same interval but with 100000 points for tabulation
Code for Fourier series coeficients:
void fourieSeriesDecompose(std::function<double(double)> func, double period, long int iterations, double *&aParams, double *&bParams){
aParams = new double[iterations];
aParams[0] = integrateRiemans(func, 0, period, 1000);
for(int i = 1; i < iterations; i++){
auto sineFunc = [&](double x) -> double { return 2 * (func(x) * cos((2 * x * i * M_PI) / period)); };
aParams[i] = integrateRiemans(sineFunc, -period / 2, period / 2, 1000) / period;
}
bParams = new double[iterations];
for(int i = 1; i < iterations; i++){
auto sineFunc = [&](double x) -> double { return 2 * (func(x) * sin(2 * (x * (i + 1) * M_PI) / period)); };
bParams[i] = integrateRiemans(sineFunc, -period / 2, period / 2, 1000) / period;
}
}
This code I use to reproduce function using found coeficients:
double fourieSeriesCompose(double x, double period, long iterations, double *aParams, double *bParams){
double y = aParams[0];
for(int i = 1; i < iterations; i++){
y += sqrt(aParams[i] * aParams[i] + bParams[i] * bParams[i]) * cos((2 * i * x * M_PI) / period - atan(bParams[i] / aParams[i]));
}
return y;
}
And the runner code
double period = M_PI * 2;
auto startFunc = [](double x) -> double{ return sin(x); };
fourieSeriesDecompose(*startFunc, period, 1000, aCoeficients, bCoeficients);
auto readyFunc = [&](double x) -> double{ return fourieSeriesCompose(x, period, 1000, aCoeficients, bCoeficients); };
tabulateFunc(readyFunc);
scaleFunc();
//Draw methods after this
see:
How to compute Discrete Fourier Transform?
So if I deciphered it correctly the aParams,bParams represent the real and imaginary part of the result then the angles in sin and cos must be the same but you have different! You got this:
auto sineFunc = [&](double x) -> double { return 2*(func(x)*cos((2* x* i *M_PI)/period));
auto sineFunc = [&](double x) -> double { return 2*(func(x)*sin( 2*(x*(i+1)*M_PI)/period));
as you can see its not the same angle. Also what is period? You got iterations! if it is period of the function you want to transform then it should be applied to it and not to the kernel ... Also integrateRiemans does what? its the nested for loop to integrate the furrier transform? Btw. hope that func is real domain otherwise the integration/sumation needs both real and imaginary part not just one ...
So what you should do is:
create (cplx) table of the func(x) data on the interval you want with iterations samples
so for loop where x = x0+i*(x1-x0)/(iterations-1) and x0,x1 is the range you want the func to sample. Lets call it f[i]
for (i=0;i<iteration;i++) f[i]=func(x0+i*(x1-x0)/(iterations-1));
furrier transform it
something like this:
for (i=0;i<iteration;i++) a[i]=b[i]=0;
for (j=0;j<iteration;j++)
for (i=0;i<iteration;i++)
{
a[j]+=f[i]*cos(-2.0*M_PI*i*j/iterations);
b[j]+=f[i]*sin(-2.0*M_PI*i*j/iterations);
}
now a[],b[] should hold your slow DFT result ... beware integer rounding ... depending on compiler you might need to cast some stuff to double to avoid integer rounding.

Fsolve equivalent in C++

I am trying to replicate Matlab's Fsolve as my project is in C++ solving an implicit RK4 scheme. I am using the NLopt library using the NLOPT_LD_MMA algorithm. I have run the required section in matlab and it is considerably faster. I was wondering whether anyone had any ideas of a better Fsolve equivalent in C++? Another reason is that I would like f1 and f2 to both tend to zero and it seems suboptimal to calculate the L2 norm to include both of them as NLopt seems to only allow a scalar return value from the objective function. Does anyone have any ideas of an alternative library or perhaps using a different algorithm/constraints to more closely replicate the default fsolve.
Would it be better (faster) perhaps to call the python scipy.minimise.fsolve from C++?
double implicitRK4(double time, double V, double dt, double I, double O, double C, double R){
const int number_of_parameters = 2;
double lb[number_of_parameters];
double ub[number_of_parameters];
lb[0] = -999; // k1 lb
lb[1] = -999;// k2 lb
ub[0] = 999; // k1 ub
ub[1] = 999; // k2 ub
double k [number_of_parameters];
k[0] = 0.01;
k[1] = 0.01;
kOptData addData(time,V,dt,I,O,C,R);
nlopt_opt opt; //NLOPT_LN_MMA NLOPT_LN_COBYLA
opt = nlopt_create(NLOPT_LD_MMA, number_of_parameters);
nlopt_set_lower_bounds(opt, lb);
nlopt_set_upper_bounds(opt, ub);
nlopt_result nlopt_remove_inequality_constraints(nlopt_opt opt);
// nlopt_result nlopt_remove_equality_constraints(nlopt_opt opt);
nlopt_set_min_objective(opt,solveKs,&addData);
double minf;
if (nlopt_optimize(opt, k, &minf) < 0) {
printf("nlopt failed!\n");
}
else {
printf("found minimum at f(%g,%g,%g) = %0.10g\n", k[0],k[1],minf);
}
nlopt_destroy(opt);
return V + (1/2)*dt*k[0] + (1/2)*dt*k[1];```
double solveKs(unsigned n, const double *x, double *grad, void *my_func_data){
kOptData *unpackdata = (kOptData*) my_func_data;
double t1,y1,t2,y2;
double f1,f2;
t1 = unpackdata->time + ((1/2)-(1/6)*sqrt(3));
y1 = unpackdata->V + (1/4)*unpackdata->dt*x[0] + ((1/4)-(1/6)*sqrt(3))*unpackdata->dt*x[1];
t2 = unpackdata->time + ((1/2)+(1/6)*sqrt(3));
y2 = unpackdata->V + ((1/4)+(1/6)*sqrt(3))*unpackdata->dt*x[0] + (1/4)*unpackdata->dt*x[1];
f1 = x[0] - stateDeriv_implicit(t1,y1,unpackdata->dt,unpackdata->I,unpackdata->O,unpackdata->C,unpackdata->R);
f2 = x[1] - stateDeriv_implicit(t2,y2,unpackdata->dt,unpackdata->I,unpackdata->O,unpackdata->C,unpackdata->R);
return sqrt(pow(f1,2) + pow(f2,2));
My matlab version below seems to be a lot simpler but I would prefer the whole code in c++!
k1 = 0.01;
k2 = 0.01;
x0 = [k1,k2];
fun = #(x)solveKs(x,t,z,h,I,OCV1,Cap,Rct,static);
options = optimoptions('fsolve','Display','none');
k = fsolve(fun,x0,options);
% Calculate the next state vector from the previous one using RungeKutta
% update equation
znext = z + (1/2)*h*k(1) + (1/2)*h*k(2);``
function [F] = solveKs(x,t,z,h,I,O,C,R,static)
t1 = t + ((1/2)-(1/6)*sqrt(3));
y1 = z + (1/4)*h*x(1) + ((1/4)-(1/6)*sqrt(3))*h *x(2);
t2 = t + ((1/2)+(1/6)*sqrt(3));
y2 = z + ((1/4)+(1/6)*sqrt(3))*h*x(1) + (1/4)*h*x(2);
F(1) = x(1) - stateDeriv_implicit(t1,y1,h,I,O,C,R,static);
F(2) = x(2) - stateDeriv_implicit(t2,y2,h,I,O,C,R,static);
end

Trouble using Ensmallen optimization

I'm trying to optimize a certain objective function using Ensmallen that is a library for mathematical optimization that i found on Github.
Unfortunally the examples that i found in the documentation didn't turn out to be so usefull.
I have a lenght function that depends on two parameters: k_i and k_f, and i want to minimize it.
This function is subjected to 4 constraint: constraint1, ... , constraint4.
Theese constraints depends on: k_i, k_f and s that is a parameter that goeas from 0 to 1 and represent the parametrization of my lenght.
Basically this is a sort of simplification of the semi infinite programming problem. the variable "s" increse from 0 to 1 with 50 steps and for every step i would like to have my objective function that satisfies my 4 constraints.
x_i, y_i, theta_i, x_f, y_f, theta_f, speed, diameter, uplim, downlim are constants.
From the optimization i want to find the value of k_i and k_f.
So this is a part of my code:
double Evaluate(const arma::mat& x) {
k_i = x(0,0);
k_f = x(1,0);
return sqrt(k_f*k_f)*(1.0/3.0E1)+sqrt(k_i*k_i)*(1.0/3.0E1)+sqrt(x_f*x_i*-7.2E1-y_f*y_i*7.2E1+k_f*k_f+k_i*k_i+(x_f*x_f)*3.6E1+(x_i*x_i)*3.6E1+(y_f*y_f)*3.6E1+(y_i*y_i)*3.6E1-k_f*x_f*cos(theta_f)*1.2E1+k_f*x_i*cos(theta_f)*1.2E1-k_i*x_f*cos(theta_i)*1.2E1+k_i*x_i*cos(theta_i)*1.2E1-k_f*y_f*sin(theta_f)*1.2E1+k_f*y_i*sin(theta_f)*1.2E1-k_i*y_f*sin(theta_i)*1.2E1+k_i*y_i*sin(theta_i)*1.2E1+k_f*k_i*cos(theta_f-theta_i)*2.0)*(1.0/3.0E1)+sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*4.9E1+(k_i*k_i)*6.4E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2-k_f*x_f*cos(theta_f)*3.36E2+k_f*x_i*cos(theta_f)*3.36E2+k_i*x_f*cos(theta_i)*3.84E2-k_i*x_i*cos(theta_i)*3.84E2-k_f*y_f*sin(theta_f)*3.36E2+k_f*y_i*sin(theta_f)*3.36E2+k_i*y_f*sin(theta_i)*3.84E2-k_i*y_i*sin(theta_i)*3.84E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/3.75E2)+sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*6.4E1+(k_i*k_i)*4.9E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2+k_f*x_f*cos(theta_f)*3.84E2-k_f*x_i*cos(theta_f)*3.84E2-k_i*x_f*cos(theta_i)*3.36E2+k_i*x_i*cos(theta_i)*3.36E2+k_f*y_f*sin(theta_f)*3.84E2-k_f*y_i*sin(theta_f)*3.84E2-k_i*y_f*sin(theta_i)*3.36E2+k_i*y_i*sin(theta_i)*3.36E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/3.75E2)+sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*9.0+(k_i*k_i)*6.4E1+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*2.16E2+k_f*x_i*cos(theta_f)*2.16E2-k_i*x_f*cos(theta_i)*5.76E2+k_i*x_i*cos(theta_i)*5.76E2-k_f*y_f*sin(theta_f)*2.16E2+k_f*y_i*sin(theta_f)*2.16E2-k_i*y_f*sin(theta_i)*5.76E2+k_i*y_i*sin(theta_i)*5.76E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/3.75E2)+sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*6.4E1+(k_i*k_i)*9.0+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*5.76E2+k_f*x_i*cos(theta_f)*5.76E2-k_i*x_f*cos(theta_i)*2.16E2+k_i*x_i*cos(theta_i)*2.16E2-k_f*y_f*sin(theta_f)*5.76E2+k_f*y_i*sin(theta_f)*5.76E2-k_i*y_f*sin(theta_i)*2.16E2+k_i*y_i*sin(theta_i)*2.16E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/3.75E2)+sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*2.89E2+(k_i*k_i)*3.969E3+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3-k_f*x_f*cos(theta_f)*1.836E3+k_f*x_i*cos(theta_f)*1.836E3+k_i*x_f*cos(theta_i)*6.804E3-k_i*x_i*cos(theta_i)*6.804E3-k_f*y_f*sin(theta_f)*1.836E3+k_f*y_i*sin(theta_f)*1.836E3+k_i*y_f*sin(theta_i)*6.804E3-k_i*y_i*sin(theta_i)*6.804E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*(1.0/7.5E2)+sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*3.969E3+(k_i*k_i)*2.89E2+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3+k_f*x_f*cos(theta_f)*6.804E3-k_f*x_i*cos(theta_f)*6.804E3-k_i*x_f*cos(theta_i)*1.836E3+k_i*x_i*cos(theta_i)*1.836E3+k_f*y_f*sin(theta_f)*6.804E3-k_f*y_i*sin(theta_f)*6.804E3-k_i*y_f*sin(theta_i)*1.836E3+k_i*y_i*sin(theta_i)*1.836E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*(1.0/7.5E2)+sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*4.9E1+(k_i*k_i)*1.089E3+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4+k_f*x_f*cos(theta_f)*1.764E3-k_f*x_i*cos(theta_f)*1.764E3-k_i*x_f*cos(theta_i)*8.316E3+k_i*x_i*cos(theta_i)*8.316E3+k_f*y_f*sin(theta_f)*1.764E3-k_f*y_i*sin(theta_f)*1.764E3-k_i*y_f*sin(theta_i)*8.316E3+k_i*y_i*sin(theta_i)*8.316E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*(1.0/7.5E2)+sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*1.089E3+(k_i*k_i)*4.9E1+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4-k_f*x_f*cos(theta_f)*8.316E3+k_f*x_i*cos(theta_f)*8.316E3+k_i*x_f*cos(theta_i)*1.764E3-k_i*x_i*cos(theta_i)*1.764E3-k_f*y_f*sin(theta_f)*8.316E3+k_f*y_i*sin(theta_f)*8.316E3+k_i*y_f*sin(theta_i)*1.764E3-k_i*y_i*sin(theta_i)*1.764E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*(1.0/7.5E2);
}
void Gradient(const arma::mat& x, arma::mat& g) {
k_i = x(0,0);
k_f = x(1,0);
g.resize(2,1);
g(0,0) = (k_i*9.8E1-x_f*cos(theta_i)*3.36E2+x_i*cos(theta_i)*3.36E2-y_f*sin(theta_i)*3.36E2+y_i*sin(theta_i)*3.36E2-k_f*cos(theta_f-theta_i)*1.12E2)*1.0/sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*6.4E1+(k_i*k_i)*4.9E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2+k_f*x_f*cos(theta_f)*3.84E2-k_f*x_i*cos(theta_f)*3.84E2-k_i*x_f*cos(theta_i)*3.36E2+k_i*x_i*cos(theta_i)*3.36E2+k_f*y_f*sin(theta_f)*3.84E2-k_f*y_i*sin(theta_f)*3.84E2-k_i*y_f*sin(theta_i)*3.36E2+k_i*y_i*sin(theta_i)*3.36E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/7.5E2)+(k_i*1.28E2+x_f*cos(theta_i)*3.84E2-x_i*cos(theta_i)*3.84E2+y_f*sin(theta_i)*3.84E2-y_i*sin(theta_i)*3.84E2-k_f*cos(theta_f-theta_i)*1.12E2)*1.0/sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*4.9E1+(k_i*k_i)*6.4E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2-k_f*x_f*cos(theta_f)*3.36E2+k_f*x_i*cos(theta_f)*3.36E2+k_i*x_f*cos(theta_i)*3.84E2-k_i*x_i*cos(theta_i)*3.84E2-k_f*y_f*sin(theta_f)*3.36E2+k_f*y_i*sin(theta_f)*3.36E2+k_i*y_f*sin(theta_i)*3.84E2-k_i*y_i*sin(theta_i)*3.84E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/7.5E2)+(k_i*1.8E1-x_f*cos(theta_i)*2.16E2+x_i*cos(theta_i)*2.16E2-y_f*sin(theta_i)*2.16E2+y_i*sin(theta_i)*2.16E2+k_f*cos(theta_f-theta_i)*4.8E1)*1.0/sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*6.4E1+(k_i*k_i)*9.0+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*5.76E2+k_f*x_i*cos(theta_f)*5.76E2-k_i*x_f*cos(theta_i)*2.16E2+k_i*x_i*cos(theta_i)*2.16E2-k_f*y_f*sin(theta_f)*5.76E2+k_f*y_i*sin(theta_f)*5.76E2-k_i*y_f*sin(theta_i)*2.16E2+k_i*y_i*sin(theta_i)*2.16E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/7.5E2)+(k_i*1.28E2-x_f*cos(theta_i)*5.76E2+x_i*cos(theta_i)*5.76E2-y_f*sin(theta_i)*5.76E2+y_i*sin(theta_i)*5.76E2+k_f*cos(theta_f-theta_i)*4.8E1)*1.0/sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*9.0+(k_i*k_i)*6.4E1+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*2.16E2+k_f*x_i*cos(theta_f)*2.16E2-k_i*x_f*cos(theta_i)*5.76E2+k_i*x_i*cos(theta_i)*5.76E2-k_f*y_f*sin(theta_f)*2.16E2+k_f*y_i*sin(theta_f)*2.16E2-k_i*y_f*sin(theta_i)*5.76E2+k_i*y_i*sin(theta_i)*5.76E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/7.5E2)+(k_i*5.78E2-x_f*cos(theta_i)*1.836E3+x_i*cos(theta_i)*1.836E3-y_f*sin(theta_i)*1.836E3+y_i*sin(theta_i)*1.836E3-k_f*cos(theta_f-theta_i)*2.142E3)*1.0/sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*3.969E3+(k_i*k_i)*2.89E2+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3+k_f*x_f*cos(theta_f)*6.804E3-k_f*x_i*cos(theta_f)*6.804E3-k_i*x_f*cos(theta_i)*1.836E3+k_i*x_i*cos(theta_i)*1.836E3+k_f*y_f*sin(theta_f)*6.804E3-k_f*y_i*sin(theta_f)*6.804E3-k_i*y_f*sin(theta_i)*1.836E3+k_i*y_i*sin(theta_i)*1.836E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*6.666666666666667E-4+(k_i*7.938E3+x_f*cos(theta_i)*6.804E3-x_i*cos(theta_i)*6.804E3+y_f*sin(theta_i)*6.804E3-y_i*sin(theta_i)*6.804E3-k_f*cos(theta_f-theta_i)*2.142E3)*1.0/sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*2.89E2+(k_i*k_i)*3.969E3+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3-k_f*x_f*cos(theta_f)*1.836E3+k_f*x_i*cos(theta_f)*1.836E3+k_i*x_f*cos(theta_i)*6.804E3-k_i*x_i*cos(theta_i)*6.804E3-k_f*y_f*sin(theta_f)*1.836E3+k_f*y_i*sin(theta_f)*1.836E3+k_i*y_f*sin(theta_i)*6.804E3-k_i*y_i*sin(theta_i)*6.804E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*6.666666666666667E-4+(k_i*9.8E1+x_f*cos(theta_i)*1.764E3-x_i*cos(theta_i)*1.764E3+y_f*sin(theta_i)*1.764E3-y_i*sin(theta_i)*1.764E3-k_f*cos(theta_f-theta_i)*4.62E2)*1.0/sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*1.089E3+(k_i*k_i)*4.9E1+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4-k_f*x_f*cos(theta_f)*8.316E3+k_f*x_i*cos(theta_f)*8.316E3+k_i*x_f*cos(theta_i)*1.764E3-k_i*x_i*cos(theta_i)*1.764E3-k_f*y_f*sin(theta_f)*8.316E3+k_f*y_i*sin(theta_f)*8.316E3+k_i*y_f*sin(theta_i)*1.764E3-k_i*y_i*sin(theta_i)*1.764E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*6.666666666666667E-4+(k_i*2.178E3-x_f*cos(theta_i)*8.316E3+x_i*cos(theta_i)*8.316E3-y_f*sin(theta_i)*8.316E3+y_i*sin(theta_i)*8.316E3-k_f*cos(theta_f-theta_i)*4.62E2)*1.0/sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*4.9E1+(k_i*k_i)*1.089E3+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4+k_f*x_f*cos(theta_f)*1.764E3-k_f*x_i*cos(theta_f)*1.764E3-k_i*x_f*cos(theta_i)*8.316E3+k_i*x_i*cos(theta_i)*8.316E3+k_f*y_f*sin(theta_f)*1.764E3-k_f*y_i*sin(theta_f)*1.764E3-k_i*y_f*sin(theta_i)*8.316E3+k_i*y_i*sin(theta_i)*8.316E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*6.666666666666667E-4+(k_i*2.0-x_f*cos(theta_i)*1.2E1+x_i*cos(theta_i)*1.2E1-y_f*sin(theta_i)*1.2E1+y_i*sin(theta_i)*1.2E1+k_f*cos(theta_f-theta_i)*2.0)*1.0/sqrt(x_f*x_i*-7.2E1-y_f*y_i*7.2E1+k_f*k_f+k_i*k_i+(x_f*x_f)*3.6E1+(x_i*x_i)*3.6E1+(y_f*y_f)*3.6E1+(y_i*y_i)*3.6E1-k_f*x_f*cos(theta_f)*1.2E1+k_f*x_i*cos(theta_f)*1.2E1-k_i*x_f*cos(theta_i)*1.2E1+k_i*x_i*cos(theta_i)*1.2E1-k_f*y_f*sin(theta_f)*1.2E1+k_f*y_i*sin(theta_f)*1.2E1-k_i*y_f*sin(theta_i)*1.2E1+k_i*y_i*sin(theta_i)*1.2E1+k_f*k_i*cos(theta_f-theta_i)*2.0)*(1.0/6.0E1)+k_i*1.0/sqrt(k_i*k_i)*(1.0/3.0E1);
g(1,0) = (k_f*9.8E1-x_f*cos(theta_f)*3.36E2+x_i*cos(theta_f)*3.36E2-y_f*sin(theta_f)*3.36E2+y_i*sin(theta_f)*3.36E2-k_i*cos(theta_f-theta_i)*1.12E2)*1.0/sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*4.9E1+(k_i*k_i)*6.4E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2-k_f*x_f*cos(theta_f)*3.36E2+k_f*x_i*cos(theta_f)*3.36E2+k_i*x_f*cos(theta_i)*3.84E2-k_i*x_i*cos(theta_i)*3.84E2-k_f*y_f*sin(theta_f)*3.36E2+k_f*y_i*sin(theta_f)*3.36E2+k_i*y_f*sin(theta_i)*3.84E2-k_i*y_i*sin(theta_i)*3.84E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/7.5E2)+(k_f*1.28E2+x_f*cos(theta_f)*3.84E2-x_i*cos(theta_f)*3.84E2+y_f*sin(theta_f)*3.84E2-y_i*sin(theta_f)*3.84E2-k_i*cos(theta_f-theta_i)*1.12E2)*1.0/sqrt(x_f*x_i*-1.152E3-y_f*y_i*1.152E3+(k_f*k_f)*6.4E1+(k_i*k_i)*4.9E1+(x_f*x_f)*5.76E2+(x_i*x_i)*5.76E2+(y_f*y_f)*5.76E2+(y_i*y_i)*5.76E2+k_f*x_f*cos(theta_f)*3.84E2-k_f*x_i*cos(theta_f)*3.84E2-k_i*x_f*cos(theta_i)*3.36E2+k_i*x_i*cos(theta_i)*3.36E2+k_f*y_f*sin(theta_f)*3.84E2-k_f*y_i*sin(theta_f)*3.84E2-k_i*y_f*sin(theta_i)*3.36E2+k_i*y_i*sin(theta_i)*3.36E2-k_f*k_i*cos(theta_f-theta_i)*1.12E2)*(1.0/7.5E2)+(k_f*1.8E1-x_f*cos(theta_f)*2.16E2+x_i*cos(theta_f)*2.16E2-y_f*sin(theta_f)*2.16E2+y_i*sin(theta_f)*2.16E2+k_i*cos(theta_f-theta_i)*4.8E1)*1.0/sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*9.0+(k_i*k_i)*6.4E1+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*2.16E2+k_f*x_i*cos(theta_f)*2.16E2-k_i*x_f*cos(theta_i)*5.76E2+k_i*x_i*cos(theta_i)*5.76E2-k_f*y_f*sin(theta_f)*2.16E2+k_f*y_i*sin(theta_f)*2.16E2-k_i*y_f*sin(theta_i)*5.76E2+k_i*y_i*sin(theta_i)*5.76E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/7.5E2)+(k_f*1.28E2-x_f*cos(theta_f)*5.76E2+x_i*cos(theta_f)*5.76E2-y_f*sin(theta_f)*5.76E2+y_i*sin(theta_f)*5.76E2+k_i*cos(theta_f-theta_i)*4.8E1)*1.0/sqrt(x_f*x_i*-2.592E3-y_f*y_i*2.592E3+(k_f*k_f)*6.4E1+(k_i*k_i)*9.0+(x_f*x_f)*1.296E3+(x_i*x_i)*1.296E3+(y_f*y_f)*1.296E3+(y_i*y_i)*1.296E3-k_f*x_f*cos(theta_f)*5.76E2+k_f*x_i*cos(theta_f)*5.76E2-k_i*x_f*cos(theta_i)*2.16E2+k_i*x_i*cos(theta_i)*2.16E2-k_f*y_f*sin(theta_f)*5.76E2+k_f*y_i*sin(theta_f)*5.76E2-k_i*y_f*sin(theta_i)*2.16E2+k_i*y_i*sin(theta_i)*2.16E2+k_f*k_i*cos(theta_f-theta_i)*4.8E1)*(1.0/7.5E2)+(k_f*5.78E2-x_f*cos(theta_f)*1.836E3+x_i*cos(theta_f)*1.836E3-y_f*sin(theta_f)*1.836E3+y_i*sin(theta_f)*1.836E3-k_i*cos(theta_f-theta_i)*2.142E3)*1.0/sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*2.89E2+(k_i*k_i)*3.969E3+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3-k_f*x_f*cos(theta_f)*1.836E3+k_f*x_i*cos(theta_f)*1.836E3+k_i*x_f*cos(theta_i)*6.804E3-k_i*x_i*cos(theta_i)*6.804E3-k_f*y_f*sin(theta_f)*1.836E3+k_f*y_i*sin(theta_f)*1.836E3+k_i*y_f*sin(theta_i)*6.804E3-k_i*y_i*sin(theta_i)*6.804E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*6.666666666666667E-4+(k_f*7.938E3+x_f*cos(theta_f)*6.804E3-x_i*cos(theta_f)*6.804E3+y_f*sin(theta_f)*6.804E3-y_i*sin(theta_f)*6.804E3-k_i*cos(theta_f-theta_i)*2.142E3)*1.0/sqrt(x_f*x_i*-5.832E3-y_f*y_i*5.832E3+(k_f*k_f)*3.969E3+(k_i*k_i)*2.89E2+(x_f*x_f)*2.916E3+(x_i*x_i)*2.916E3+(y_f*y_f)*2.916E3+(y_i*y_i)*2.916E3+k_f*x_f*cos(theta_f)*6.804E3-k_f*x_i*cos(theta_f)*6.804E3-k_i*x_f*cos(theta_i)*1.836E3+k_i*x_i*cos(theta_i)*1.836E3+k_f*y_f*sin(theta_f)*6.804E3-k_f*y_i*sin(theta_f)*6.804E3-k_i*y_f*sin(theta_i)*1.836E3+k_i*y_i*sin(theta_i)*1.836E3-k_f*k_i*cos(theta_f-theta_i)*2.142E3)*6.666666666666667E-4+(k_f*9.8E1+x_f*cos(theta_f)*1.764E3-x_i*cos(theta_f)*1.764E3+y_f*sin(theta_f)*1.764E3-y_i*sin(theta_f)*1.764E3-k_i*cos(theta_f-theta_i)*4.62E2)*1.0/sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*4.9E1+(k_i*k_i)*1.089E3+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4+k_f*x_f*cos(theta_f)*1.764E3-k_f*x_i*cos(theta_f)*1.764E3-k_i*x_f*cos(theta_i)*8.316E3+k_i*x_i*cos(theta_i)*8.316E3+k_f*y_f*sin(theta_f)*1.764E3-k_f*y_i*sin(theta_f)*1.764E3-k_i*y_f*sin(theta_i)*8.316E3+k_i*y_i*sin(theta_i)*8.316E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*6.666666666666667E-4+(k_f*2.178E3-x_f*cos(theta_f)*8.316E3+x_i*cos(theta_f)*8.316E3-y_f*sin(theta_f)*8.316E3+y_i*sin(theta_f)*8.316E3-k_i*cos(theta_f-theta_i)*4.62E2)*1.0/sqrt(x_f*x_i*-3.1752E4-y_f*y_i*3.1752E4+(k_f*k_f)*1.089E3+(k_i*k_i)*4.9E1+(x_f*x_f)*1.5876E4+(x_i*x_i)*1.5876E4+(y_f*y_f)*1.5876E4+(y_i*y_i)*1.5876E4-k_f*x_f*cos(theta_f)*8.316E3+k_f*x_i*cos(theta_f)*8.316E3+k_i*x_f*cos(theta_i)*1.764E3-k_i*x_i*cos(theta_i)*1.764E3-k_f*y_f*sin(theta_f)*8.316E3+k_f*y_i*sin(theta_f)*8.316E3+k_i*y_f*sin(theta_i)*1.764E3-k_i*y_i*sin(theta_i)*1.764E3-k_f*k_i*cos(theta_f-theta_i)*4.62E2)*6.666666666666667E-4+(k_f*2.0-x_f*cos(theta_f)*1.2E1+x_i*cos(theta_f)*1.2E1-y_f*sin(theta_f)*1.2E1+y_i*sin(theta_f)*1.2E1+k_i*cos(theta_f-theta_i)*2.0)*1.0/sqrt(x_f*x_i*-7.2E1-y_f*y_i*7.2E1+k_f*k_f+k_i*k_i+(x_f*x_f)*3.6E1+(x_i*x_i)*3.6E1+(y_f*y_f)*3.6E1+(y_i*y_i)*3.6E1-k_f*x_f*cos(theta_f)*1.2E1+k_f*x_i*cos(theta_f)*1.2E1-k_i*x_f*cos(theta_i)*1.2E1+k_i*x_i*cos(theta_i)*1.2E1-k_f*y_f*sin(theta_f)*1.2E1+k_f*y_i*sin(theta_f)*1.2E1-k_i*y_f*sin(theta_i)*1.2E1+k_i*y_i*sin(theta_i)*1.2E1+k_f*k_i*cos(theta_f-theta_i)*2.0)*(1.0/6.0E1)+k_f*1.0/sqrt(k_f*k_f)*(1.0/3.0E1);
}
size_t NumConstraints() {
return 50;
}
double EvaluateConstraint(const size_t i, const arma::mat& x){
k_i = x(0,0);
k_f = x(1,0);
double index_ensmallen = i;
double s = index_ensmallen/49;
double v = sqrt((s*s*s*s)*pow(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i),2.0)*9.0+(s*s)*pow(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0,2.0)*4.0+(k_i*k_i)*pow(cos(theta_i),2.0)+(k_i*k_i)*pow(sin(theta_i),2.0)+(s*s*s*s)*pow(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i),2.0)*9.0+(s*s)*pow(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0,2.0)*4.0-(s*s*s)*(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*1.2E1-(s*s*s)*(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*1.2E1-k_i*s*cos(theta_i)*(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*4.0-k_i*s*sin(theta_i)*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*4.0+k_i*(s*s)*cos(theta_i)*(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*6.0+k_i*(s*s)*sin(theta_i)*(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*6.0);
double w = -(s*(k_i*sin(theta_i)*(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*6.0-k_i*cos(theta_i)*(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*6.0)-(s*s)*((x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*6.0-(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*6.0)-k_i*sin(theta_i)*(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*2.0+k_i*cos(theta_i)*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*2.0)/(-s*(k_i*sin(theta_i)*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*4.0+k_i*cos(theta_i)*(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*4.0)+(k_i*k_i)*pow(cos(theta_i),2.0)+(k_i*k_i)*pow(sin(theta_i),2.0)+(s*s*s*s)*(pow(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i),2.0)*9.0+pow(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i),2.0)*9.0)-(s*s*s)*((x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0)*1.2E1+(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0)*1.2E1)+(s*s)*(pow(x_f*-3.0+x_i*3.0+k_f*cos(theta_f)+k_i*cos(theta_i)*2.0,2.0)*4.0+pow(y_f*-3.0+y_i*3.0+k_f*sin(theta_f)+k_i*sin(theta_i)*2.0,2.0)*4.0+k_i*sin(theta_i)*(y_f*-2.0+y_i*2.0+k_f*sin(theta_f)+k_i*sin(theta_i))*6.0+k_i*cos(theta_i)*(x_f*-2.0+x_i*2.0+k_f*cos(theta_f)+k_i*cos(theta_i))*6.0));
double constraint1 = w - tan(uplim)*v;
double constraint2 = tan(downlim)*v - w;
double constraint3 = v*(speed-1) + diameter*speed*w;
double constraint4 = v*(speed-1) - diameter*speed*w;
if ( (constraint1 >0) || (constraint2 >0) || (constraint3 >0) || (constraint4 >0) ){
return DBL_MAX; //constraint unsatisfied
}
return 0;
}//close EvaluateConstraint
void GradientConstraint(const size_t i, const arma::mat& x, arma::mat& g){
g.resize(2,1);
k_i = x(0,0);
k_f = x(1,0);
double s=i/49;
//g(0,0) = 0
//g(1,0) = 0
}//close gradientconstraint
When i try to use this optimizator i find that k_i and k_f are equal to Nan. But i tested it with the optimizer "fmincon" of Matlab and i obtain some valid results!
So i don't know what to do, i thought that maybe i have written something wrong here in the EvaluateConstraint method because when i try to print their value i find "Nan".
Edit: Raising the value of the initial point (for example x0:(500, 500)) "unlocks" the simulation, the optimizator don't use the same value every iteration, it changes as it should be, but still no solution.

Value inside loop doesnt change in C++

here is a sample code that doesnt seem to work. I get the same value of X and Y ( both of them equal to zero ) for all the iteration. Can someone help me with this mistake of mine?
#include <iostream>
using namespace std;
int main()
{
double coord[4][2];
int div_x, div_y;
coord[1][0]=2;
coord[1][1]=0;
coord[2][0]=2;
coord[2][1]=4;
coord[3][0]=0;
coord[3][1]=4;
div_x = 4;
div_y = 3;
double a =0,b=0,c=0,d=0,e=0,f=0,g=0,h=0;
a = coord[1][0]+coord[2][0]+coord[3][0];
b = coord[1][0]+coord[2][0]-coord[3][0];
c = coord[2][0]-coord[1][0]+coord[3][0];
d = coord[2][0]-coord[1][0]-coord[3][0];
e = coord[1][1]+coord[2][1]+coord[3][1];
f = coord[1][1]+coord[2][1]-coord[3][1];
g = coord[2][1]-coord[1][1]+coord[3][1];
h = coord[2][1]-coord[1][1]-coord[3][1];
for (int i=0; i<div_y+1; i++){ // loop all rows (blue)
for (int j=0; j<div_x+1; j++){ // loop all nodes of one row (green)
double w = -1 + (2/div_x)*j;
double s = -1 + (2/div_y)*i;
double X = (a+b*w+c*s+(w*s*d));
double Y = (e+f*w+g*s+(h*s*w));
cout<<"\nX "<<X<<endl;
cout<<"\nY "<<Y<<endl;
}
}
return 0;
}
.
Your problem is with the divisions here:
double w = -1 + (2/div_x)*j;
double s = -1 + (2/div_y)*i;
2/div_x and 2/div_y are integer divisions. When you divide two values of type integer in C++, the division is carried out as an integer division. Since div_x is 4 and div_y is 3, the result of both of them is 0. As an integer division:
2 / 4 = 0
2 / 3 = 0
The easiest way to fix this is to use a double value for one of the two values, which results in a double division. For example:
double w = -1.0 + (2.0/div_x)*j;
double s = -1.0 + (2.0/div_y)*i;
You may also want to consider using the float type instead of double, unless you really need more than float precision, which is about 7 decimal digits.
In your code, div_x and div_y are int, thus, (2/div_x) and (2/div_y) are integer divisions, and evaluate to 0.
So w and s are both always equal to -1.
You can force float evaluation by using : (2.0/div_x) and (2.0/div_y)

"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).)