Solving an uncomplete nonlinear system of equations with Z3 - c++

I am trying to make a solver for nonlinear system of equations using the Z3 library in c++.
It will exists with multiple equations and variables. Depending on previous steps in my software, it could be that some variables are unknown.
When too many variables are unknown and the system does not have a single solution, I want to be notified about this.
I made a simple fictional system of equations for testing that looks as follows:
Ax = 1
Ay = 1
Bx = 3
By = 2
Cx = 7
Cy = Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax)
I wrote the following code to solve the system, in this example fairly easy:
context ctx;
expr Ax = ctx.real_const("Ax");
expr Ay = ctx.real_const("Ay");
expr Bx = ctx.real_const("Bx");
expr By = ctx.real_const("By");
expr Cx = ctx.real_const("Cx");
expr Cy = ctx.real_const("Cy");
solver s(ctx);
s.add(Ax == 1);
s.add(Ay == 1);
s.add(Bx == 3);
s.add(By == 2);
s.add(Cx == 7);
s.add(Cy == Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax));
std::cout << s.check() << "\n";
model m = s.get_model();
auto CySolution = m.eval(Cy, true);
std::cout << CySolution << "\n";
As output I get the following:
sat
4.0
When for example "Ax" would be unknown, this can be simulated using following code:
context ctx;
expr Ax = ctx.real_const("Ax");
expr Ay = ctx.real_const("Ay");
expr Bx = ctx.real_const("Bx");
expr By = ctx.real_const("By");
expr Cx = ctx.real_const("Cx");
expr Cy = ctx.real_const("Cy");
solver s(ctx);
//s.add(Ax == 1);
s.add(Ay == 1);
s.add(Bx == 3);
s.add(By == 2);
s.add(Cx == 7);
s.add(Cy == Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax));
std::cout << s.check() << "\n";
model m = s.get_model();
auto CySolution = m.eval(Cy, true);
std::cout << CySolution << "\n";
Now the output is:
sat
(/ 78.0 23.0)
I have tried detect when this system of equations give an implicit solution using functions as "expr.get_sort()" or "expr.is_real", but there is never a difference between the complete solution and the implicit one.
Now I have two questions:
How can I interpret "(/ 78.0 23.0)"?
Is there a proper way to detect if the solution is an implicit function or not?
Thanks in advance for any help!

(/ 78.0 23.0) simply means 78/23, i.e., approx. 3.39. Z3 prints real-values in this format since they are infinitely precise; as the fraction might require an unbounded number of digits in general.
Your question regarding "proper way to detect is an implicit function" is a bit ambiguous. I assume what you mean is if there's a unique solution? That is, if a variable's value is "forced" by all the other equations or not?
If that's the case, i.e., to check that a solution is unique, you'd essentially get the first solution, then assert the negation of that solution and ask if there's some other solution with this additional constraint: If the solver comes back unsat then you know the solution was unique. See many questions on stack-overflow regarding how to get multiple solutions from the solver.

Related

Localization (multilateration) code producing the same coordinates every time?

