I am currently trying to find the intersections points of two rotated polynomial 2nd degree (so also called parabolic).
I am able to calculate the intersection points with no rotations, but not with one.
My current code is based on Code or formula for intersection of two parabolas in any rotation
syms t1 t2
% a1 b1 c1 are coefficients of the first polynomial
% a2 b2 c2 of the second one
% First polynomial equation
fax = a1*t1.^2 + b1*t1 + c1;
fay = t1;
fax1 = fax*cos(w1) - sin(w1)*fay;
fay1 = +fax*sin(w1) + cos(w1)*fay;
% Second polynomial equation
fbx = a2*t2.^2 + b2*t2+ c2;
fby = t2;
fbx1 = fbx*cos(w2) - sin(w2)*fby;
fby1 = fbx*sin(w2) + cos(w2)*fby;
[solT1 solT2] = solve([fbx1-fax1,fby1-fay1],[t1 t2],'MaxDegree', 4);
double(solT1)
double(solT2)
But the solve function does not return equal values for x/y equations. Can somebody help me, where do I have my failure?
Output:
>> double(solT1)
ans =
-35970.3949972882 + 0i
-547.958594347212 + 0i
45277.2230289302 + 73433.2725463157i
45277.2230289302 - 73433.2725463157i
>> double(solT2)
ans =
-43312.4016357418 + 0i
-123.972586439179 + 0i
87780.3324792941 - 89532.7369678429i
87780.3324792941 + 89532.7369678429i
Related
How explicitly does Matlab solve the rightmost equation in c1, specifically ((x-1)\y)?
I am well aware what happens when you use a matrix, e.g. A\b (where A is a matrix and b is a column vector), but what happens when you use backslash on two vectors with equal rows?
The problem:
x = (1:3)';
y = ones(3,1);
c1 = ((x-1)\y) % why does this =0.6?
You're doing [0;1;2]\[1;1;1]. Essentially x=0.6 is the least-squares solution to
[0;1;2]*x=[1;1;1]
The case you have from the documentation is the following:
If A is a rectangular m-by-n matrix with m ~= n, and B is a matrix with m rows, then A\B returns a least-squares solution to the system of equations A*x= B.
(Specifically, you have m=3, n=1).
A = (1:3).' - 1; % = [0;1;2]
B = ones(3,1); % = [1;1;1]
x = A\B; % = 0.6
Algebraically, it's easy to see this is the solution to the least-squares minimisation
% Calculate least squares
leastSquares = sum( ((A*x) - B).^2 )
= sum( ([0;1;2]*x - [1;1;1]).^2 )
= sum( [-1; x-1; 2x-1].^2 )
= 1 + (x-1)^2 + (2x-1)^2
= 1 + x^2 - 2*x + 1 + 4*x^2 - 4*x + 1
= 5*x^2 - 6*x + 3
% Minimum least squares -> derivative = 0
d(leastSquares)/dx = 10*x - 6 = 0
10*x = 6
x = 0.6
I have no doubt that MATLAB uses a more sophisticated algorithm to come to the same conclusion, but this lays out the mathematics in a fairly plain way.
You can see experimentally that there is no better solution by testing the following for various values of x... 0.6 gives the smallest error:
sum( ([0;1;2]*x - [1;1;1]).^2 )
I am required to solve these particular ODEs using numerical methods in MATLAB. The ODEs essentially model the fall of a body of mass m, connected to a piece of elastic with spring constant k. The solutions to these ODEs are to represent the body's position and velocity at discrete positions in time.
The parameters for the ODEs are,
H = 74
D = 31
c = 0.9
m = 80
L = 25
k = 90
g = 9.8
C = c/m
K = k/m
T = 60
n = 10000
I've implemented the following two methods; Euler and Fourth Order Runge -
Kutta to approximate the solutions over the interval [0, 60].
Here is my Runge Kutta function,
function [t, y, v, h] = rk4_approx(T, n, g, C, K, L)
%% calculates interval width h for each iteration
h = (T / n);
%% creates time array t
t = 0:h:T;
%% initialises arrays y and v to hold solutions
y = zeros(1,n+1);
v = zeros(1,n+1);
%% functions
z = #(v) v;
q = #(v, y) (g - C*abs(v)*v - max(0, K*(y - L)));
%% initial values
v(1) = 0;
y(1) = 0;
%% performs iterations
for j = 1:n
%% jumper's position at each time-step
r1 = h*z(v(j));
r2 = h*z(v(j) + 0.5*h);
r3 = h*z(v(j) + 0.5*h);
r4 = h*z(v(j) + h);
y(j+1) = y(j) + (1/6)*(r1 + 2*r2 + 2*r3 + r4); %position solution
%% jumper's velocity at each time-step
k1 = h*q(v(j), y(j));
k2 = h*q(v(j) + 0.5*h, y(j) + 0.5*k1);
k3 = h*q(v(j) + 0.5*h, y(j) + 0.5*k2);
k4 = h*q(v(j) + h, y(j) + k3);
v(j+1) = v(j) + (1/6)*(k1 + 2*k2 + 2*k3 + k4); %velocity solution
end
end
Here is my Euler function,
function [t, y, v, h] = euler_approx(T, n, g, C, K, L)
% calculates interval width h
h = T / n;
% creates time array t
t = 0:h:T;
% initialise solution arrays y and v
y = zeros(1,n+1);
v = zeros(1,n+1);
% perform iterations
for j = 1:n
y(j+1) = y(j) + h*v(j);
v(j+1) = v(j) + h*(g - C*abs(v(j))*v(j) - max(0, K*(y(j) - L)));
end
end
However, after varying the parameter 'n' (where n is the number of 'steps' in the iteration) it appears the Euler solution for the position of the body converges to the maximum value of approximately y = 50 faster then the Runge - Kutta solution does. Since this ODE does not have a closed solution I have nothing to compare my answer to. I suspect the answer to be y = 50 though.
Therefore, I'm doubting my answer.
Is my code for the Runge - Kutta solution incorrect? Should it not converge faster than the Euler solution?
Sorry for my poor formatting.
The Runge-Kutta integration is incorrect.
It is vital to appreciate the difference between independent and dependent (also called state and a host of other names) variables. Time is the independent variable in this problem. Given a time, you can provide a height and a velocity; the reverse is not uniquely true. When you read a Runge-Kutta formula, such as the one provided by Wikipedia, t is the independent variable and y is vector of dependent variables. Also, when performing time integration of systems of equations (here we have a system of two equations), it is very important to keep track of which right-hand side belongs to which equation if you are going to perform the march element-wise, which I will do for simplicity.
All that said, the problem with the current RK integrator is two-fold
v is being stepped as if it were t; this is incorrect. Both v and y are stepped similarly.
y should be stepped with the r variables since the r variables come from y's right-hand side equation z. Similarly, v is stepped with the k variables.
The updated core of the integrator is thus:
r1 = h*z(v(j));
k1 = h*q(v(j), y(j));
r2 = h*z(v(j) + 0.5*k1);
k2 = h*q(v(j) + 0.5*k1, y(j) + 0.5*r1);
r3 = h*z(v(j) + 0.5*k2);
k3 = h*q(v(j) + 0.5*k2, y(j) + 0.5*r2);
r4 = h*z(v(j) + k3);
k4 = h*q(v(j) + k3, y(j) + r3);
y(j+1) = y(j) + (1/6)*(r1 + 2*r2 + 2*r3 + r4); %position solution
v(j+1) = v(j) + (1/6)*(k1 + 2*k2 + 2*k3 + k4); %velocity solution
Notice how both v and y are updated in a similar fashion and, therefore, are required to be updated in lock-step with one another. This form of the integrator will give far better performance than Euler.
Finally, if in doubt in the future about a solution you don't know, always remember you have the MATLAB ODE suite at your disposal, and a quick call to the extensively vetted and very robust ode45 can relieve a lot of concerns. I actually used this call
[t45,w45] = ode45(#(t,w) [z(w(2));q(w(2),w(1))],linspace(0,T,200).',[0;0]);
to check my work.
I have a mathematical function E which I want to minimize. I get from solving this 16 possible solutions x1, x2, ..., x16, only two of which that actually minimize the function (located at a minimum). Using a for loop, I can then plug all of these 16 solutions into the original function, and select the solutions I need by applying some criteria via if statements (plotting E vs E(x) if x is real and positive, if first derivative of E is below a threshold, and if the second derivative of E is positive).
That way I only plot the solutions I'm interested in. However, I would now like to extract the relevant x that I plot. Here's a sample MATLAB code that plots the way I just described. I want to extract the thetas that I actually end up plotting. How to do that?
format long
theta_s = 0.77944100;
sigma = 0.50659500;
Delta = 0.52687700;
%% Defining the coefficients of the 4th degree polynomial
alpha = cos(2*theta_s);
beta = sin(2*theta_s);
gamma = 2*Delta^2/sigma^2;
a = -gamma^2 - beta^2*Delta^2 - alpha^2*Delta^2 + 2*alpha*Delta*gamma;
b = 2*alpha*gamma - 2*Delta*gamma - 2*alpha^2*Delta + 2*alpha*Delta^2 -...
2*beta^2*Delta;
c = 2*gamma^2 - 2*alpha*Delta*gamma - 2*gamma - alpha^2 + 4*alpha*Delta +...
beta^2*Delta^2 - beta^2 - Delta^2;
d = -2*alpha*gamma + 2*Delta*gamma + 2*alpha + 2*beta^2*Delta - 2*Delta;
e = beta^2 - gamma^2 + 2*gamma - 1;
%% Solve the polynomial numerically.
P = [a b c d e];
R = roots(P);
%% Solve r = cos(2x) for x: x = n*pi +- 1/2 * acos(r). Using n = 0 and 1.
theta = [1/2.*acos(R) -1/2.*acos(R) pi+1/2.*acos(R) pi-1/2.*acos(R)];
figure;
hold on;
x = 0:1/1000:2*pi;
y_1 = sigma*cos(x - theta_s) + sqrt(1 + Delta*cos(2*x));
y_2 = sigma*cos(x - theta_s) - sqrt(1 + Delta*cos(2*x));
plot(x,y_1,'black');
plot(x,y_2,'black');
grid on;
%% Plot theta if real, if positive, if 1st derivative is ~zero, and if 2nd derivative is positive
for j=1:numel(theta);
A = isreal(theta(j));
x_j = theta(j);
y_j = sigma*cos(x_j - theta_s) + sqrt(1 + Delta*cos(2*x_j));
FirstDer = sigma* sin(theta(j) - theta_s) + Delta*sin(2*theta(j))/...
sqrt(1 + Delta*cos(2*theta(j)));
SecDer = -sigma*cos(theta(j)-theta_s) - 2*Delta*cos(2*theta(j))/...
(1 + Delta*cos(2*theta(j)))^(1/2) - Delta^2 * (sin(2*theta(j)))^2/...
(1 + Delta*cos(2*theta(j)))^(3/2);
if A == 1 && x_j>=0 && FirstDer < 1E-7 && SecDer > 0
plot(x_j,y_j,['o','blue'])
end
end
After you finish all plotting, get the axes handle:
ax = gca;
then write:
X = get(ax.Children,{'XData'});
And X will be cell array of all the x-axis values from all lines in the graph. One cell for each line.
For the code above:
X =
[1.961054062875753]
[4.514533853417446]
[1x6284 double]
[1x6284 double]
(First, the code all worked. Thanks for the effort there.)
There are options here. A are couple below
Record the values as you generate them
Within the "success" if statement, simply record the values. See edits to your code below.
This would always be the preferred option for me, it just seems much more efficient.
xyResults = zeros(0,2); %%% INITIALIZE HERE
for j=1:numel(theta);
A = isreal(theta(j));
x_j = theta(j);
y_j = sigma*cos(x_j - theta_s) + sqrt(1 + Delta*cos(2*x_j));
FirstDer = sigma* sin(theta(j) - theta_s) + Delta*sin(2*theta(j))/...
sqrt(1 + Delta*cos(2*theta(j)));
SecDer = -sigma*cos(theta(j)-theta_s) - 2*Delta*cos(2*theta(j))/...
(1 + Delta*cos(2*theta(j)))^(1/2) - Delta^2 * (sin(2*theta(j)))^2/...
(1 + Delta*cos(2*theta(j)))^(3/2);
if A == 1 && x_j>=0 && FirstDer < 1E-7 && SecDer > 0
xyResults(end+1,:) = [x_j y_j]; %%%% RECORD HERE
plot(x_j,y_j,['o','blue'])
end
end
Get the result from the graphics objects
You can get the data you want from the actual graphics objects. This would be the option if there was just no way to capture the data as it was generated.
%First find the objects witht the data you want
% (Ideally you could record handles to the lines as you generated
% them above. But then you could also simply record the answer, so
% let's assume that direct record is not possible.)
% (BTW, 'findobj' is an underused, powerful function.)
h = findobj(0,'Marker','o','Color','b','type','line')
%Then get the `xdata` filed from each
capturedXdata = get(h,'XData');
capturedXdata =
2×1 cell array
[1.96105406287575]
[4.51453385341745]
%Then get the `ydata` filed from each
capturedYdata = get(h,'YData');
capturedYdata =
2×1 cell array
[1.96105406287575]
[4.51453385341745]
Need to solve the system of nonlinear differential equations:
x1p = a1*u2*x1^1.3 + a2*u1 + a3*u3
x2p = (a4*u2 + a5)*x1^1.3 + a6*x2
x3p = (a7*u3 + (a8*u2-a9)*x1)/a10
x1p, x2p & x3p are time derivatives of x1, x2 & x3, i.e. dx1/dt, dx2/dt & dx3/dt.
we have descrete data of x1, x2 & x3 as well as of u1, u2 & u3. We need to solve the problem in order to get the unknown coefficients, a1, a2, …, a10.
Have checked many posts and can say the solution involves ODE45 (or other ODEX) and probably fsolve or fminsearch (Matlab), but have not managed to setup up the problem correctly, guess we don't understand the coding well. Please, suggestions.
you should replace x1p, x2p ,and x3p by using definition of derivative:
x1p = (x1(i+1) - x(i))/ dt , and like this for the others.
then use folowing algorithm (it is not complete):
descrete data of x1, x2 & x3 as well as of u1, u2 & u3
dt = 0.01
myFun = #(a,x1,x2,x3,u1,u2,u3)
[ (x1(i+1) - x1(i))/ dt = a(1)*u2(i)*x1(i)^1.3 + a(2)*u1(i) + a(3)*u3(i);
(x2(i+1) - x2(i))/ dt = (a(4)*u2(i) + a(5)*x1(i)^1.3 + a(6)*x2(i);
(x3(i+1) - x3(i))/ dt = (a(7)*u3(i) + (a(8)*u2(i)-a(9))*x1(i))/a(10) ]
A=[];
a0 = [0; 0; 0 ;0 ;.... ]
for i= 1:1: lenngth(x1)
a=fsolve(#(a)myFun(a,x1,x2,x3,u1,u2,u3),a0,options);
a0 = [ a(1,1) ; a(2,1); a(3,1) ; .......]
A = cat(1,A,a) ;
end
a1 = mean(A(1,:))
a2 = mean(A(2,:))
.
.
a10 = mean(A(10,:))
I want to write a program which will calculate the statistic in Bertrand paradox.
In my way, I want select two dot in circle , and pass line using them (two dots), it is my chord. Then I want to calculate how many of these chords are longer than sqrt(3); but when I run this script some of the chords are bigger than 2 ! ( radius of my circle is 1 )
I don't know what is wrong with it, can anybody help me?
See this link please for the formula used.
r1 = rand(1,1000000);
teta1 = 2*pi * rand(1,1000000);
x1 = r1 .* (cos(teta1));
y1 = r1 .* (sin(teta1));
r2 = rand(1,1000000);
teta2 = 2*pi * rand(1,1000000);
x2 = r2 .* (cos(teta2));
y2 = r2 .* (sin(teta2));
%solve this equation : solve('(t*x2 +(1-t)*x1)^2 +(t*y2 +(1-t)*y1)^2 =1', 't');
t1= ((- x1.^2.*y2.^2 + x1.^2 + 2*x1.*x2.*y1.*y2 - 2*x1.*x2 - x2.^2.*y1.^2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2).^(1/2) - x1.*x2 - y1.*y2 + x1.^2 + y1.^2)/(x1.^2 - 2*x1.*x2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2);
t2= -((- x1.^2.*y2.^2 + x1.^2 + 2*x1.*x2.*y1.*y2 - 2*x1.*x2 - x2.^2.*y1.^2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2).^(1/2) + x1.*x2 + y1.*y2 - x1.^2 - y1.^2)/(x1.^2 - 2*x1.*x2 + x2.^2 + y1.^2 - 2*y1.*y2 + y2.^2);
length = abs (t1-t2) * sqrt (( x2-x1).^2 + (y2-y1).^2);
hist(length)
flag = 0;
for check = length
if( check > sqrt(3) )
flag = flag + 1;
end
end
prob = (flag/1000000)^2;
Your formula for length is probably to blame for the nonsensical results, and given its length, it is easier to replace it than to debug. Here is another way to find the length of chord passing through two points (x1,y1) and (x2,y2):
Find the distance of the chord from the center
Use the Pythagorean theorem to find its length
In Matlab code, this is done by
distance = abs(x1.*y2-x2.*y1)./sqrt((x2-x1).^2+(y2-y1).^2);
length = 2*sqrt(1-distance.^2);
The formula for distance involves abs(x1.*y2-x2.*y1), which is twice the area of the triangle with vertices (0,0), (x1,y1), and (x2,y2). Dividing this quantity by the base of triangle, sqrt((x2-x1).^2+(y2-y1).^2), yields its height.
Also, putting 1000000 samples into mere 10 bins is a waste of information: you get a crude histogram for all that effort. Better to use hist(length,100).
Finally, your method of selecting two points through which to pass a line does not take them from the uniform distribution on the disk. If you want uniform distribution over the disk, use
r1 = sqrt(rand(1,1000000));
r2 = sqrt(rand(1,1000000));
because for a uniformly distributed point, the square of the distance to the center is uniformly distributed in [0,1].
Finally, I've no idea why you square in prob = (flag/1000000)^2.
Here is your code with aforementioned modifications.
r1 = sqrt(rand(1,1000000));
teta1 = 2*pi * rand(1,1000000);
x1 = r1 .* (cos(teta1));
y1 = r1 .* (sin(teta1));
r2 = sqrt(rand(1,1000000));
teta2 = 2*pi * rand(1,1000000);
x2 = r2 .* (cos(teta2));
y2 = r2 .* (sin(teta2));
distance = abs(x1.*y2-x2.*y1)./sqrt((x2-x1).^2+(y2-y1).^2);
length = 2*sqrt(1-distance.^2);
hist(length,100)
flag = 0;
for check = length
if( check > sqrt(3) )
flag = flag + 1;
end
end
prob = flag/1000000;