Matrix multiplication and differences - matlab

I need to compute this equation with MATLAB:
where Sn can be both matrices or scalar and I tried to do it with
S_A = S_3*S_5*((ones-(S_1*S_5)).^(-1))*S_2+S_4
The problem is it doesn't give me the right result and the problem it seems to be with the difference but I cannot figure why is giving me wrong results.
The result is supposed to be this one
but the MATLAB result is
I don't understand why the two results are not the same.
The only way that I figured is through this
diff = ones-(S_1*S_5);
if S_1*S_5 == zeros %Perchè senza non funziona?
diff = ones;
else
diff = (ones-(S_1*S_5)).^(-1)
end
S_A = S_3*S_5*diff*S_2+S_4;
But I don't think it's a smart solution. Anyone knows why I'm not getting the correct results?

"I tried to do it with S_A = S_3*S_5*((ones-(S_1*S_5)).^(-1))*S_2+S_4"
The problem here is that A^(-1) in mathematical notation means "take the inverse", whereas you used A. ^(-1), note the dot, which in MATLAB's notation means "take the each matrix element to the power -1". Taking the inverse of a matrix is not smart in MATLAB anyway, be it via inv() or ^(-1), instead, use mldivide:
S_A = S_3*S_5*(eye(size(S_1*S_5,1))-(S_1*S_5))\S_2+S_4
Also, as mentioned in Brice's answer use eye, not ones to create an identity matrix, and feed it a size argument as opposed to nothing. All in all it looks to me like you do not have a firm grasp of basic MATLAB functionality, so I'd like to point you to The MathWorks own tutorial on MATLAB.

ones outputs a matrix filled with ones, not the identitiy matrix which is given by function eye.
You also need to specify the size of ones or eye, otherwise it will simply output a scalar 1 (i.e. a 1-by-1 matrix filled with ones, or the 1-by-1 identity matrix).
Try (assuming all matrices have the same size):
siz=length(S_1);
S_A = S_3*S_5*((eye(siz)-(S_1*S_5))^(-1))*S_2+S_4

Related

Create diagonal matrix without using MATLAB built-in functions

I know the answer to this question as shown below.
function a = reverse_diag(n)
b = zeros(n);
b(1:n+1:end) = 1;
a(1:n, n:-1:1) = b(1:n, 1:n);
end
But why does it look like that? What does this mean?
b(1:n+1:end) = 1;
I seem to recall seeing something similar to this in MATLAB answers very recently, hence I will be brief.
MATLAB arrays can be indexed in 2 relevant ways:
Like A(x,y) using the actual coordinates in the matrix.
Like A(index), no matter how many dimensions the matrix A actually has. This is called linear indexing and will go through the matrix column by column. So for a 10x10 matrix, A(11) is actually A(2,1).
Read up on ind2sub and sub2ind to get a sense of how these work. You should now be able to figure out why that line works.

Finding intersection between two functions using Matlab or Scilab