EDIT: The localization is always about x=1980.000032943933547358028590679168701171875, y=3191.99997642902735606185160577297210693359375
I've written the following code to solve the Time Delay of Arrival problem. That is, given the location of three observers, the velocity of some signal, and the time at which each receiver "saw" the signal, I want to localize the source. Here, we assume that the source and the observers are in a 2-dimensional plane (a planar Euclidean space).
My solution is as follows:
Given the time at which each observer saw the signal, I elect one receiver to be the "baseline", which I take to be t=0. I then subtract that time from the Time of Arrival at the other two observers. Now, I assign to each observer a circle, with the radius given by this difference (the "baseline" observer starts with r=0), and I slowly increment the radius of each circle until all three intersect at some point.
In reality, it's unlikely that they'll ever precisely intersect at a single point, as, for one, I can only increase the radius by a discrete amount with each iteration, and we also assume, but do not known, that the observer's clocks are precisely synchronized.
To solve this, I adapted Paul Bourke's code: http://paulbourke.net/geometry/circlesphere/tvoght.c (reasoning here: http://paulbourke.net/geometry/circlesphere/). My adaptation was more-or-less identical to this one: https://stackoverflow.com/a/19724186/14073182.
My problem is, the code always produces the same localization, to within a few tenths of a unit. I tried generating some psuedodata (i.e. pick some location, compute the expected delay, feed that into the algorithm and see if it reconstructs the correct localization), and the algorithm still produces roughly the same localization... namely, fairly close to the center of the triangle formed by the three receivers.
Any idea what I'm doing wrong here? I've talked with a few people (physicists working in GIS, geodesics, similar fields, and a mathematician), and haven't gotten anywhere.
My code is below (it's fairly brief, all things considered). To localize some source, call localizeSource(a,b,c,&xf,&xy). Where a, b, and c are the delays (radii), and xf, xy are where the coordinates of the localization will be stored.
#define EPSILON 0.0001 // Define some threshold
#define x0 3000.00
#define y0 3600.00
#define x1 2100.00
#define y1 2100.00
#define x2 0960.00
#define y2 3600.00
bool findIntersection(double r0, double r1, double r2, double *xf, double *yf){
double a, dx, dy, d, h, rx, ry;
double point2_x, point2_y;
dx = x1 - x0;
dy = y1 - y0;
d = sqrt((dy*dy) + (dx*dx));
if (d > (r0 + r1))
{
return false;
}
a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;
point2_x = x0 + (dx * a/d);
point2_y = y0 + (dy * a/d);
h = sqrt((r0*r0) - (a*a));
rx = -dy * (h/d);
ry = dx * (h/d);
double intersectionPoint1_x = point2_x + rx;
double intersectionPoint2_x = point2_x - rx;
double intersectionPoint1_y = point2_y + ry;
double intersectionPoint2_y = point2_y - ry;
dx = intersectionPoint1_x - x2;
dy = intersectionPoint1_y - y2;
double d1 = sqrt((dy*dy) + (dx*dx));
dx = intersectionPoint2_x - x2;
dy = intersectionPoint2_y - y2;
double d2 = sqrt((dy*dy) + (dx*dx));
if(fabs(d1 - r2) < EPSILON) {
std::cout << std::setprecision(100) << intersectionPoint1_x << ", " << intersectionPoint1_y << "\n";
*xf = intersectionPoint1_x; *yf = intersectionPoint1_y;
return true;
}
else if(fabs(d2 - r2) < EPSILON) {
std::cout << std::setprecision(100) << intersectionPoint2_x << ", " << intersectionPoint2_y << "\n";
*xf = intersectionPoint2_x; *yf = intersectionPoint2_y;
return true;
}
else {
return false;
}
}
void localizeSource(double r0, double r1, double r2, double *xf, double *yf){
bool foundSource = false;
while(foundSource == false){
foundSource = findIntersection(r0, r1, r2, xf, yf);
r0 += 0.0001; r1 += 0.0001; r2 += 0.0001;
}
}
int main(){
double xf, xy;
localizeSource(1000,3000,0,&xf,&xy);
}
It's not super clear what you are trying to solve... Your question talks about "time delay [sic] of arrival" but then you link to the "intersection of circles" algorithm. TDoA algorithm uses parabolas not circles.
Time Difference of Arrival algorithm:
Someone on SO already wrote sample code using Fang's Method
Issues implementing the Fang Algorithm for TDOA Trilateration
Hyperbolic Position Location Estimation in the Multipath Propagation Environment
Time Difference of Arrival (TDoA) Localization Combining Weighted Least Squares and Firefly Algorithm
If you're just looking for the Triangulation / Trilateration formula:
A = 2*x2 - 2*x1
B = 2*y2 - 2*y1
C = r1*r1 - r2*r2 - x1*x1 + x2*x2 - y1*y1 + y2*y2
D = 2*x3 - 2*x2
E = 2*y3 - 2*y2
F = r2*r2 - r3*r3 - x2*x2 + x3*x3 - y2*y2 + y3*y3
x = (C*E - F*B) / (E*A - B*D)
y = (C*D - A*F) / (B*D - A*E)

What is wrong with this code as the answer to the following online judge problem? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
The problem states that given the radius of three circles, and assuming that three circles touch themselves in a way shown:
we need to find out the area of the blue portion between them. I have written the following code and run a few test cases. All of them worked fine. The online judge says the answer is wrong.
#include <iostream>
#include <math.h>
#include <iomanip>
using namespace std;
int main()
{
double r1, r2, r3, tarea, r1area, r2area, r3area;
long double res;
int i, test;
cin >> test;
for(i = 1;i <= test;i++)
{
cin >> r1 >> r2 >> r3;
tarea = sqrt(((r1 + r2 + r3)*r1*r2*r3));
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
r3area = 0.5*(r3*r3)*(asin((2*tarea)/((r1+r2)*(r2+r3))));
res = tarea - (r1area + r2area + r3area);
cout << "Case " << i << ": " << fixed << setprecision(8) << res << endl;
}
return 0;
}
The lack of simmetry in the formula is a strong evidence that something is wrong in the posted code, as shown in idclev 463035818's answer.
There's another mathematical issue, though, that may come up in the tests.
The code tries to implement the law of sines, in order to calculate the angles of the triangle formed by the centers of the circles. The problem is that when one of the radii is small enough, the corresponding angle in the triangle become obtuse and the chosen formula doesn't hold anymore.
Consider the documentation of std::asin, the returned value is in the range [-π/2, π/2], it can't represent an obtuse angle.
We could rewrite the formulas using the law of cosines (which doesn't have this issue) or we could just evaluate the greatest angle remembering that the three interior angles of a triangle add up to π.
#include <cmath>
#if __has_include(<numbers>)
# include <numbers>
#else
namespace std::numbers {
inline constexpr double pi = 3.14159265358979323846;
}
#endif
double area_circumscribed_by_circles(double r1, double r2, double r3)
{
// I want the third to have the smaller radius.
if (r1 < r2) {
if ( r1 < r3 )
std::swap(r1, r3);
} else {
if ( r2 < r3 )
std::swap(r2, r3);
}
if (r3 == 0.0)
return 0.0;
// Apply Heron's formula to find the area of the triangle
// formed by the centers of the circles.
double area = std::sqrt((r1 + r2 + r3) * r1 * r2 * r3);
// Find the first two angles using the law of sines.
double angle_1 = std::asin(2.0 * area / ((r1 + r2) * (r1 + r3)));
double angle_2 = std::asin(2.0 * area / ((r2 + r1) * (r2 + r3)));
// The third angle may be obtuse, we can't use the previous formula.
double angle_3 = std::numbers::pi - (angle_1 + angle_2);
// Now we can subtract the area of the sectors.
return area - 0.5 * (r1 * r1 * angle_1 + r2 * r2 * angle_2 + r3 * r3 * angle_3);
}
Look closely at the formulas:
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
r3area = 0.5*(r3*r3)*(asin((2*tarea)/((r1+r2)*(r2+r3))));
res = tarea - (r1area + r2area + r3area);
Without entering into the details of the maths I know that they cannot be correct. Why? Symmetry! The final result does not change if you permute the labeling of the circles. This is fine for the last line, because with
auto a = r1area;
auto b = r2area;
auto c = r3area;
all those expressions yield the same result:
res = tarea - (a + b + c);
res = tarea - (a + c + b);
res = tarea - (b + a + c);
res = tarea - (b + c + a);
....
Similarly you should get the same result for permutations of r1,r2 and r3 and this is not the case.
This
r1area = 0.5*(r1*r1)*(asin((2*tarea)/((r1+r2)*(r1+r3))));
can be rewritten as
r1area = calc_area( r1*r1, r1+r2, r1+r3);
or
Aarea = calc_area( A*A, A+B, A+C);
Because of the symmetry of the problem, it should be possible to get the forumla for Barea by permuting A,B and C, but if we swap A and B (those are just labels!) then we get
Barea = calc_area( B*B, B+A, B+C);
while you have:
r2area = 0.5*(r2*r2)*(asin((2*tarea)/((r2+r3)*(r1+r3))));
// ->
r2area = calc_area( r2*r2, r2+r3, r1+r3);
// ->
Barea = calc_area( B*B, B+C, A+C);
Note that the last parameter is B+C vs A+C, ie XArea has X+Y,X+Z in one case but X+Y,Y+Z in the other. Hence no permutation of the labels can make those formulas the same. However, the area between the circles will not change if you put different labels on the circles, ergo your formulas cannot be correct.

sympy CSE: avoid pow/powf

When Sympy generates C code,
is there a way to enforce CSE optimizations for pow (or powf) occurrences in an expression?
For example, this code snippet
c, s = symbols('c s')
myexpr = c**6/1800 - c**5/100 - 0.00833333333333333*c**4*s**2 + 19*c**4/200 + 0.1*c**3*s**2 - 9*c**3/20 + c**2*s**4/120 - 0.57*c**2*s**2 + 43*c**2/40 - c*s**4/20 + 1.35*c*s**2 + 23*c/50 - 0.000555555555555556*s**6 + 19*s**4/200 - 1.075*s**2 - 2107/1800
import sympy
from sympy.codegen.ast import real, float64
sub_exprs,final_expr = sympy.cse([myexpr])
for var,expr in sub_exprs : print "const real", printing.ccode(expr, standard='C99', assign_to=var, type_aliases={real: float64})
print "return ",printing.ccode(final_expr[0], standard='C99', type_aliases={real: float64}),";"
produces the following disappointing output:
const real x0 = pow(c, 2);
const real x1 = pow(c, 3);
const real x2 = pow(c, 4);
const real x3 = pow(s, 2);
const real x4 = pow(s, 4);
return (1.0/1800.0)*pow(c, 6) - 1.0/100.0*pow(c, 5) + 1.3500000000000001*c*x3 - 1.0/20.0*c*x4 + (23.0/50.0)*c - 0.00055555555555555599*pow(s, 6) - 0.56999999999999995*x0*x3 + (1.0/120.0)*x0*x4 + (43.0/40.0)*x0 + 0.10000000000000001*x1*x3 - 9.0/20.0*x1 - 0.0083333333333333297*x2*x3 + (19.0/200.0)*x2 - 1.075*x3 + (19.0/200.0)*x4 - 2107.0/1800.0 ;
Pow optimizations have been completely ignored.
What is the workaround for this?
Remark: I saw that this issue is partially mentioned here:
"The code printers don’t print optimal code in many cases. An example of this is powers in C. x**2 prints as pow(x, 2) instead of x*x. Other optimizations (like mathematical simplifications) should happen before the code printers."
The CSE routine in sympy is not perfect (improved CSE is listed as an area for improvement), e.g.:
>>> sympy.cse([x**4, x**3*y])
([], [x**4, x**3*y])
Expanding pow in the printer or before the printer has been discussed some time, there is now a create_expand_pow optimization which can help some:
>>> expand_opt = create_expand_pow_optimization(3)
>>> expand_opt(x**5 + x**3)
x**5 + x*x*x
Note however that most compilers will already generate optimal assembly (regardless of CSE in the source code) if you pass them the right optimization flags.

Integrate function

I have this function to reach a certain 1 dimensional value accelerated and damped with overshoot. That is: given an inital value, a velocity and a acceleration (force/mass), the target value is attained by accelerating to it and gets increasingly damped while getting closer to the target value.
This all works fine, howver If i want to know what the TotalAngle is after time 't' I have to run this function say N steps with a 'small' dt to find the 'limit'.
I was wondering If i can (and how) to intergrate over dt so that the TotalAngle can be determined given a time 't' initially.
Regards, Tanks for any help.
dt = delta time step per frame
input = 1
TotalAngle = 0 at t=0
Velocity = 0 at t=0
void FAccelDampedWithOvershoot::Update(float dt, float input, float& Velocity, float& TotalAngle)
{
const float Force = 500000.f;
const float DampForce = 5000.f;
const float MaxAngle = 45.f;
const float InvMass = 1.f / 162400.f;
float target = MaxAngle * input;
float ratio = (target - TotalAngle) / MaxAngle;
float fMove = Force * ratio;
float fDamp = -Velocity * DampForce;
Velocity += (fMove + fDamp) * invMass * dt;
TotalAngle += Velocity * dt;
}
Updated with fixed bugs in math
Originally I've lost mass and MaxAngle a few times. This is why you should first solve it on a paper and then enter to the SO rather than trying to solve it in the text editor.
Anyway, I've fixed the math and now it seems to work reasonably well. I put fixed solution just over previous one.
Well, this looks like a Newtonian mechanics which means differential equations. Let's try to solve them.
SO is not very friendly to math formulas and I'm a bit bored to type characters so here is what I use:
F = Force
Fd = DampForce
MA = MaxAngle
A= TotalAngle
v = Velocity
m = 1 / InvMass
' for derivative i.e. something' is 1-st derivative of something by t and something'' is 2-nd derivative
if I divide you last two lines of code by dt and merge in all the other lines I can get (I also assume that input = 1 as other case is obviously symmetrical)
v' = ([F * (1 - A / MA)] - v * Fd) / m
and applying A' = v we get
m * A'' = F(1 - A/MA) - Fd * A'
or moving to one side we get a simple 2-nd order differential equation
m * A'' + Fd * A' + F/MA * A = F
IIRC, the way to solve it is to first solve characteristic equation which here is
m * x^2 + Fd * x + F/MA = 0
x[1,2] = (-Fd +/- sqrt(Fd^2 - 4*F*m/MA))/ (2*m)
I expect that part under sqrt i.e. (Fd^2 - 4*F*m/MA) is negative thus solution should be of the following form. Let
Dm = Fd/(2*m)
K = sqrt(F/MA/m - Dm^2)
(note the negated value under sqrt so it works now) then
A(t) = e^(-Dm*t) * [P * sin(K*t) + Q * cos(K*t)] + C
where P, Q and C are some constants.
The solution is easier to find as a sum of two solutions: some specific solution for
m * A'' + Fd * A' + F/MA * A = F
and a general solution for homogeneou
m * A'' + Fd * A' + F/MA * A = 0
that makes original conditions fit. Obviously specific solution A(t) = MA works and thus C = MA. So now we need to fit P and Q of general solution to match starting conditions. To find them we need
A(0) = - MA
A'(0) = V(0) = 0
Given that e^0 = 1, sin(0) = 0 and cos(0) = 1 you get something like
Q = -MA
P = 0
or
P = 0
Q = - MA
C = MA
thus
A(t) = MA * [1 - e^(-Dm*t) * cos(K*t)]
where
Dm = Fd/(2*m)
K = sqrt(F/MA/m - Dm^2)
which kind of makes sense given your task.
Note also that this equation assumes that everything happens in radians rather than degrees (i.e. derivative of [sin(t)]' is just cos(t)) so you should transform all your constants accordingly or transform the solution.
const float Force = 500000.f * M_PI / 180;
const float DampForce = 5000.f * M_PI / 180;
const float MaxAngle = M_PI_4;
which on my machine produces
Dm = 0.000268677541
K = 0.261568546
This seems to be similar to original funcion is I step with dt = 0.01f and the main obstacle seems to be precision loss because of float
Hope this helps!
This is not a full answer and I am sure someone else can work it out, but there is no room in the comments and it may help you find a better solution.
The image below shows the velocity (blue) as your function integrates at time steps 1. The red shows the function below that calculates the value for time t
The function F(t)
F(t) = sin((t / f) * pi * 2) * (1 / (((t / f) + a) ^ c)) * b
With f = 23.7, a = 1.4, c = 2, and b= 50 that give the red plot in the image above
All the values are just approximation.
f determines the frequency and is close to a match,
a,b,c control the falloff in amplitude and are a by eye guestimate.
If it does not matter that you have a perfect match then this will work for you. totalAngle uses the same function but t has 0.25 added to it. Unfortunately I did not get any values for a,b,c for totalAngle and I did notice that it was offset so you will have to add the offset value d (I normalised everything so have no idea what the range of totalAngle was)
Function F(t) for totalAngle
F(t) = sin(((t+0.25) / f) * pi * 2) * (1 / ((((t+0.25) / f) + a) ^ c)) * b + d
Sorry only have f = 23.7, c= 2, a~1.4 nothing for b=? d=?

How i can make matlab precision to be the same as in c++?

I have problem with precision. I have to make my c++ code to have same precision as matlab. In matlab i have script which do some stuff with numbers etc. I got code in c++ which do the same as that script. Output on the same input is diffrent :( I found that in my script when i try 104 >= 104 it returns false. I tried to use format long but it did not help me to find out why its false. Both numbers are type of double. i thought that maybe matlab stores somewhere the real value of 104 and its for real like 103.9999... So i leveled up my precision in c++. It also didnt help because when matlab returns me value of 50.000 in c++ i got value of 50.050 with high precision. Those 2 values are from few calculations like + or *. Is there any way to make my c++ and matlab scrips have same precision?
for i = 1:neighbors
y = spoints(i,1)+origy;
x = spoints(i,2)+origx;
% Calculate floors, ceils and rounds for the x and y.
fy = floor(y); cy = ceil(y); ry = round(y);
fx = floor(x); cx = ceil(x); rx = round(x);
% Check if interpolation is needed.
if (abs(x - rx) < 1e-6) && (abs(y - ry) < 1e-6)
% Interpolation is not needed, use original datatypes
N = image(ry:ry+dy,rx:rx+dx);
D = N >= C;
else
% Interpolation needed, use double type images
ty = y - fy;
tx = x - fx;
% Calculate the interpolation weights.
w1 = (1 - tx) * (1 - ty);
w2 = tx * (1 - ty);
w3 = (1 - tx) * ty ;
w4 = tx * ty ;
%Compute interpolated pixel values
N = w1*d_image(fy:fy+dy,fx:fx+dx) + w2*d_image(fy:fy+dy,cx:cx+dx) + ...
w3*d_image(cy:cy+dy,fx:fx+dx) + w4*d_image(cy:cy+dy,cx:cx+dx);
D = N >= d_C;
end
I got problems in else which is in line 12. tx and ty eqauls 0.707106781186547 or 1 - 0.707106781186547. Values from d_image are in range 0 and 255. N is value 0..255 of interpolating 4 pixels from image. d_C is value 0.255. Still dunno why matlab shows that when i have in N vlaues like: x x x 140.0000 140.0000 and in d_C: x x x 140 x. D gives me 0 on 4th position so 140.0000 != 140. I Debugged it trying more precision but it still says that its 140.00000000000000 and it is still not 140.
int Codes::Interpolation( Point_<int> point, Point_<int> center , Mat *mat)
{
int x = center.x-point.x;
int y = center.y-point.y;
Point_<double> my;
if(x<0)
{
if(y<0)
{
my.x=center.x+LEN;
my.y=center.y+LEN;
}
else
{
my.x=center.x+LEN;
my.y=center.y-LEN;
}
}
else
{
if(y<0)
{
my.x=center.x-LEN;
my.y=center.y+LEN;
}
else
{
my.x=center.x-LEN;
my.y=center.y-LEN;
}
}
int a=my.x;
int b=my.y;
double tx = my.x - a;
double ty = my.y - b;
double wage[4];
wage[0] = (1 - tx) * (1 - ty);
wage[1] = tx * (1 - ty);
wage[2] = (1 - tx) * ty ;
wage[3] = tx * ty ;
int values[4];
//wpisanie do tablicy 4 pixeli ktore wchodza do interpolacji
for(int i=0;i<4;i++)
{
int val = mat->at<uchar>(Point_<int>(a+help[i].x,a+help[i].y));
values[i]=val;
}
double moze = (wage[0]) * (values[0]) + (wage[1]) * (values[1]) + (wage[2]) * (values[2]) + (wage[3]) * (values[3]);
return moze;
}
LEN = 0.707106781186547 Values in array values are 100% same as matlab values.
Matlab uses double precision. You can use C++'s double type. That should make most things similar, but not 100%.
As someone else noted, this is probably not the source of your problem. Either there is a difference in the algorithms, or it might be something like a library function defined differently in Matlab and in C++. For example, Matlab's std() divides by (n-1) and your code may divide by n.
First, as a rule of thumb, it is never a good idea to compare floating point variables directly. Instead of, for example instead of if (nr >= 104) you should use if (nr >= 104-e), where e is a small number, like 0.00001.
However, there must be some serious undersampling or rounding error somewhere in your script, because getting 50050 instead of 50000 is not in the limit of common floating point imprecision. For example, Matlab can have a step of as small as 15 digits!
I guess there are some casting problems in your code, for example
int i;
double d;
// ...
d = i/3 * d;
will will give a very inaccurate result, because you have an integer division. d = (double)i/3 * d or d = i/3. * d would give a much more accurate result.
The above example would NOT cause any problems in Matlab, because there everything is already a floating-point number by default, so a similar problem might be behind the differences in the results of the c++ and Matlab code.
Seeing your calculations would help a lot in finding what went wrong.
EDIT:
In c and c++, if you compare a double with an integer of the same value, you have a very high chance that they will not be equal. It's the same with two doubles, but you might get lucky if you perform the exact same computations on them. Even in Matlab it's dangerous, and maybe you were just lucky that as both are doubles, both got truncated the same way.
By you recent edit it seems, that the problem is where you evaluate your array. You should never use == or != when comparing floats or doubles in c++ (or in any languages when you use floating-point variables). The proper way to do a comparison is to check whether they are within a small distance of each other.
An example: using == or != to compare two doubles is like comparing the weight of two objects by counting the number of atoms in them, and deciding that they are not equal even if there is one single atom difference between them.
MATLAB uses double precision unless you say otherwise. Any differences you see with an identical implementation in C++ will be due to floating-point errors.