I'm trying to create two matlab .m files. "f.m" contains a function of the polynomial I want to use.
function y = f(x)
y = x.^3 - 7*x + 6;
Compute.m calls fzero with that function returning the polynomial and a for loop of values from -10 to 10.
clc
fun = #f;
answerArray= [];
for x0 = -10:10
z = fzero(fun,x0);
answerArray=[answerArray z];
end
answerArrayUnique=unique(answerArray)
The problem is my unique method is not working for some of the negative values. I am getting an answer of:
answerArrayUnique =
-3.0000 -3.0000 -3.0000 1.0000 2.0000
What is strange, is that if unique was failing every time on negative numbers there would be many more -3.0000's. Anyone have any idea what is causing this?
Note: Using the unique method call on that again does not fix the issue, which leads me to believe it thinks the numbers as they go further out in to the ten-thousandth spot are different.. maybe?
You should see Mendis answer, for how to properly do it. However, the problem you have is because those -3.000 are not equal.
unique work by sorting and then checking if consecutive numbers are equal. However, as you have used a numerical method to find the zeros, the solutions are approximate. Try to subtract two of the equal solutions, the difference will be small, but not zero.
To avoid this you can use uniquetol which allows you to specify a tolerance, for which within, you think two numbers are equal. e.g. uniquetol(answerArray,1e-4)
In matlab the best way to represent a polynomialy is thru coefficient vector. for your example:
p = [1 0 -7 +6];
To calculate the value at x=0.8 for example you use:
polyval(p,0.8)
to find the roots you use:
r = roots(p) %output: -3 2 1
Use 'fzero' only for non linear function and pray to find all solutions.
Related
For the linear regression, I want to generate the matrix for polynomials of n degree.
if n is 1
X=[x(:), ones(length(x),1)]
if n is 2
X=[x(:).^2 x(:) ones(length(x),1)]
...
if n is 5
X=[x(:).^5 x(:).^4 x(:).^3 x(:).^2 x(:) ones(length(x),1)]
I do not know how to code with matlab if I set n=6 and it will automatically generate the wanted X matrix. Hope you can help me.
This can be easily done with bsxfun:
X = bsxfun(#power, x(:), n:-1:0);
Or, in Matlab versions from R1016b onwards, you can use implicit expansion:
X = x(:).^(n:-1:0);
Check out the polyval function. I believe that will do what you’re looking for.
To get increasing the polynomial to increase in degree, you can increase the length of your p argument using a loop.
If you write edit polyfit you can see how MATLAB have implemented the polyfit command, which is similar to what you are trying to do. In there you will find the code
% Construct the Vandermonde matrix V = [x.^n ... x.^2 x ones(size(x))]
V(:,n+1) = ones(length(x),1,class(x));
for j = n:-1:1
V(:,j) = x.*V(:,j+1);
end
Which constructs the matrix you are interested in. The benefit of this method over the bsxfun is that you only calculate x(:).^n and then saves the intermediary results. Instead of treating all powers as seperate problems, e.g. x(:)^(n-1) as a seperate problem to x(:).^n.
So I have these three vectors:
And I have to find out for what value of k these three vectors are linearly dependent. I have tried using rref and linsolve with syms for this but that did not work out. I'm relatively new to MatLab and matrices so please keep that in mind.
I know in order to check if vectors are linearly dependent that c1...cn have to be non-zero.
I also want to know how you can use variables in general when solving these types of equations in MatLab.
A set of vectors (at least if you have n vectors in n dimensions) is linearly dependent if the matrix constructed from them is singular, i.e. if its determinant is 0. If you have the Symbolic Math Toolbox, you can construct a symbolic matrix:
syms k;
M = [1 k 0; -1 1 2; 0 0 3];
det(M)
This will tell you that det(M)==3*k+3, which you can solve by hand. But generally, you can ask matlab to solve it:
solve(det(M)==0,k);
which will tell you the answer is -1. So unless k==-1, these vectors are linearly independent (i.e. they comprise a basis of the Euclidean space R^3).
Update: If you don't have the Symbolic Math Toolbox, you could still try to find a numerical solution. First define a function
detfun=#(k) det([1 k 0; -1 1 2; 0 0 3]);
that for any value of k will give you the determinant of your matrix, for instance detfun(3) gives 12. Then you can use fsolve to find a numerical solution to the equation detfun(k)==0, by calling
fsolve(detfun,0)
in which the second argument, 0, refers to the starting point of the search performed by fsolve. This will tell you that the answer is k==-1, but a single call to fsolve will only give you a single solution. If your function has multiple roots, you have to play around with the starting points to find more of them. In this case, you can know that your function (i.e. det(M(k)) is linear in k, so it has a unique root.
The problem i am trying to understand is easy but i cant seem to get the correct result in matlab. The actual problem is that i want to get the weight vectors of a 2 hidden layer input RBF using just the plain distance as a function, i.e. no Baysian or Gaussian function as my φ. I will use the function with 2 centres let's say 0,0 and 1,1. So this will give me a Matrix φ of:
[0 sqrt(2) ; 1 1; 1 1; sqrt(2) 0] *[w1; w2] = [0;1;1;0] As defined my the XOR function.
When i apply the pseudoinverse of the Φ in matlab * [0;1;1;0] though i get [0.33 ; 0.33] which is not the correct value which would allow me to get the correct output values [0;1;1;0].
i.e. .33 * sqrt(2) != 0 .
Can someone explain to me why this is the case?
I'll take a swag at this. The matrix, I'll call A, A = [0 sqrt(2) ; 1 1; 1 1; sqrt(2) 0] has full column rank, but not full row rank, i.e. rank(A) = 2. Then you essentially solve the system Ax = b, where x is your weighting vector. You could also just do x = A\b in Matlab, which is supposedly a much more accurate answer. I get the same answer as you. This is a very rough explanation, when your system can not be solved for a certain solution vector, it means that there exists no such vector x that can be solved for Ax = b. What Matlab does is try to estimate the answer as close as possible. I'm guessing you used pinv, if you look at the Matlab help it says:
If A has more rows than columns and is not of full rank, then the overdetermined least squares problem
minimize norm(A*x-b)
does not have a unique solution. Two of the infinitely many solutions are
x = pinv(A)*b
and
y = A\b
So, this appears to be your problem. I would recommend looking at your φ matrix if possible to come up with a more robust system. Hope this is useful.
I have been give a very large matrix (I cannot change the values of the matrix) and I need to calculate the inverse of a (covariance) matrix.
Sometimes I get the error saying
Matrix is close to singular or badly scaled.
Results may be inaccurate
In these situations I see that the value of the det returns 0.
Before calculating inverse (of a covariance matrix) I want to check the value of the det and perform something like this
covarianceFea=cov(fea_class);
covdet=det(covarianceFea);
if(covdet ==0)
covdet=covdet+.00001;
%calculate the covariance using this new det
end
Is there any way to use the new det and then use this to calculate the inverse of the covariance matrix?
Sigh. Computation of the determinant to determine singularity is a ridiculous thing to do, utterly so. Especially so for a large matrix. Sorry, but it is. Why? Yes, some books tell you to do it. Maybe even your instructor.
Analytical singularity is one thing. But how about numerical determination of singularity? Unless you are using a symbolic tool, MATLAB uses floating point arithmetic. This means it stores numbers as floating point, double precision values. Those numbers cannot be smaller in magnitude than
>> realmin
ans =
2.2251e-308
(Actually, MATLAB goes a bit lower than that, in terms of denormalized numbers, which can go down to approximately 1e-323.) See that when I try to store a number smaller than that, MATLAB thinks it is zero.
>> A = 1e-323
A =
9.8813e-324
>> A = 1e-324
A =
0
What happens with a large matrix? For example, is this matrix singular:
M = eye(1000);
Since M is an identity matrix, it is fairly clearly non-singular. In fact, det does suggest that it is non-singular.
>> det(M)
ans =
1
But, multiply it by some constant. Does that make it non-singular? NO!!!!!!!!!!!!!!!!!!!!!!!! Of course not. But try it anyway.
>> det(M*0.1)
ans =
0
Hmm. Thats is odd. MATLAB tells me the determinant is zero. But we know that the determinant is 1e-1000. Oh, yes. Gosh, 1e-1000 is smaller, by a considerable amount than the smallest number that I just showed you that MATLAB can store as a double. So the determinant underflows, even though it is obviously non-zero. Is the matrix singular? Of course not. But does the use of det fail here? Of course it will, and this is completely expected.
Instead, use a good tool for the determination of singularity. Use a tool like cond, or rank. For example, can we fool rank?
>> rank(M)
ans =
1000
>> rank(M*.1)
ans =
1000
See that rank knows this is a full rank matrix, regardless of whether we scale it or not. The same is true of cond, computing the condition number of M.
>> cond(M)
ans =
1
>> cond(M*.1)
ans =
1
Welcome to the world of floating point arithmetic. And oh, by the way, forget about det as a tool for almost any computation using floating point arithmetic. It is a poor choice almost always.
Woodchips has given you a very good explanation for why you shouldn't use the determinant. This seems to be a common misconception and your question is very related to another question on inverting matrices: Is there a fast way to invert a matrix in Matlab?, where the OP decided that because the determinant of his matrix was 1, it was definitely invertible! Here's a snippet from my answer
Rather than det(A)=1, it is the condition number of your matrix that dictates how accurate or stable the inverse will be. Note that det(A)=∏i=1:n λi. So just setting λ1=M, λn=1/M and λi≠1,n=1 will give you det(A)=1. However, as M → ∞, cond(A) = M2 → ∞ and λn → 0, meaning your matrix is approaching singularity and there will be large numerical errors in computing the inverse.
You can test this in MATLAB with the following simple example:
A = eye(10);
A([1 2]) = [1e15 1e-15];
%# calculate determinant
det(A)
ans =
1
%# calculate condition number
cond(A)
ans =
1.0000e+30
In such a scenario, calculating an inverse is not a very good idea. If you just have to do it, I would suggest using this to increase display precision:
format long;
Other suggestion could be to try using an SVD of the matrix and tinker around with singular values there.
A = U∑V'
inv(A) = V*inv(∑)*U'
∑ is a diagonal matrix where you will see one of the diagonal entries close to 0. Try playing around with this number if you want some sort of an approximation.
Suppose I have an arbitrary transformation matrix A such as,
A =
0.9966 0.0007 -6.5625
0.0027 0.9938 1.0598
0 0 1.0000
And a set of points such that their x and y coordinates are represented by X and Y respectively.
And suppose,
[Xf Yf] = tformfwd(maketform('projective',A),X,Y);
Now,
[Xff Yff] = tformfwd(maketform('projective',inv(A)),Xf,Yf);
[Xfi Yfi] = tforminv(maketform('projective',A),Xf,Yf);
[Xff Yff] and [Xfi Yfi] seem to be exactly the same (and they should).
Is tforminv just there for convenience or am I missing something here?
I'll preface this by saying it is my best guess...
It's possible that tforminv may perform the transformation without actually forming the inverse matrix. For example, you can solve a system of linear equations Ax = b in two ways:
x = inv(A)*b;
x = A\b;
According to the documentation for inv, the second option (using the matrix division operator) can perform better "from both an execution time and numerical accuracy standpoint" since it "produces the solution using Gaussian elimination, without forming the inverse". tforminv may do something similar and thus show better overall behavior compared with passing the inverse matrix to tformfwd.
If you were so inclined, you could probably try a number of different transformation matrices and test the two approaches (tforminv or tformfwd and inv) to see how accurate the results are and how fast they are each computed.