I'm doing this:
>> plot(x,y1,x,y2);
>> x=0:0.001:5;
>> y1=sin(x)+cos(1+x.^2)-1;
>> y2 = ((1/2).*x)-1;
>> find (y1==y2)
And getting this:
ans =
Empty matrix: 1-by-0
As an answer and it is simply driving me crazy! I do not know why Matlab and Scilab does not give me the answer of the intersects. I have been trying to make the intervals smaller like x = 0:0.0001:5; but it did not change anything. How can I make it return to me the intersection values?
Thank you.
You have to remember that Matlab is used to find numerical solutions to problems. You are providing a discrete set of input points x=0:0.001:5; and asking it to calculate the discrete output points y1[x] and y2[x]. This means that y1 and y2 are not continuous and don't necessarily intersect as their continuous counterparts do. I don't have Matlab so I did not run your code, but your discrete functions most likely do not interset. That is to say, there is no pair of points a = y1[x_i] and b = y2[x_i] where a = b. Instead what you most likely want to do is look for points where y2-y1 is on one side of zero at a particular input, and on the other side of zero for the next input. This would mean that the function's continuous conterparts would have crossed somewhere in between.
The case where the functions meet but don't cross is a little more tricky but the same kind of idea.
EDIT:
This sort of thing is easiest to wrap your head around with image so I created one illustrate what I mean.
Here I used many fewer points than you are trying to use, but the idea is the same. You can see that the continuous versions of y1 and y2 cross in several places, but what you're asking matlab to do is find a point in y1 that is equal to a point in y2 for identical values of x. In this image you can see that many are close, but your computer stores floating point numbers to a very high precision and so the chances of them actually being equal is very small.
When you increase the number of sample points, the image starts to look more like its' continuous counterpart.
The two existing answers explain why you can't find an exact intersection so easily. But what you really need is an answer to what to do instead to obtain precise intersections?
In your specific case, you know the analytical functions which you want to figure out the intersection of. You can use fzero with an (optionally anonymous) function to find the zero of the function defined by the difference of your two original functions:
y1fun = #(x) sin(x)+cos(1+x.^2)-1;
y2fun = #(x) ((1/2).*x)-1;
diff_fun = #(x) y1fun(x)-y2fun(x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(diff_fun,x0);
Now, this will give you one zero of the difference function, i.e. one intersection of your functions. It turns out that finding every zero of a function is a challenging task. Generally you have to call fzero multiple times with various starting points x0. If you suspect what your functions look like, this is not hopeless at all.
So what happens if your functions are more messy? In the general case, you can use an interpolating function to play the part of y1fun and y2fun in the example above, for instance by using interp1:
% generate data
xdata = 0:0.001:5;
y1data = sin(xdata)+cos(1+xdata.^2)-1;
y2data = ((1/2).*xdata)-1;
y1fun = #(x) interp1(xdata,y1data,x);
y2fun = #(x) interp1(xdata,y2data,x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(#(x)y1fun(x)-y2fun(x),x0);
which leads back to the original problem. Note that interp1 by default uses linear interpolation, depending on what your function looks like and how your data are scatted you can choose other options. Also note the option for extrapolation (to be avoided).
So in both cases, you get one crossing for each call to fzero. By choosing the starting points carefully, you should be able to find all the zeros, as exactly as possible.
Maybe the two vectors do not have exactly equal values anywhere. You could try to search for a smallest difference:
abs(y1-y2)<tolerance
where tolerance=0.001 is a small number

how to compute all the minors with a given order of a matrix in matlab

I have a matrix m*n,
I want from it all the minors (the determinant of the submatrices) of order p.
I din't found anything good in the documentation, I could do it with a function written by my self, but I'd prefer something out of the box.
My real need is to check when,in a symbolic matrix, I have a fall of rank,and that happens when all the minors of that rank and above are zeros.
Any idea to do it with pure matlab comands? since there is a function to evalutate rank it has get the minors someway.
There appear to be some good answers already, but here is a simple explanation of what you can do:
Suppose you want to know the rank of every i-jth submatrix of a matrix M.
Now i believe the simplest way to get all ranks is to loop over all rows and columns and store this result in a matrix R.
M = magic(5);
R = NaN(size(M));
for i=1:size(M,1);
for j=1:size(M,2);
R(i,j) = rank(M([1:i-1 i+1:end],[1:j-1 j+1:end]));
end
end
If you want all determinants replace rank with det.
This calculates the submatrix:
submatrix=#(M,r,c)M([1:r-1,r+1:end],[1:c-1,c+1:end])
You may either use 'arrayfun' and 'meshgrid' or two loops to iterate over all submatrices.
Caveat: I don't have the Symbolic Toolbox but for a regular matlab array you can calculate the i-th, j-th minor with an anonymous function like this:
minor = #(i,j,A)det(A(setdiff([1:end],[i]),setdiff([1:end],[j])))
Or if you want the i-th, j-th cofactor, simply use:
cofactor = #(i,j,A)(-1)^(i+j)*det(A(setdiff([1:end],[i]),setdiff([1:end],[j])))
But as mentioned I don't know if something like this will work with the Symbolic Toolbox. If it does not work as-is, perhaps this can at least give you some ideas on how you might implement the function for the symbolic case.
Hope this helps.

How to find if a matrix is Singular in Matlab

