The following error message was received after running my code located at the end of the message:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
I'm sorry for the length of the code. It appears that the error is coming from when I am calling the numerov function within the f function. If you are able to determine what the error is would you please let me know? Thank you!
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>
using namespace std;
int nx = 500, m = 10, ni = 10;
double x1 = 0, x2 = 1, h = (x2 - x1)/nx;
int nr, nl;
vector<double> ul, q, u;
//Method to achieve the evenly spaced Simpson rule
double simpson(vector <double> y, double h)
{
int n = y.size() - 1;
double s0 = 0, s1 = 0, s2 = 0;
for (int i = 1; i < n; i += 2)
{
s0 += y.at(i);
s1 += y.at(i-1);
s2 += y.at(i+1);
}
double s = (s1 + 4*s0 + s2)/3;
//Add the last slice separately for an even n+1
if ((n+1)%2 == 0)
return h*(s + (5*y.at(n) + 8*y.at(n-1) - y.at(n-2))/12);
else
return h*2;
}
//Method to perform the Numerov integration
vector <double> numerov(int m, double h, double u0, double u1, double q)
{
vector<double> u;
u.push_back(u0);
u.push_back(u1);
double g = h*h/12;
for (int i = 1; i < m+1; i++)
{
double c0 = 1 + g*q;
double c1 = 2 - 10*g*q;
double c2 = 1 + g*q;
double d = g*(0);
u.push_back((c1*u.at(i) - c0*u.at(i-1) + d)/c2);
}
return u;
}
//Method to provide the function for the root search
double f(double x)
{
vector<double> w;
vector<double> j = numerov(nx + 1, h, 0.0, 0.001, x);
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
}
//Method to carry out the secant search
double secant(int n, double del, double x, double dx)
{
int k = 0;
double x1 = x + dx;
while ((abs(dx) > del) && (k < n))
{
double d = f(x1) - f(x);
double x2 = x1 - f(x1)*(x1 - x)/d;
x = x1;
x1 = x2;
dx = x1 - x;
k++;
}
if (k == n)
cout << "Convergence not found after " << n << " iterations." << endl;
return x1;
}
int main()
{
double del = 1e-6, e = 0, de = 0.1;
//Find the eigenvalue via the secant method
e = secant (ni, del, e, de);
//Find the solution u(x)
u = numerov(nx + 1, h, 0.0, 0.01, e);
//Output the wavefunction to a file
ofstream myfile ("Problem 2.txt");
if (myfile.is_open())
{
myfile << "Input" << "\t" << "u(x)" << endl;
double x = x1;
double mh = m*h;
for (int i = 0; i <= nx; i += m)
{
myfile << x << "\t" << u.at(i) << endl;
x += mh;
}
myfile.close();
}
return 0;
}
vector<double> w;
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
w will have nothing in it, since that loop will run 0 times. Thus, w.at(0) will throw the out of range error.
Why do you think the problem is in the numerov function?
I see an error in the function f?
vector<double> w;
vector<double> j = numerov(nx + 1, h, 0.0, 0.001, x);
for (int i = 0; i < 0; i++)
{
w.push_back(j.at(i));
}
return w.at(0);
There is nothing on vector w and you try to access element 0.
Related
Here is the question:
There is a house with a backyard which is square bounded by
coordinates (0,0) in the southwest to (1000,1000) in
the northeast. In this yard there are a number of water sprinklers
placed to keep the lawn soaked in the middle of the summer. However,
it might or might not be possible to cross the yard without getting
soaked and without leaving the yard?
Input The input starts with a line containing an integer 1≤n≤1000, the
number of water sprinklers. A line follows for each sprinkler,
containing three integers: the (x,y)(x,y) location of the sprinkler
(0≤x,y,≤10000) and its range r (1≤r≤1000). The sprinklers will soak
anybody passing strictly within the range of the sprinkler (i.e.,
within distance strictly less than r).
The house is located on the west side (x=0) and a path is needed to
the east side of the yard (x=1000).
Output If you can find a path through the yard, output four real
numbers, separated by spaces, rounded to two digits after the decimal
place. These should be the coordinates at which you may enter and
leave the yard, respectively. If you can enter and leave at several
places, give the results with the highest y. If there is no way to get
through the yard without getting soaked, print a line containing
“IMPOSSIBLE”.
Sample Input
3
500 500 499
0 0 999
1000 1000 200
Sample output
0.00 1000.00 1000.00 800.00
Here is my thought process:
Define circle objects with x,y,r and write a function to determine if a given point is wet or not(inside the circle or not) on the circumference is not wet btw.
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<int,int>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) +
pow(p->second - this->k, 2) ) ) {
return true;
}
else
return false;
};
Then implement a depth first search, prioritizing to go up and right whenever possible.
However since circles are not guaranteed to be pass on integer coordinates an the result is expected in floats with double precision (xxx.xx). So if we keep everything in integers the grid suddenly becomes 100,000 x 100,000 which is way too big. Also the time limit is 1 sec.
So I thought ok lets stick to 1000x1000 and work with floats instead. Loop over int coordinates and whenever I hit a sprinkle just snap in the perimeter of the circle since we are safe in the perimeter. But in that case could not figure out how DFS work.
Here is the latest trial
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <utility>
#include <unordered_set>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct pair_hash {
inline std::size_t operator()(const std::pair<int,int> & v) const {
return v.first*31+v.second;
}
};
class circle {
int h;
int k;
int r;
public:
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
};
bool iswet(pair<float,float>* p){
if (pow(this->r - 0.001, 2) > (pow(p->first - this->h, 2) + pow(p->second - this->k, 2) ) ) {
this->closest_pair(p);
return true;
}
else
return false;
};
void closest_pair(pair<float,float>* p){
float vx = p->first - this->h;
float vy = p->second - this->k;
float magv = sqrt(vx * vx + vy * vy);
p->first = this->h + vx / magv * this->r;
p->second = this->k + vy / magv * this->r;
}
};
static bool test_sprinkles(vector<circle> &sprinkles, pair<float,float>* p){
for (int k = 0; k < sprinkles.size(); k++)
if (sprinkles[k].iswet(p)) return false;
return true;
}
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
pair<float,float> enter = make_pair(0, MAXY);
deque<pair<float,float>> mystack;
mystack.push_back(enter);
pair<float,float>* cp;
bool found = false;
unordered_set<pair<float, float>, pair_hash> visited;
while (!mystack.empty()){
cp = &mystack.back();
if (cp->first == MAXX) {
found = true;
break;
}
visited.insert(*cp);
if (cp->second > MAXY || cp->second < MINY || cp ->first < MINX ) {
visited.insert(*cp);
mystack.pop_back();
continue;
}
if (!test_sprinkles(sprinkles_array,cp)) {
continue;
}
pair<int,int> newpair = make_pair(cp->first, cp->second + 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first + 1 , cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first, cp->second - 1);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
newpair = make_pair(cp->first - 1, cp->second);
if (visited.find(newpair) == visited.end()) {
mystack.push_back(newpair);
continue;
}
else visited.insert(newpair);
mystack.pop_back();
}
cout << setprecision(2);
cout << fixed;
if (found){
double xin = mystack.front().first;
double yin = mystack.front().second;
pair <float, float> p = mystack.back();
p.second++;
for (int k = 0; k < sprinkles_array.size(); k++)
if (sprinkles_array[k].iswet(&p)) break;
double xout = p.first;
double yout = p.second;
cout << xin << " " << yin << " " << xout << " " << yout << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}
Yes #JosephIreland is right. Solved it with grouping intersecting (not touching) circles. Then these groups have maxy and min y coordinates. If it exceeds the yard miny and maxy the way is blocked.
Then these groups also have upper and lower intersection points with x=0 and x=1000 lines. If the upper points are larger than the yard maxy then the maximum entry/exit points are lower entery points.
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <utility>
#include <iomanip>
using namespace std;
const int MAXY = 1e3;
const int MAXX = 1e3;
const int MINY = 0;
const int MINX = 0;
struct circle {
int h;
int k;
int r;
float maxy;
float miny;
circle();
circle(int h, int k, int r){
this->h = h;
this->k = k;
this->r = r;
this->miny = this->k - r;
this->maxy = this->k + r;
};
};
struct group {
float maxy = -1;
float miny = -1;
vector<circle*> circles;
float upper_endy = -1;
float upper_starty = -1;
float lower_endy = -1;
float lower_starty = -1;
void add_circle(circle& c){
if ((c.maxy > this->maxy) || this->circles.empty() ) this->maxy = c.maxy;
if ((c.miny < this->miny) || this->circles.empty() ) this->miny = c.miny;
this->circles.push_back(&c);
// find where it crosses x=minx and x= maxx
float root = sqrt(pow(c.r, 2) - pow(MINX - c.h, 2));
float y1 = root + c.k;
float y2 = -root + c.k;
if (y1 > this->upper_starty) this->upper_starty = y1;
if (y2 > this->lower_starty) this->lower_starty = y2;
root = sqrt(pow(c.r, 2) - pow(MAXX - c.h, 2));
y1 = root + c.k;
y2 = -root + c.k;
if (y1 > this->upper_endy) this->upper_endy = y1;
if (y2 > this->lower_endy) this->lower_endy = y2;
};
bool does_intersect(circle& c1){
for(circle* c2 : circles){
float dist = sqrt(pow(c1.h - c2->h,2)) + sqrt(pow(c1.k - c2->k,2));
(dist < (c1.r + c2->r)) ? true : false;
};
};
};
int main(){
int n; // number of sprinkles
while (cin >> n){
vector<circle> sprinkles_array;
sprinkles_array.reserve(n);
int h, k, r;
while (n--){
cin >> h >> k >> r;
sprinkles_array.push_back(circle(h, k, r));
}/* code */
vector<group> groups;
group newgroup;
newgroup.add_circle(sprinkles_array[0]);
groups.push_back(newgroup);
for (int i = 1; i < sprinkles_array.size(); i++){
bool no_group = true;
for (group g:groups){
if (g.does_intersect(sprinkles_array[i])){
g.add_circle(sprinkles_array[i]);
no_group = false;
break;
}
}
if (no_group) {
group newgroup;
newgroup.add_circle(sprinkles_array[i]);
groups.push_back(newgroup);
}
}
float entery = MAXY;
float exity = MAXY;
bool found = true;
for (group g : groups){
if ((g.miny < MINY) && (g.maxy > MAXY)){
found = false;
break;
}
if (g.upper_starty > entery)
entery = g.lower_starty;
if (g.upper_endy > exity)
exity = g.lower_endy;
}
cout << setprecision(2);
cout << fixed;
if (found){
cout << float(MINX) << " " << entery << " " << float(MAXX) << " " << exity << endl;
}
else
{
cout << "IMPOSSIBLE" << endl;
}
}
}
I'm translating Python's version of 'page_dewarper' (https://mzucker.github.io/2016/08/15/page-dewarping.html) into C++. I'm going to use dlib, which is a fantastic tool, that helped me in a few optimization problems before. In line 748 of Github repo (https://github.com/mzucker/page_dewarp/blob/master/page_dewarp.py) Matt uses optimize function from Scipy, to find the minimal distance between two vectors. I think, my C++ equivalent should be solve_least_squares_lm() or solve_least_squares(). I'll give a concrete example to analyze.
My data:
a) dstpoints is a vector with OpenCV points - std::vector<cv::Point2f> (I have 162 points in this example, they are not changing),
b) ppts is also std::vector<cv::Point2f> and the same size as dstpoints.
std::vector<cv::Point2f> ppts = project_keypoints(params, input);
It is dependent on:
- dlib::column_vector 'input' is 2*162=324 long and is not changing,
- dlib::column_vector 'params' is 189 long and its values should be changed to get the minimal value of variable 'suma', something like this:
double suma = 0.0;
for (int i=0; i<dstpoints_size; i++)
{
suma += pow(dstpoints[i].x - ppts[i].x, 2);
suma += pow(dstpoints[i].y - ppts[i].y, 2);
}
I'm looking for 'params' vector that will give me the smallest value of 'suma' variable. Least squares algorithm seems to be a good option to solve it: http://dlib.net/dlib/optimization/optimization_least_squares_abstract.h.html#solve_least_squares, but I don't know if it is good for my case.
I think, my problem is that for every different 'params' vector I get different 'ppts' vector, not only single value, and I don't know if solve_least_squares function can match my example.
I must calculate residual for every point. I think, my 'list' from aforementioned link should be something like this:
(ppts[i].x - dstpoints[i].x, ppts[i].y - dstpoints[i].y, ppts[i+1].x - dstpoints[i+1].x, ppts[i+1].y - dstpoints[i+1].y, etc.)
, where 'ppts' vector depends on 'params' vector and then this problem can be solved with least squares algorithm. I don't know how to create data_samples with these assumptions, because it requires dlib::input_vector for every sample, as it is shown in example: http://dlib.net/least_squares_ex.cpp.html.
Am I thinking right?
I'm doing the same thing this days. My solution is writing a Powell Class by myself. It works, but really slowly. The program takes 2 minutes in dewarping linguistics_thesis.jpg.
I don't know what cause the program running so slowly. Maybe because of the algorithm or the code has some extra loop. I'm a Chinese student and my school only have java lessons. So it is normal if you find some extra codes in my codes.
Here is my Powell class.
using namespace std;
using namespace cv;
class MyPowell
{
public:
vector<vector<double>> xi;
vector<double> pcom;
vector<double> xicom;
vector<Point2d> dstpoints;
vector<double> myparams;
vector<double> params;
vector<Point> keypoint_index;
Point2d dst_br;
Point2d dims;
int N;
int itmax;
int ncom;
int iter;
double fret, ftol;
int usingAorB;
MyPowell(vector<Point2d> &dstpoints, vector<double> ¶ms, vector<Point> &keypoint_index);
MyPowell(Point2d &dst_br, vector<double> ¶ms, Point2d & dims);
MyPowell();
double obj(vector<double> ¶ms);
void powell(vector<double> &p, vector<vector<double>> &xi, double ftol, double &fret);
double sign(double a);// , double b);
double sqr(double a);
void linmin(vector<double> &p, vector<double> &xit, int n, double &fret);
void mnbrak(double & ax, double & bx, double & cx,
double & fa, double & fb, double & fc);
double f1dim(double x);
double brent(double ax, double bx, double cx, double & xmin, double tol);
vector<double> usePowell();
void erase(vector<double>& pbar, vector<double> &prr, vector<double> &pr);
};
#include"Powell.h"
MyPowell::MyPowell(vector<Point2d> &dstpoints, vector<double>& params, vector<Point> &keypoint_index)
{
this->dstpoints = dstpoints;
this->myparams = params;
this->keypoint_index = keypoint_index;
N = params.size();
itmax = N * N;
usingAorB = 1;
}
MyPowell::MyPowell(Point2d & dst_br, vector<double>& params, Point2d & dims)
{
this->dst_br = dst_br;
this->myparams.push_back(dims.x);
this->myparams.push_back(dims.y);
this->params = params;
this->dims = dims;
N = 2;
itmax = N * 1000;
usingAorB = 2;
}
MyPowell::MyPowell()
{
usingAorB = 3;
}
double MyPowell::obj(vector<double> &myparams)
{
if (1 == usingAorB)
{
vector<Point2d> ppts = Dewarp::projectKeypoints(keypoint_index, myparams);
double total = 0;
for (int i = 0; i < ppts.size(); i++)
{
double x = dstpoints[i].x - ppts[i].x;
double y = dstpoints[i].y - ppts[i].y;
total += (x * x + y * y);
}
return total;
}
else if(2 == usingAorB)
{
dims.x = myparams[0];
dims.y = myparams[1];
//cout << "dims.x " << dims.x << " dims.y " << dims.y << endl;
vector<Point2d> vdims = { dims };
vector<Point2d> proj_br = Dewarp::projectXY(vdims, params);
double total = 0;
double x = dst_br.x - proj_br[0].x;
double y = dst_br.y - proj_br[0].y;
total += (x * x + y * y);
return total;
}
return 0;
}
void MyPowell::powell(vector<double> &x, vector<vector<double>> &direc, double ftol, double &fval)
{
vector<double> x1;
vector<double> x2;
vector<double> direc1;
int myitmax = 20;
if(N>500)
myitmax = 10;
else if (N > 300)
{
myitmax = 15;
}
double fx2, t, fx, dum, delta;
fval = obj(x);
int bigind;
for (int j = 0; j < N; j++)
{
x1.push_back(x[j]);
}
int iter = 0;
while (true)
{
do
{
do
{
iter += 1;
fx = fval;
bigind = 0;
delta = 0.0;
for (int i = 0; i < N; i++)
{
direc1 = direc[i];
fx2 = fval;
linmin(x, direc1, N, fval);
if (fabs(fx2 - fval) > delta)
{
delta = fabs(fx2 - fval);
bigind = i;
}
}
if (2.0 * fabs(fx - fval) <= ftol * (fabs(fx) + fabs(fval)) + 1e-7)
{
erase(direc1, x2, x1);
return;
}
if (iter >= itmax)
{
cout << "powell exceeding maximum iterations" << endl;
return;
}
if (!x2.empty())
{
x2.clear();
}
for (int j = 0; j < N; j++)
{
x2.push_back(2.0*x[j] - x1[j]);
direc1[j] = x[j] - x1[j];
x1[j] = x[j];
}
myitmax--;
cout << fx2 << endl;
fx2 = obj(x2);
if (myitmax < 0)
return;
} while (fx2 >= fx);
dum = fx - 2 * fval + fx2;
t = 2.0*dum*pow((fx - fval - delta), 2) - delta * pow((fx - fx2), 2);
} while (t >= 0.0);
linmin(x, direc1, N, fval);
direc[bigind] = direc1;
}
}
double MyPowell::sign(double a)//, double b)
{
if (a > 0.0)
{
return 1;
}
else
{
if (a < 0.0)
{
return -1;
}
}
return 0;
}
double MyPowell::sqr(double a)
{
return a * a;
}
void MyPowell::linmin(vector<double>& p, vector<double>& xit, int n, double &fret)
{
double tol = 1e-2;
ncom = n;
pcom = p;
xicom = xit;
double ax = 0.0;
double xx = 1.0;
double bx = 0.0;
double fa, fb, fx, xmin;
mnbrak(ax, xx, bx, fa, fx, fb);
fret = brent(ax, xx, bx, xmin, tol);
for (int i = 0; i < n; i++)
{
xit[i] = (xmin * xit[i]);
p[i] += xit[i];
}
}
void MyPowell::mnbrak(double & ax, double & bx, double & cx,
double & fa, double & fb, double & fc)
{
const double GOLD = 1.618034, GLIMIT = 110.0, TINY = 1e-20;
double val, fw, tmp2, tmp1, w, wlim;
double denom;
fa = f1dim(ax);
fb = f1dim(bx);
if (fb > fa)
{
val = ax;
ax = bx;
bx = val;
val = fb;
fb = fa;
fa = val;
}
cx = bx + GOLD * (bx - ax);
fc = f1dim(cx);
int iter = 0;
while (fb >= fc)
{
tmp1 = (bx - ax) * (fb - fc);
tmp2 = (bx - cx) * (fb - fa);
val = tmp2 - tmp1;
if (fabs(val) < TINY)
{
denom = 2.0*TINY;
}
else
{
denom = 2.0*val;
}
w = bx - ((bx - cx)*tmp2 - (bx - ax)*tmp1) / (denom);
wlim = bx + GLIMIT * (cx - bx);
if ((bx - w) * (w - cx) > 0.0)
{
fw = f1dim(w);
if (fw < fc)
{
ax = bx;
fa = fb;
bx = w;
fb = fw;
return;
}
else if (fw > fb)
{
cx = w;
fc = fw;
return;
}
w = cx + GOLD * (cx - bx);
fw = f1dim(w);
}
else
{
if ((cx - w)*(w - wlim) >= 0.0)
{
fw = f1dim(w);
if (fw < fc)
{
bx = cx;
cx = w;
w = cx + GOLD * (cx - bx);
fb = fc;
fc = fw;
fw = f1dim(w);
}
}
else if ((w - wlim)*(wlim - cx) >= 0.0)
{
w = wlim;
fw = f1dim(w);
}
else
{
w = cx + GOLD * (cx - bx);
fw = f1dim(w);
}
}
ax = bx;
bx = cx;
cx = w;
fa = fb;
fb = fc;
fc = fw;
}
}
double MyPowell::f1dim(double x)
{
vector<double> xt;
for (int j = 0; j < ncom; j++)
{
xt.push_back(pcom[j] + x * xicom[j]);
}
return obj(xt);
}
double MyPowell::brent(double ax, double bx, double cx, double & xmin, double tol = 1.48e-8)
{
const double CGOLD = 0.3819660, ZEPS = 1.0e-4;
int itmax = 500;
double a = MIN(ax, cx);
double b = MAX(ax, cx);
double v = bx;
double w = v, x = v;
double deltax = 0.0;
double fx = f1dim(x);
double fv = fx;
double fw = fx;
double rat = 0, u = 0, fu;
int iter;
int done;
double dx_temp, xmid, tol1, tol2, tmp1, tmp2, p;
for (iter = 0; iter < 500; iter++)
{
xmid = 0.5 * (a + b);
tol1 = tol * fabs(x) + ZEPS;
tol2 = 2.0*tol1;
if (fabs(x - xmid) <= (tol2 - 0.5*(b - a)))
break;
done = -1;
if (fabs(deltax) > tol1)
{
tmp1 = (x - w) * (fx - fv);
tmp2 = (x - v) * (fx - fw);
p = (x - v) * tmp2 - (x - w) * tmp1;
tmp2 = 2.0 * (tmp2 - tmp1);
if (tmp2 > 0.0)
p = -p;
tmp2 = fabs(tmp2);
dx_temp = deltax;
deltax = rat;
if ((p > tmp2 * (a - x)) && (p < tmp2 * (b - x)) &&
fabs(p) < fabs(0.5 * tmp2 * dx_temp))
{
rat = p / tmp2;
u = x + rat;
if ((u - a) < tol2 || (b - u) < tol2)
{
rat = fabs(tol1) * sign(xmid - x);
}
done = 0;
}
}
if(done)
{
if (x >= xmid)
{
deltax = a - x;
}
else
{
deltax = b - x;
}
rat = CGOLD * deltax;
}
if (fabs(rat) >= tol1)
{
u = x + rat;
}
else
{
u = x + fabs(tol1) * sign(rat);
}
fu = f1dim(u);
if (fu > fx)
{
if (u < x)
{
a = u;
}
else
{
b = u;
}
if (fu <= fw || w == x)
{
v = w;
w = u;
fv = fw;
fw = fu;
}
else if (fu <= fv || v == x || v == w)
{
v = u;
fv = fu;
}
}
else
{
if (u >= x)
a = x;
else
b = x;
v = w;
w = x;
x = u;
fv = fw;
fw = fx;
fx = fu;
}
}
if(iter > itmax)
cout << "\n Brent exceed maximum iterations.\n\n";
xmin = x;
return fx;
}
vector<double> MyPowell::usePowell()
{
ftol = 1e-4;
vector<vector<double>> xi;
for (int i = 0; i < N; i++)
{
vector<double> xii;
for (int j = 0; j < N; j++)
{
xii.push_back(0);
}
xii[i]=(1.0);
xi.push_back(xii);
}
double fret = 0;
powell(myparams, xi, ftol, fret);
//for (int i = 0; i < xi.size(); i++)
//{
// double a = obj(xi[i]);
// if (fret > a)
// {
// fret = a;
// myparams = xi[i];
// }
//}
cout << "final result" << fret << endl;
return myparams;
}
void MyPowell::erase(vector<double>& pbar, vector<double>& prr, vector<double>& pr)
{
for (int i = 0; i < pbar.size(); i++)
{
pbar[i] = 0;
}
for (int i = 0; i < prr.size(); i++)
{
prr[i] = 0;
}
for (int i = 0; i < pr.size(); i++)
{
pr[i] = 0;
}
}
I used PRAXIS library, because it doesn't need derivative information and is fast.
I modified the code a little to my needs and now it is faster than original version written in Python.
Given two points in the x, y plane:
x, f(x)
1, 3
2, 5
I can interpolate them using Lagrange and find f(1.5), which result in 4. Thinking a little I managed to find a way to discover the coefficients of the equation:
void l1Coefficients(const vector<double> &x, const vector<double> &y) {
double a0 = y[0]/(x[0]-x[1]);
double a1 = y[1]/(x[1]-x[0]);
double b0 = (-x[1]*y[0])/(x[0]-x[1]);
double b1 = (-x[0]*y[1])/(x[1]-x[0]);
double a = a0 + a1;
double b = b0 + b1;
cout << "P1(x) = " << a << "x +" << b << endl;
}
That gives me P1(x) = 2x +1.
Thinking a little more I was able to extend that to 2nd order equations. So, given the points:
1, 1
2, 4
3, 9
I found the equation P2(x) = 1x^2 +0x +0 with the following:
void l2Coefficients(const vector<double> &x, const vector<double> &y) {
double a0 = y[0] / ((x[0]-x[1])*(x[0]-x[2]));
double a1 = y[1] / ((x[1]-x[0])*(x[1]-x[2]));
double a2 = y[2] / ((x[2]-x[0])*(x[2]-x[1]));
double b0 = -(x[1]+x[2])*y[0] / ((x[0]-x[1])*(x[0]-x[2]));
double b1 = -(x[0]+x[2])*y[1] / ((x[1]-x[0])*(x[1]-x[2]));
double b2 = -(x[0]+x[1])*y[2] / ((x[2]-x[0])*(x[2]-x[1]));
double c0 = (x[1]*x[2])*y[0] / ((x[0]-x[1])*(x[0]-x[2]));
double c1 = (x[0]*x[2])*y[1] / ((x[1]-x[0])*(x[1]-x[2]));
double c2 = (x[0]*x[1])*y[2] / ((x[2]-x[0])*(x[2]-x[1]));
double a = a0 + a1 + a2;
double b = b0 + b1 + b2;
double c = c0 + c1 + c2;
cout << "P2(x) = " << a << "x^2 +" << b << "x +" << c << endl;
}
Working hard I actually was able to find the coefficients for equations of order up to 4th.
How to find the coefficients of order n equations? Where
Pn(x) = c_2x^2 + c_1x^1 + c_0x^0 + ...
It's a simple linear algebra problem.
We have a set of N samples of the form xk -> f(xk) and we know the general form of function f(x), which is:
f(x) = c0x0 + c1x1 + ... + cN-1xN-1
We want to find the coefficients c0 ... cN-1. To achieve that, we build a system of N equations of the form:
c0xk0 + c1xk1 + ... + cN-1xkN-1 = f(xk)
where k is the sample number. Since xk and f(xk) are constants rather than variables, we have a linear system of equations.
Expressed in terms of linear algebra, we have to solve:
Ac = b
where A is a Vandermonde matrix of powers of x and b is a vector of f(xk) values.
To solve such a system, you need a linear algebra library, such as Eigen. See here for example code.
The only thing that can go wrong with such an approach is the system of linear equations being under-determined, which will happen if your N samples can be fit with with a polynomial of degree less than N-1. In such a case you can still solve this system with Moore-Penrose pseudo inverse like this:
c = pinv(A)*b
Unfortunately, Eigen doesn't have a pinv() implementation, though it's pretty easy to code it by yourself in terms of Singular Value Decomposition (SVD).
I created a naive implementation of the matrix solution:
#include <iostream>
#include <vector>
#include <stdexcept>
class Matrix
{
private:
class RowIterator
{
public:
RowIterator(Matrix* mat, int rowNum) :_mat(mat), _rowNum(rowNum) {}
double& operator[] (int colNum) { return _mat->_data[_rowNum*_mat->_sizeX + colNum]; }
private:
Matrix* _mat;
int _rowNum;
};
int _sizeY, _sizeX;
std::vector<double> _data;
public:
Matrix(int sizeY, int sizeX) : _sizeY(sizeY), _sizeX(sizeX), _data(_sizeY*_sizeX){}
Matrix(std::vector<std::vector<double> > initList) : _sizeY(initList.size()), _sizeX(_sizeY>0 ? initList.begin()->size() : 0), _data()
{
_data.reserve(_sizeY*_sizeX);
for (const std::vector<double>& list : initList)
{
_data.insert(_data.end(), list.begin(), list.end());
}
}
RowIterator operator[] (int rowNum) { return RowIterator(this, rowNum); }
int getSize() { return _sizeX*_sizeY; }
int getSizeX() { return _sizeX; }
int getSizeY() { return _sizeY; }
Matrix reduce(int rowNum, int colNum)
{
Matrix mat(_sizeY-1, _sizeX-1);
int rowRem = 0;
for (int y = 0; y < _sizeY; y++)
{
if (rowNum == y)
{
rowRem = 1;
continue;
}
int colRem = 0;
for (int x = 0; x < _sizeX; x++)
{
if (colNum == x)
{
colRem = 1;
continue;
}
mat[y - rowRem][x - colRem] = (*this)[y][x];
}
}
return mat;
}
Matrix replaceCol(int colNum, std::vector<double> newCol)
{
Matrix mat = *this;
for (int y = 0; y < _sizeY; y++)
{
mat[y][colNum] = newCol[y];
}
return mat;
}
};
double solveMatrix(Matrix mat)
{
if (mat.getSizeX() != mat.getSizeY()) throw std::invalid_argument("Not square matrix");
if (mat.getSize() > 1)
{
double sum = 0.0;
int sign = 1;
for (int x = 0; x < mat.getSizeX(); x++)
{
sum += sign * mat[0][x] * solveMatrix(mat.reduce(0, x));
sign = -sign;
}
return sum;
}
return mat[0][0];
}
std::vector<double> solveEq(std::vector< std::pair<double, double> > points)
{
std::vector<std::vector<double> > xes(points.size());
for (int i = 0; i<points.size(); i++)
{
xes[i].push_back(1);
for (int j = 1; j<points.size(); j++)
{
xes[i].push_back(xes[i].back() * points[i].first);
}
}
Matrix mat(xes);
std::vector<double> ys(points.size());
for (int i = 0; i < points.size(); i++)
{
ys[i] = points[i].second;
}
double w = solveMatrix(mat);
std::vector<double> result(points.size(), 0.0);
if(w!=0)
for (int i = 0; i < ys.size(); i++)
{
result[i] = solveMatrix(mat.replaceCol(i, ys));
result[i] /= w;
}
return result;
}
void printCoe(std::vector<double> coe)
{
std::cout << "f(x)=";
bool notFirstSign = false;
for (int i = coe.size() - 1; i >= 0; i--)
{
if (coe[i] != 0.0)
{
if (coe[i] >= 0.0 && notFirstSign)
std::cout << "+";
notFirstSign = true;
if (coe[i] != 1.0)
if (coe[i] == -1.0)
std::cout << "-";
else
std::cout << coe[i];
if (i == 1)
std::cout << "x";
if (i>1)
std::cout << "x^" << i;
}
}
std::cout << std::endl;
}
int main()
{
std::vector< std::pair<double, double> > points1 = { {3,31}, {6,94}, {4,48}, {0,4} };
std::vector<double> coe = solveEq(points1);
printCoe(coe);
std::vector< std::pair<double, double> > points2 = { { 0,0 },{ 1,-1 },{ 2,-16 },{ 3,-81 },{ 4,-256 } };
printCoe(solveEq(points2));
printCoe(solveEq({ { 0,0 },{ 1,1 },{ 2,8 },{ 3,27 } }));
std::cin.ignore();
return 0;
}
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.
I need some help here. Please excuse the complexity of the code. Basically, I am looking to use the bisection method to find a value "Theta" and each i increment.
I know that all the calculations work fine when I know the Theta, and I have the code run to just simply calculate all the values, but when I introduce a while loop and the bisection method to have the code approximate Theta, I can't seem to get it to run correctly. I am assuming I have my while loop set up incorrectly....
#include <math.h>
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm> // std::max
using namespace std;
double FuncM(double theta, double r, double F, double G, double Gprime, double d_t, double sig);
double FuncM(double theta, double r, double F, double G, double Gprime, double d_t, double sig)
{
double eps = 0.0001;
return ((log(max((r + (theta + F - 0.5 * G * Gprime ) * d_t), eps))) / sig);
}
double FuncJSTAR(double m, double x_0, double d_x);
double FuncJSTAR(double m, double x_0, double d_x)
{
return (int(((m - x_0) / d_x)+ 0.5));
}
double FuncCN(double m, double x_0, double j, double d_x);
double FuncCN(double m, double x_0, double j, double d_x)
{
return (m - x_0 - j * d_x);
}
double FuncPup(double d_t, double cn, double d_x);
double FuncPup(double d_t, double cn, double d_x)
{
return (((d_t + pow(cn, 2.0)) / (2.0 * pow(d_x, 2.0))) + (cn / (2.0 * d_x)));
}
double FuncPdn(double d_t, double cn, double d_x);
double FuncPdn(double d_t, double cn, double d_x)
{
return (((d_t + pow(cn, 2.0)) / (2.0 * pow(d_x, 2.0))) - (cn / (2.0 * d_x)));
}
double FuncPmd(double pd, double pu);
double FuncPmd(double pd, double pu)
{
return (1 - pu - pd);
}
int main()
{
const int Maturities = 5;
const double EPS = 0.00001;
double TermStructure[Maturities][2] = {
{0.5 , 0.05},
{1.0 , 0.06},
{1.5 , 0.07},
{2.0 , 0.075},
{3.0 , 0.085} };
//--------------------------------------------------------------------------------------------------------
vector<double> Price(Maturities);
double Initial_Price = 1.00;
for (int i = 0; i < Maturities; i++)
{
Price[i] = Initial_Price * exp(-TermStructure[i][1] * TermStructure[i][0]);
}
//--------------------------------------------------------------------------------------------------------
int j_max = 8;
int j_range = ((j_max * 2) + 1);
//--------------------------------------------------------------------------------------------------------
// Set up vector of possible j values
vector<int> j_value(j_range);
for (int j = 0; j < j_range; j++)
{
j_value[j] = j_max - j;
}
//--------------------------------------------------------------------------------------------------------
double dt = 0.5;
double dx = sqrt(3 * dt);
double sigma = 0.15;
double mean_reversion = 0.2; // "a" value
//--------------------------------------------------------------------------------------------------------
double r0 = TermStructure[0][1]; // Initialise r(0) in case no corresponding dt rate in term structure
//--------------------------------------------------------------------------------------------------------
double x0 = log(r0) / sigma;
//--------------------------------------------------------------------------------------------------------
vector<double> r_j(j_range); // rate at each j
vector<double> F_r(j_range);
vector<double> G_r(j_range);
vector<double> G_prime_r(j_range);
for(int j = 0; j < j_range; j++)
{
if (j == j_max)
{
r_j[j] = r0;
}
else
{
r_j[j] = exp((x0 + j_value[j]*dx) * sigma);
}
F_r[j] = -mean_reversion * r_j[j];
G_r[j] = sigma * r_j[j];
G_prime_r[j] = sigma;
}
//--------------------------------------------------------------------------------------------------------
vector<vector<double>> m((j_range), vector<double>(Maturities));
vector<vector<int>> j_star((j_range), vector<int>(Maturities));
vector<vector<double>> Central_Node((j_range), vector<double>(Maturities));
vector<double> Theta(Maturities - 1);
vector<vector<double>> Pu((j_range), vector<double>(Maturities));
vector<vector<double>> Pd((j_range), vector<double>(Maturities));
vector<vector<double>> Pm((j_range), vector<double>(Maturities));
vector<vector<double>> Q((j_range), vector<double>(Maturities));// = {}; // Arrow Debreu Price. Initialised all array values to 0
vector<double> Q_dt_sum(Maturities);// = {}; // Sum of Arrow Debreu Price at each time step. Initialised all array values to 0
//--------------------------------------------------------------------------------------------------------
double Theta_A, Theta_B, Theta_C;
int JSTART;
int JEND;
int TempStart;
int TempEnd;
int max;
int min;
vector<vector<int>> Up((j_range), vector<int>(Maturities));
vector<vector<int>> Down((j_range), vector<int>(Maturities));
// Theta[0] = 0.0498039349327417;
// Theta[1] = 0.0538710670441647;
// Theta[2] = 0.0181648634139392;
// Theta[3] = 0.0381183886467521;
for(int i = 0; i < (Maturities-1); i++)
{
Theta_A = 0.00;
Theta_B = TermStructure[i][1];
Q_dt_sum[0] = Initial_Price;
Q_dt_sum[i+1] = 0.0;
while (fabs(Theta_A - Theta_B) >= 0.0000001)
{
max = 1;
min = 10;
if (i == 0)
{
JSTART = j_max;
JEND = j_max;
}
else
{
JSTART = TempStart;
JEND = TempEnd;
}
for(int j = JSTART; j >= JEND; j--)
{
Theta_C = (Theta_A + Theta_B) / 2.0; // If Theta C is too low, the associated Price will be higher than Price from initial term structure. (ie P(Theta C) > P(i+2) for Theta C < Theta)
// If P_C > P(i+2), set Theta_B = Theta_C, else if P_C < P(i+2), set Theta_A = Theta_C, Else if P_C = P(i+2), Theta_C = Theta[i]
//cout << Theta_A << " " << Theta_B << " " << Theta_C << endl;
m[j][i] = FuncM(Theta[i], r_j[j], F_r[j], G_r[j], G_prime_r[j], dt, sigma);
j_star[j][i] = FuncJSTAR(m[j][i], x0, dx);
Central_Node[j][i] = FuncCN(m[j][i], x0, j_star[j][i], dx);
Pu[j][i] = FuncPup(dt, Central_Node[j][i], dx);
Pd[j][i] = FuncPdn(dt, Central_Node[j][i], dx);
Pm[j][i] = FuncPmd(Pd[j][i], Pu[j][i]);
for (int p = 0; p < j_range; p++)
{
Q[p][i] = 0; // Clear Q array
}
Q[j_max][0] = Initial_Price;
Q[j_max -(j_star[j][i]+1)][i+1] = Q[j_max - (j_star[j][i]+1)][i+1] + Q[j][i] * Pu[j][i] * exp(-r_j[j] * dt);
Q[j_max -(j_star[j][i] )][i+1] = Q[j_max - (j_star[j][i] )][i+1] + Q[j][i] * Pm[j][i] * exp(-r_j[j] * dt);
Q[j_max -(j_star[j][i]-1)][i+1] = Q[j_max - (j_star[j][i]-1)][i+1] + Q[j][i] * Pd[j][i] * exp(-r_j[j] * dt);
}
for (int j = 0; j < j_range; j++)
{
Up[j][i] = j_star[j][i] + 1;
Down[j][i] = j_star[j][i] - 1;
if (Up[j][i] > max)
{
max = Up[j][i];
}
if ((Down[j][i] < min) && (Down[j][i] > 0))
{
min = Down[j][i];
}
}
TempEnd = j_max - (max);
TempStart = j_max - (min);
for (int j = 0; j < j_range; j++)
{
Q_dt_sum[i+1] = Q_dt_sum[i+1] + Q[j][i] * exp(-r_j[j] * dt);
cout << Q_dt_sum[i+1] << endl;
}
if (Q_dt_sum[i+1] == Price[i+2])
{
Theta[i] = Theta_C;
break;
}
if (Q_dt_sum[i+1] > Price[i+2])
{
Theta_B = Theta_C;
}
else if (Q_dt_sum[i+1] < Price[i+2])
{
Theta_A = Theta_C;
}
}
cout << Theta[i] << endl;
}
return 0;
}
Ok, my bad. I had a value being called incorrectly.
All good.