Solving a system of equations programmably? [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
System of linear equations in C++?
I have the following 2 systems of equations:
For a,b,c,d:
0 = a * r1_x + b * r1_x * r1_y + c * r1_y + d
1 = a * r2_x + b * r2_x * r2_y + c * r2_y + d
0 = a * r3_x + b * r3_x * r3_y + c * r3_y + d
1 = a * r4_x + b * r4_x * r4_y + c * r4_y + d
For e,f,g,h:
0 = e * r1_x + f * r1_x * r1_y + g * r1_y + h
0 = e * r2_x + f * r2_x * r2_y + g * r2_y + h
1 = e * r3_x + f * r3_x * r3_y + g * r3_y + h
1 = e * r4_x + f * r4_x * r4_y + g * r4_y + h
I know the values of r1_x, r1_y, r2_x, r2_y, r3_x, r3_y, r4_x, r4_y,
and need to solve for a,b,c,d in the first one, and ,e,f,g, h in the second.
I know how I would solve these with pencil and paper, but I'm really unsure how to program it. How could I solve the above equations in C or C++ (or psuedocode).
Thanks

You can map it to a matrix system, A x = b, where A is the coefficient matrix, b is the solution vector, and x are the unknowns. You can either implement Gaussian elimination, or use a well known library. If you use LAPACK, the routine you want it dgesv.

Linear algebra and matricies are your friends here.
Eigen looks like a recent C++ linear algebra library. See if it can help you.
Here is what your system of equations looks like. This is the matrix:
(source: equationsheet.com)
This is the vector of unknowns:
(source: equationsheet.com)
Here is the right-hand-side vector:
(source: equationsheet.com)
You solve this system of equations by solving
Since your matrix is block diagonal, so is your solution.
You can enter your linear equation into Wolfram Alpha and get a symbolic solution.
Here is the solution for one of your systems. You can see the form that the matrix takes.

You can use Gaussian elimination, but that's probably overkill if you'll only ever have 4 equations with 4 variables.
If you can solve it on paper, then solve it on paper, find the formulas for a, b, c, d and e, f, g, h then just plug them into your program.

Related

C++ What is wrong with this version of the quadratic formula?

In my book, it asks me the following question This is for compsci-1
What is wrong with this version of the quadratic formula?
x1 = (-b - sqrt(b * b - 4 * a * c)) / 2 * a;
x2 = (-b + sqrt(b * b - 4 * a * c)) / 2 * a;
The equation your code is translating is:
which of course is not the solution for quadratic equations. You want a solution for this equation:
What's the difference? In the first one you compute the numerator, then you divide by two, then you multiply by a. That's what your code is doing. In the second one you compute the numerator, then you compute the denominator, finally you divide them.
So with additional variables:
num1 = -b - sqrt(b * b - 4 * a * c);
num2 = -b + sqrt(b * b - 4 * a * c);
den = 2 * a;
x1 = num1 / den;
x2 = num2 / den;
which can of course be written as:
x1 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
x2 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
Where you have to plug in those parenthesis in order to force the denominator to be computed before the division. As suggested in the comment by #atru.

Average value from 2d space

I'm currently working on a pice of software that interpolates data from existing measurements and makes estimates from this. The data is arranged in a 2D environment where we've got a wind speed on one axis and a wind angle on the other and each point represents a target speed.
For an example I've got three points:
p1: wind speed 6 knots, wind angle 90 degrees => target speed 5
p2: wind speed 6 knots, wind angle 70 degrees => target speed 6
p3: wind speed 8 knots, wind angle 70 degrees => target speed 7
Now I want to interpolate the point of wind speed 6 knots and wind angle 80 degrees. I would like an algorithm that uses all of these points and gives me an average of these three points.
Ages ago I made a 3D renderer and I think I used a technique there to color a polygon and I think this can be useful in this scenario. All the examples that I've found on the internet rely on OpenGL and such and that won't work for me as I want this solution to be pure c/c++ for an embedded environment. Since i run in an embedded environment I've got limited resources mainly in terms of program size.
Do any of you guys have any pointers to help me get past this problem? Thanks!
After diving into my old calculus i found a mathematical answer to this problem.
Given that I've got three points in the space I can form a plane:
P: (Px, Py, Pz)
Q: (Qx, Qy, Qz)
R: (Rx, Ry, Rz)
These points and the math described in here http://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfPlanes.aspx allowed me to move forward.
Vector(PQ) = (PQx, PQy, PQz)
Vector(PR) = (PRx, PRy, PRz)
Now I apply the cross product to these two vectors and this gives the normal vector of the plane
(Cross product math described here: http://tutorial.math.lamar.edu/Classes/CalcII/CrossProduct.aspx#Vectors_CrossProd_Ex2)
Vector(PQ) x Vector(PR) = Vector(PQy * PRz - PQz * PRy,
PQz * PRx - PQx * PRz,
PQx * PRy - PQy * PRx)
So, this is what I've got as a plane equation, without respect to that it has to pass trough one of the points:
x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) = 0
To get the full equation of my plane that passes trough all of the points, I have to apply one point, as described in example 1 in the first link.
x(PQy * PRz - PQz * PRy) + y(PQz * PRx - PQx * PRz) + z(PQx * PRy - PQy * PRx) =
Px(PQy * PRz - PQz * PRy) + Py(PQz * PRx - PQx * PRz) + Pz(PQx * PRy - PQy * PRx)
To apply my example to this formula I get the following equation:
P: (90, 6, 5)
Q: (70, 6, 6)
R: (70, 8, 7)
Vector(PQ) = (20, 0, -1)
Vector(PR) = (20, -2, -2)
Cross product of these gives me this formula:
-2x + 20y - 40z = 0
If I now apply the point P to this I can get the full equatio of my plane:
-2x + 20y - 40z = -2 * 90 + 20 * 6 - 40 * 5
-2x + 20y - 40z = -260
z = (-2x + 20y + 260) / 40
As I seek the z value where x = 6 and y = 80 I put these values into the equation.
x = 80
y = 6
z = (-2 * 80 + 20 * 6 + 260) / 40
z = 5.5
5.5 is the expected answer for this example as it exactly in the middle of P and Q.
The final implementation of this algorithm:
float TargetSpeed::PlaneInterpolation(Point3D p, Point3D q, Point3D r, int x, int y)
{
Point3D pq = Point3D(p.X - q.X, p.Y - q.Y, p.Z - q.Z);
Point3D pr = Point3D(p.X - r.X, p.Y - r.Y, p.Z - r.Z);
Point3D n = Point3D(pq.Y * pr.Z - pq.Z * pr.Y,
pq.Z * pr.X - pq.X * pr.Z,
pq.X * pr.Y - pq.Y * pr.X);
float d = n.X * p.X + n.Y * p.Y + n.Z * p.Z;
float z = (d - n.X * (float)x - n.Y * (float)y) / n.Z;
return z;
}
Is the data on a regular grid? If so, I would just use something like linear interpolation. If not, then look at something like qhull.

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=?

Point translation ortghogonally to the line

I am currently working on a project of drawing thick polylines and I am using interpolation in OpenGL. I managed to calculate all the necessary points but I need to draw two more points. I need to translate one point orthogonally to the line connecting two points. The scatch below shows what are the points. Point L is to be translated for the distance between L and nJ orthogonally to the line AB (B is the central point). Similar thing is with translation to the nK.
I have written the code:
float alpha = atan2(B.y - A.y,B.x - A.x) - deg90;
float alpha2 = atan2(C.y - B.y, C.x - B.x) - deg90;
nJ.x = L.x + w*cos(alpha); // w is distance between A1 and A2
nJ.y = L.y + w*sin(alpha);
nK.x = L.x + w*cos(alpha2);
nK.y = L.y + w*sin(alpha2);
The code works only for some points, not all. I need to fix + sing in above calculations of nJ and nK, but I do not know how. Anyone having suggestion?
First you need the left-hand-side function:
lhs(v) = [-v.y, v.x]
This turns a vector 90 degrees counter-clockwise.
Now you need the turn function:
turn(u, v, w) = sign(lhs(v - u), w - v)
If you have a polyline from u to v to w, turn(u,v,w) tells you whether it's a left turn (counter-clockwise turn) (positive), right turn (clockwise turn) (negative), or colinear (0).
There are four infinite lines in your picture that run parallel to ab and bc, with a distance of w between each pair.
The lines on the lower part are:
f(s) = (a + 0.5 * w * normalize(lhs(b - a))) + (b - a) * s
g(t) = (b + 0.5 * w * normalize(lhs(c - b))) + (c - b) * t
You want to find the intersection of the two lines; i.e., you want to solve for s and t in f(s) = g(t). This is just a system of two linear equations with two unknowns.
The solution is your point L = f(s) = g(t) in the picture.
To compute I you can use the exact same idea:
f(s) = (a - 0.5 * w * normalize(lhs(b - a))) + (b - a) * s
g(t) = (b - 0.5 * w * normalize(lhs(c - b))) + (c - b) * t
Solve for I = f(s) = g(t).
Update
Once you have L you can compute Kn and Jn as follows.
Kn = L - w * normalize(lhs(b - a))
Jn = L - w * normalize(lhs(c - b))
In computational geometry code, trigonometry is usually a code smell - it's not always wrong, but it usually is wrong. Try to stick to linear algebra.

Clojure head retention

I'm reading Clojure Programming book by O'Reilly..
I came across an example of head retention.
First example retains reference to d (I presume), so it doesn't get garbage collected:
(let [[t d] (split-with #(< % 12) (range 1e8))]
[(count d) (count t)])
;= #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>
While the second example doesn't retain it, so it goes with no problem:
(let [[t d] (split-with #(< % 12) (range 1e8))]
[(count t) (count d)])
;= [12 99999988]
What I don't get here is what exactly is retained in which case and why.
If I try to return just [(count d)], like this:
(let [[t d] (split-with #(< % 12) (range 1e8))]
[(count d)])
it seems to create the same memory problem.
Further, I recall reading that count in every case realizes/evaluates a sequence.
So, I need that clarified.
If I try to return (count t) first, how is that faster/more memory efficient than if I don't return it at all?
And what & why gets retained in which case?
In both the first and the final examples the original sequence passed to split-with is retained while being realized in full in memory; hence the OOME. The way this happens is indirect; what is retained directly is t, while the original sequence is being held onto by t, a lazy seq, in its unrealized state.
The way t causes the original sequence to be held is as follows. Prior to being realized, t is a LazySeq object storing a thunk which may be called upon at some point to realize t; this thunk needs to store a pointer to the original sequence argument to split-with before it is realized to pass it on to take-while -- see the implementation of split-with. Once t is realized, the thunk becomes eligible for GC (the field which holds it in the LazySeq object is set to null) at t no longer holds the head of the huge input seq.
The input seq itself is being realized in full by (count d), which needs to realize d, and thus the original input seq.
Moving on to why t is being retained:
In the first case, this is because (count d) gets evaluated before (count t). Since Clojure evaluates these expressions left to right, the local t needs to hang around for the second call to count, and since it happens to hold on to a huge seq (as explained above), that leads to the OOME.
The final example where only (count d) is returned should ideally not hold on to t; the reason that is not the case is somewhat subtle and best explained by referring to the second example.
The second example happens to work fine, because after (count t) is evaluated, t is no longer needed. The Clojure compiler notices this and uses a clever trick to have the local reset to nil simultaneously with the count call being made. The crucial piece of Java code does something like f(t, t=null), so that the current value of t is passed to the appropriate function, but the local is cleared before control is handed over to f, since this happens as a side effect of the expression t=null which is an argument to f; clearly here Java's left-to-right semantics are key to this working.
Back to the final example, this doesn't work, because t is not actually used anywhere and unused locals are not handled by the locals clearing process. (The clearing happens at the point of last use; in absence of such a point in the program, there is no clearing.)
As for count realizing lazy sequences: it must do that, as there is no general way of predicting the length of a lazy seq without realizing it.
Answer by #MichaƂ Marczyk, while correct, is a little difficult to comprehend. I find this post on Google Groups easier to grasp.
Here's how I understand it:
Step 1 Create lazy sequence: (range 1e8). Values are not realized yet, I marked them as asterixes (*):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
Step 2 Create two more lazy seqences which are "windows" through which you look at the original, huge lazy sequence. First window contains only 12 elements (t), the other the rest of elements (d):
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
Step 3 - out of memory scenario - you evaluate [(count d) (count t)]. So, first you count elements in d, then in t. What will happen is that you will go through all values starting at the first element of d and realize them (marked as !):
* * * * * * * * * * * * * ! * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
start here and move right ->
* * * * * * * * * * * * * ! ! * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
* * * * * * * * * * * * * ! ! ! * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
...
; this is theoretical end of counting process which will never happen
; because of OutOfMemoryError
* * * * * * * * * * * * * ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ... ! ! !
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
Problem is that all the realized values (!) are being retained, because the head of the collection (first 12 elements) are still needed - we still need to evaluate (count t). This consumes a lot of memory causing JVM to crash.
Step 3 - valid scenario - this time you evaluate [(count t) (count d)]. So we first want to count elements in smaller, head sequence:
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
start here and move right ->
! * * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
Then, we count elements in d sequence. Compiler knows that elements from t aren't needed anymore, so it can garbage collect them freeing up the memory:
! * * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
! * * * * * * * * * * * * * * * ... * * *
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
...
... !
t t t t t t t t t t t t t d d d d d d d d d d d d d d d d d ... d d d
^
Now we can see that, because elements from t weren't needed anymore, compiler was able to clear memory as it went through the large sequence.
An important addition to the final example:
(let [[t d] (split-with #(< % 12) (range 1e8))]
[(count d)])
Back to the final example, this doesn't work, because t is not actually used anywhere and unused locals are not handled by the locals clearing process.
It's not the case anymore. Since Clojure 1.9 unused destructured locals are cleared. See CLJ-1744 for more details.