I use the function below to generate the betas for a given set of guess lambdas from my optimiser.
When running I often get the following warning message:
Warning: Matrix is singular to working precision.
In NSS_betas at 9
In DElambda at 19
In Individual_Lambdas at 36
I'd like to be able to exclude any betas that form a singular matrix form the solution set, however I don't know how to test for it?
I've been trying to use rcond() but I don't know where to make the cut off between singular and non singular?
Surely if Matlab is generating the warning message it already knows if the matrix is singular or not so if I could just find where that variable was stored I could use that?
function betas=NSS_betas(lambda,data)
mats=data.mats2';
lambda=lambda;
yM=data.y2';
nObs=size(yM,1);
G= [ones(nObs,1) (1-exp(-mats./lambda(1)))./(mats./lambda(1)) ((1-exp(-mats./lambda(1)))./(mats./lambda(1))-exp(-mats./lambda(1))) ((1-exp(-mats./lambda(2)))./(mats./lambda(2))-exp(-mats./lambda(2)))];
betas=G\yM;
r=rcond(G);
end
Thanks for the advice:
I tested all three examples below after setting the lambda values to be equal so guiving a singular matrix
if (~isinf(G))
r=rank(G);
r2=rcond(G);
r3=min(svd(G));
end
r=3, r2 =2.602085213965190e-16; r3= 1.075949299504113e-15;
So in this test rank() and rcond () worked assuming I take the benchmark values as given below.
However what happens when I have two values that are close but not exactly equal?
How can I decide what is too close?
rcond is the right way to go here. If it nears the machine precision of zero, your matrix is singular. I usually go with:
if( rcond(A) < 1e-12 )
% This matrix doesn't look good
end
You can experiment with a value that suites your needs, but taking the inverse of a matrix that is even close to singular with MATLAB can produce garbage results.
You could compare the result of rank(G) with the number of columns of G. If the rank is less than the column dimension, you will have a singular matrix.
you can also check this by:
min(svd(A))>eps
and verifying that the smallest singular value is larger than eps, or any other numerical tolerance that is relevant to your needs. (the code will return 1 or 0)
Here's more info about it...
Condition number (Maximal singular value/Minimal singular value) is another good method:
cond(A)
It uses svd. It should be as close to 1 as possible. Very large values mean that the matrix is almost singular. Inf means that it is precisely singular.
Note that almost all of the methods mentioned in other answers use somehow svd :
There are special tools designed for this problem, appropriately called "rank revealing matrix factorizations". To my best (albeit a little old) knowledge, a good enough way to decide whether a n x n matrix A is nonsingular is to go with
det(A) <> 0 <=> rank(A) = n
and use a rank-revealing QR factorization of A:
AP = QR
where Q is orthogonal, P is a permutation matrix and R is an upper triangular matrix with the property that the magnitude of the diagonal elements is decreased along the diagonal.

how to get the maximally independent vectors given a set of vectors in MATLAB?

If I am given a set of vectors (they can be provided as the column vectors of a matrix), and I want to get the maximally independent vectors, what is the best way to go about it?
I could add one vector to the result set at a time to see if the rank of the newly formed matrix is increased or not. But I feel it is not very efficient. Of course, I could go back to do Gauss elimination to work this out. But I am just wondering if there is a better (efficient and numerically stable and robut) approach to this problem.
Thanks.
Edit
Feel the addition by watching the rank increasing is probably not valid. We can do deletion by watching if the rank is decreasing though.
This code will do the trick. It's a little bit dirty because it grows rInd on the fly, which isn't the most efficient, but the idea is more important. It uses the QR decomposition, which is basically Gram-Schmidt orthogonalization. From this, it goes through the rows of r until it finds the next vector in A that adds something linearly independent to the currently known basis.
iUnderConsideration = 1;
[q,r] = qr(A);
rInd = [];
for j = 1:size(r,2),
if(r(iUnderConsideration,j) ~= 0)
rInd = [rInd r(:,j)];
iUnderConsideration = iUnderConsideration + 1;
end
if(iUnderConsideration > size(r,1))
break;
end
end
q*rInd %here's your answer
As a side note, this code will chose the vectors of your matrix A without changing them. svd wouldn't give you these directly.
[U,S,V]=svd(vectors);
U(1:size(vectors,1),1:size(vectors,2))=vectors;
U now contains the original vectors plus an optimally orthogonal set.
Doing RREF and looking for columns with the leading zeros is your best bet:
matr(:,logical(sum(rref(matr)==1)))
This will give you the basis for the column space of the matrix.
SVD is your answer.
The MATLAB reference for SVD.