I want to solve these equations using MATLAB and I am sure there is a non zero solution. The equations are:
0.7071*x + 0.7071*z = x
-0.5*x + 0.7071*y + 0.5*z = y
-0.5*x - 0.7071*y + 0.5*z = z
I wrote in MATLAB:
[x,y,z]=solve('0.7071 * x+0.7071 * z=x','-0.5 * x+0.7071 * y+0.5 * z=y','-0.5 * x-0.7071 * y+0.5 * z=z');
But the result is x = y = z = 0.
As I said I am sure that there is a solution. Can any one help?
You're looking for a non-trivial solution v to A*v=v with v=[x;y;z] and...
A =
0.70710678118655 0 0.70710678118655
-0.50000000000000 0.70710678118655 0.50000000000000
-0.50000000000000 -0.70710678118655 0.50000000000000
You can transform this into (A-I)v=0 where I is the 3x3 identity matrix. What you have to do to find a nontrivial solution is checking the null space of A-I:
>> null(A-eye(3))
ans =
0.67859834454585
-0.67859834454585
0.28108463771482
So, you have a onedimensional nullspace. Otherwise you'd see more than one column. Every linear combination of the columns is a point in this null space that A-I maps to the null vector. So, every multiple of this vector is a solution to your problem.
Actually, your matrix A is a rotation matrix of the first kind because det(A)=1 and A'*A=identity. So it has an eigenvalue of 1 with the rotation axis as corresponding eigenvector. The vector I computed above is the normalized rotation axis.
Note: For this I replaced your 0.7071 with sqrt(0.5). If rounding errors are a concern but you know in advance that there has to be a nontrivial solution the best bet is to do a singular value decomposition of A-I and pick the right most right singular vector:
>> [u,s,v] = svd(A-eye(3));
>> v(:,end)
ans =
0.67859834454585
-0.67859834454585
0.28108463771482
This way you can calculate a vector v that minimizes |A*v-v| under the constraint that |v|=1 where |.| is the Euclidean norm.
I don't think you need to use the solve function as your equations is a system of linear equations.
Recast as a matrix equation:
Ax = B
In your case:
| -0.2929 0.0 0.7071 | | x | | 0 |
| -0.5 -0.2929 0.5 | | y | = | 0 |
| -0.5 -0.7071 -0.5 | | z | | 0 |
Use the built-in functionally of MATLAB to solve it. See e.g. MATLAB: Solution of Linear Systems of Equations.
The core of MATLAB is to solve this kind of equation.
Using FreeMat (an open-source MATLAB-like environment with
a GPL license; direct download URL for Windows installer):
A = [ -0.2929 0.0 0.7071; -0.5 -0.2929 0.5; -0.5 -0.7071 -0.5 ]
B = [0.0; 0.0; 0.0]
A\B
ans =
0
0
0
So the solution is: x = 0, y = 0, z = 0
The solution can also be derived by hand. Starting from the last two equations:
-0.5*x + 0.7071*y + 0.5*z = y
-0.5*x - 0.7071*y + 0.5*z = z
0.2929*y = -0.5*x + 0.5*z
0.7071*y = -0.5*x + 0.5*z
0.2929*y = 0.7071*y
Thus y = 0.0 and:
0.7071*y = -0.5*x + 0.5*z
0 = -0.5*x + 0.5*z
0 = -0.5*x + 0.5*z
0.5*x = 0.5*z
x = z
Inserting in the first equation:
0.7071*x + 0.7071*z = x
0.7071*x + 0.7071*x = x
1.4142*x = x
Thus x = 0.0. And as x = z, then z = 0.0.
x = 0, y = 0, z = 0 is the correct solution. This problem can be easily worked by hand.
A = [ 0.7071 0 0.7071 ;
-0.5 0.7071 0.5 ;
-0.5 -0.7071 0.5 ];
B = [1 ; 1 ; 1];
AA = A-diag(B)
-0.2929 0 0.7071
-0.5 -0.2929 0.5
-0.5 -0.7071 -0.5
BB = B-B
0
0
0
AA\BB
0
0
0
Friends use MATLAB command rref(A) for Ax=B.... It will give a upper triangular Matrix. Then u can calculate non-trivial solutions easily... But keep in mind that if rref(A)=I (as in your case) then non-trivial solutions do not exist.
BEST OF LUCK
Related
My mathematics (and matlab) is just not up to this and so I humbly ask for your help:
I have a model of flow through a annulus. I want to get the radius of the peak flow point and the radius of the annulus to the centreline.
So, I have 3 points, ABC, in a 3D model whose co-ordinates we know but not aligned to xyz. I want AB to be two points on a plane and point A to be the origin (centre of the annulus). Point C is on a plane parallel to the previous plane (the peak flow point). I would like to know how to calculate the distance between C on its plane to the normal vector of the AB plane that goes through the point A.
Here are pics of the model:
Flow through an annulus
Points in the model
Now I've had a friend who's cleverer than I come up with a matlab code to translate and rotate the model and then calculate the magnitudes of AB and AnormC. However, it's not working as it puts C at a greater radius than B. I also realise there is more than one way to solve this problem.
The code is below. Any thoughts where we've gone wrong? Or maybe is there a better way to do this? I thought of vectors but my scribblings amount to nought.
Thank you.
Toby
%Origin
O = [0 0 0]'; Ox = [O' 1]';
%Vector co-ordinates of 1 (A - Origin centreline), ...
% 2 (B - Radius of artery), and 3 (C - Radius of Peak Velocity)
A = [13.3856 -60.0377 15.8443]'; Ax = [A' 1]';
B = [26.9486 -51.0653 20.9265]'; Bx = [B' 1]';
C = [16.2240 -92.5594 40.8687]'; Cx = [C' 1]';
%Find the new i unit vector in the old co-ords (the unit vector along the new x axis)
AB = B - A;
magAB = sqrt(sum(AB.^2));
new_i=AB./magAB;
%Calculate the angle to rotate through Z when transforming
thetaZ = atan(new_i(2)/new_i(1));
%Hence, define the translation matrix (to move the origin to A) and ...
% the rotation matrixes (to align the new x axis with AB and new_i)
T = [1 0 0 -A(1) ; 0 1 0 -A(2) ; 0 0 1 -A(3) ; 0 0 0 1];
Rz = [cos(thetaZ) sin(thetaZ) 0 0 ; -sin(thetaZ) cos(thetaZ) 0 0 ; 0 0 1 0 ; 0 0 0 1];
Transform = Rz * T;
%transform Cx to the new co-ordinates by translation and rotation in Z
A_dash = round(Transform * Ax,10);
B_dash = round(Transform * Bx,10);
C_dash = round(Transform * Cx,10);
new_i_t = round(Transform * [new_i' 1]',4); new_i_t = new_i_t(1:3);
new_O = round(Transform * Ox,4); new_O = new_O(1:3);
A_dash = A_dash(1:3); B_dash = B_dash(1:3); C_dash = C_dash(1:3);
%Perform a final rotation in Y
thetaY = atan(B_dash(3)/B_dash(1));
Ry = [cos(thetaY) 0 sin(thetaY) ; 0 1 0 ; -sin(thetaY) 0 cos(thetaY)];
B_dash = Ry * B_dash;
C_dash = Ry * C_dash;
%Taking point C onto the plane of AB
C_dashflat = C_dash.*[1 1 0]';
%Find Radius of Peak Flow
Radius_Peak_Flow = sqrt(sum(C_dashflat.^2));
%Find Radius of Artery
Radius_Artery = magAB;
%Ratio (between 0 -1)
Ratio = Radius_Peak_Flow/Radius_Artery
I am novice to deep learning so I begin with the simplest test case: XOR learning.
In the new edition of Digital Image Processing by G & W the authors give an example of XOR learning by a deep net with 3 layers: input, hidden and output (each layer has 2 neurons.), and a sigmoid as the network activation function.
For network initailization they say: "We used alpha = 1.0, an inital set of Gaussian random weights of zero mean and standard deviation of 0.02" (alpha is the gradient descent learning rate).
Training was made with 4 labeled examples:
X = [1 -1 -1 1;1 -1 1 -1];%MATLAB syntax
R = [1 1 0 0;0 0 1 1];%Labels
I have written the following MATLAB code to implement the network learing process:
function output = neuralNet4e(input,specs)
NumPat = size(input.X,2);%Number of patterns
NumLayers = length(specs.W);
for kEpoch = 1:specs.NumEpochs
% forward pass
A = cell(NumLayers,1);%Output of each neuron in each layer
derZ = cell(NumLayers,1);%Activation function derivative on each neuron dot product
A{1} = input.X;
for kLayer = 2:NumLayers
B = repmat(specs.b{kLayer},1,NumPat);
Z = specs.W{kLayer} * A{kLayer - 1} + B;
derZ{kLayer} = specs.activationFuncDerive(Z);
A{kLayer} = specs.activationFunc(Z);
end
% backprop
D = cell(NumLayers,1);
D{NumLayers} = (A{NumLayers} - input.R).* derZ{NumLayers};
for kLayer = (NumLayers-1):-1:2
D{kLayer} = (specs.W{kLayer + 1}' * D{kLayer + 1}).*derZ{kLayer};
end
%Update weights and biases
for kLayer = 2:NumLayers
specs.W{kLayer} = specs.W{kLayer} - specs.alpha * D{kLayer} * A{kLayer - 1}' ;
specs.b{kLayer} = specs.b{kLayer} - specs.alpha * sum(D{kLayer},2);
end
end
output.A = A;
end
Now, when I am using their setup (i.e., weights initalizaion with std = 0.02)
clearvars
s = 0.02;
input.X = [1 -1 -1 1;1 -1 1 -1];
input.R = [1 1 0 0;0 0 1 1];
specs.W = {[];s * randn(2,2);s * randn(2,2)};
specs.b = {[];s * randn(2,1);s * randn(2,1)};
specs.activationFunc = #(x) 1./(1 + exp(-x));
specs.activationFuncDerive = #(x) exp(-x)./(1 + exp(-x)).^2;
specs.NumEpochs = 1e4;
specs.alpha = 1;
output = neuralNet4e(input,specs);
I'm getting (after 10000 epoches) that the final output of the net is
output.A{3} = [0.5 0.5 0.5 0.5;0.5 0.5 0.5 0.5]
but when I changed s = 0.02; to s = 1; I got output.A{3} = [0.989 0.987 0.010 0.010;0.010 0.012 0.0.98 0.98] as it should.
Is it possible to get these results with `s=0.02;' and I am doing something wrong in my code? or is standard deviation of 0.02 is just a typo?
Based on your code, I don't see any errors. In my knowledge, the result that you got,
[0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5]
That is a typical result of overfitting. There are many reasons for this to happen, such as too many epochs, too large learning rate, too small sample data, and others.
On your example, s=0.02 limits the values of randomized weights and biases. Changing that to s=1 makes the randomized values unchanged/unscaled.
To make the s=0.02 one work, you can try minimizing the number of epochs or maybe lowering the alpha.
Hope this helps.
I want to find the rotation matrix between two vectors.
[0;0;1] = R * [0.0023;0.0019;0.9899]
How do I find the 3*3 rotation matrix?
This is a simple rearrangement
% [0;0;1] = R * [0.0023;0.0019;0.9899];
% So ...
% [0;0;1] / [0.0023;0.0019;0.9899] = R
% This is a valid MATLAB command
R = [0;0;1] / [0.0023;0.0019;0.9899];
>> R =
[ 0 0 0
0 0 0
0 0 1.0102 ]
We can validate this result
R * [0.0023;0.0019;0.9899]
>> ans =
[0; 0; 1]
Your problem can be defined as a linear equation, say,
y = mx
where, y and x are matrices. Find m.
Solution:
m = x\y or m = mldivide(x,y)
Notice the backslash. It is not a forward slash / as Wolfie mentioned in his answer. For details see https://www.mathworks.com/help/matlab/ref/mldivide.html
Additional Details:
If x is a singular matrix, use pinv. See https://www.mathworks.com/help/matlab/ref/pinv.html for reference.
I know this problem comes up a lot on here and I've read through many threads but am still stuck on my specific problem. I'm using a mass matrix with ode function to solve 4 equations simultaneously, 2 algebraic and 2 differential:
function ade
% Equation set
% y(1)== radius 1, y(2)== concentration Cc
% y(3)== radius 2 y(4)== concentration Cc2
%==========================================================================
clc
close all
M = [1 0 0 0
0 0 0 0
0 0 1 0
0 0 0 0];
options = odeset('Mass',M);
y0= [1,1,1,1];
tspan = [0:1:1440];
[t,y]= ode15s(#equations,tspan,y0,options);
function mainequations = equations (t, y)
m = 18;
m2 = 599;
ro = 1000;
ro2 = 1050;
k = 0.085;
k2 = 0.085;
theta = 46/8;
theta2 = 46/8;
De = 7.65*10^-14;
Cb = 0.993;
R = 8.29*10^-7;
alpha = (m*k)/ro;
alpha1 = (m2*k2)/ro2;
beta = (theta*k*y(2))/De;
beta2 = (theta2*k2*y(4))/De;
mainequations = [-alpha*y(2)
y(4) - y(2)-(beta * y(1)^2 *(1/y(1) - y(3)))
-alpha1*y(4)
Cb - y(4) -(beta * y(1)^2 + beta2*(y(3))^2)*(1/y(3) - 1/R)];
I'm pretty sure the problem is in the equations at the bottom, I'm guessing one is the wrong size, but when debugging all the y values are the same size i.e. 4x1. Can anyone help?
Thanks
I have a sequence S :
S= 'ABCD' % which means A<B<C<D
I want to convert S into a matrix M[i,j] which have to satisfy those conditions :
M[i,j] , M[j,i] are random
M[i,i] =0.5
M[i,j] + M[j,i] = 1
M[i,j] < M[j,i] % For example: if A<B then M[A,B] < M[B,A]
For example: if we have S = 'ABCD', the M matrix will be expected as follows:
A B C D
A o.5 0.25 0.2 0.1
B 0.75 0.5 0.35 0.15
C 0.8 0.65 0.5 0.4
D 0.9 0.85 0.6 0.5
How to create that kind of above matrix from a given sequence ?
From your question it appears you want
to fill the lower part of the matrix with random entries uniformly distributed on the interval (0,0.5) (so that condition 4 in your question be satisfied);
the upper part is then computed according to condition 3; and
the diagonal is determined by condition 2.
You can do that as follows:
n = 4; %// size
M = NaN(n); %// preallocate
M(1:n+1:end) = 0.5; %// fill diagonal
ind_lower = tril(true(n), -1); %// logical index for lower part
M(ind_lower) = 0.5*rand(n*(n-1)/2, 1); %// fill lower part
M_aux = NaN(n); %// auxiliary variable to fill upper part
M_aux(ind_lower) = 1-M(ind_lower).';
M_aux = M_aux.';
M(ind_lower.') = M_aux(ind_lower.'); %// fill upper part
Example result:
M =
0.5000 0.5214 0.7573 0.5999
0.4786 0.5000 0.9291 0.7891
0.2427 0.0709 0.5000 0.5421
0.4001 0.2109 0.4579 0.5000
Here's another similar approach:
n = 4;
M = tril(rand(n)*0.5, -1);
P = triu(1-M.', 1);
M = M + P + eye(n)*0.5;
Result:
M =
0.500000 0.987433 0.711005 0.944642
0.012567 0.500000 0.782633 0.902365
0.288995 0.217367 0.500000 0.783708
0.055358 0.097635 0.216292 0.500000