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.
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.
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.
I have a matrix that is a function of some parameter A=A(x). I would like to find the points x where this matrix becomes singular. Example (I have a large matrix though):
syms x
A=[x sin(x); cos(x^2) 2.5];
So far I have been symbolically computing the determinant of the matrix and then used fzero or newtzero to find the roots of that characteristic equation. I.e.
detA = det(A);
fzero(matlabFunction(detA),startingGuess)
Then I found this: How to find out if a matrix is singular?, where it is advocated to not use the determinant under any circumstances.
Indeed the symbolic determinant calculation is terribly slow. However I tried to use rank(A) instead as suggested in the link and it does not seem to work for symbolic matrices.
Is there any way to implement the suggestions in the link for finding the roots of a characteristic equation of a matrix that is given symbolically?
A possible approach would be the following: a square matrix A is singular if and only if the homogeneous linear (with respect to the vector y) system A*y = 0 has nontrivial solutions y <> 0 (which is equivalent to det(A) = 0 and rank(A) = 0 among others. So a more or less standard, as I recall from the past, technique to compute such points x is to solve the nonlinear system
A(x)*y = 0 (1)
||y|| = 1 (2)
This way you can compute a point x* and a vector y* such that A(x*) is singular and y* is an eigenvector corresponding to the zero eigenvalue of A(x*).
If I remember correctly, you can also solve the somewhat easier system
A(x)*y = 0 (1)
<y,c> = 1 (2a)
where c is "almost" any nonzero random vector (normalize it to 1 to avoid numerical problems).
As a matter of fact there is an enormous bibliography on the subject - you can look for saddle-node bifurcation computations (in case A(x) is the Jacobian of a vector field), or for "distance to instability".
From a discussion with Ander Biguri it seems that the determinant is actually a perfectly fine method of approaching this problem. The problem seems to be to solve the final equation in a stable manner, which would be a different question.
I have a symbolic function, whose zeros I am particular interested in knowing. I have searched through google, trying to find something related to my query, but was unsuccessful.
Could someone please help me?
EDIT:
T(x,t) = 72/((2*n+1)^2*pi^3)*(1 - (2*n+1)^2*pi^2*t/45 + (2*n+1)^4*pi^4*t^2/(2*45^2) - (2*n+1)^6*pi^6*t^3/(6*45^3))*(2*n+1)*pi*x/3;
for i=1:1:1000
T_new = 72/((2*i+1)^2*pi^3)*(1 - (2*i+1)^2*pi^2*t/45 + (2*i+1)^4*pi^4*t^2/(2*45^2) - (2*i+1)^6*pi^6*t^3/(6*45^3))*(2*i+1)*pi*x/3;
T = T + T_new;
end
T = T - 72/((2*n+1)^2*pi^3)*(1 - (2*n+1)^2*pi^2*t/45 + (2*n+1)^4*pi^4*t^2/(2*45^2) - (2*n+1)^6*pi^6*t^3/(6*45^3))*(2*n+1)*pi*x/3;
T = T(1.5,t);
T_EQ = 0.00001
S = solve(T - T_EQ == 0,t);
The problem that I get is that S is an a vector which contains imaginary numbers. I expected a real number, because I am trying to calculate a time.
Here is a little background as to what I am trying to do:
http://hans.math.upenn.edu/~deturck/m241/solving_the_heat_eqn.pdf
In the given link is the heat equation solved for a particular one-dimensional case. The temperature distribution, that satisfies the prescribed boundary and initial conditions, is given on page 50, I believe.
What I would like to do is find the time at which the one-dimensional object equilibrates with the environment, which is held at a constant temperature of T=0. As far as I know, the easiest way to do this would be to use the Taylor expansion of the exponential function, using only the first few terms, because I expect the equilibrium time to be relatively short; and then use the small angle approximation for the sine function, because the rod has a relatively small length. Doing just this, I made a for loop to generate terms just as the summation function would--as you can see, I used 1000 terms.
Does what I am doing seem wrong to anyone? If there is a better method, could someone please recommend it?
You shouldn't be surprised to see imaginary roots provided that at least one root is real and positive, corresponding to your time. The question is if the time makes any sense due to the approximations that you're making. Have you plotted the the actual function to get a rough approximation for where the zero is?
I can't really comment on the particular problem you're trying to solve. You need to make sure that you're using enough Taylor expansion terms an that they are accurate for the domain. Have you tried this leaving in the exp and/or sin? Is there any reason that you can't just use zero? And have you checked that your summation has converged after 1,000 terms? Or does it converge much sooner or not at all?
The main question is why are you using symbolic math at all to solve this? This seems like a numeric problem unless you're experiencing overflow/underflow issues in your summation. You can find the zero using fzero in this case:
N = 32; % Number of terms in summation
x = 1.5;
T_EQ = 1e-5;
n = (2*(0:N)+1)*pi;
T = #(t)sum((72./n.^3).*exp(-n.^2*t/45).*sin(n*x/3))-T_EQ;
S = fzero(T,[0 1e3]) % Bounds around a root guarantees solution if function monotonic
which returns
S =
56.333877640358708
If you're going to use solve, I'd do something like the following to avoid for loops:
syms t
N = 32;
x = 1.5;
T_EQ = 1e-5;
n = (2*sym(0:N)+1)*sym(pi);
T(t) = sum((72./n.^3).*exp(-n.^2*t/45).*sin(n*x/3));
S = double(solve(T-T_EQ==0,t))
or, using symsum:
syms n t
N = 32;
x = 1.5;
T_EQ = 1e-5;
T(t) = symsum((72/(pi*(2*n+1))^3)*exp(-(pi*(2*n+1))^2*t/45)*sin(pi*(2*n+1)*x/3),n,0,N);
S = double(solve(T-T_EQ==0,t))
Lastly, your symbolic solutions are not even exact as some your pi variables are being converted to rational approximations. pi is floating point. Things like pi*t are generally safe if t is symbolic, because pi will be recognized as such. However, pi^2 is calculated in floating-point before being converted to symbolic due to order of operations. In general your should use sym('pi') or sym(pi) in symbolic expressions.
Assuming you have a polynomial or trigonometric function of x or y, and what you mean by "zeros" is the values where the function crosses the axis, i.e., either x or y is zero, you can call the value of the function when a variable is 0. An example:
syms x y
f=-cos(x)*exp(-(x^2)/40);
ezsurf(f,[-10,10])
F=matlabFunction(f,'vars',{[x]});
F([0])
The ezsurf just visualizes the plot. If you want a function of both x and y, you do something like the following:
syms x y
f=-cos(x)*cos(y)*exp(-(x^2+y^2)/40);
ezsurf(f,[-10,10])
F=matlabFunction(f,'vars',{[x,y]});
for y=0
solve(f)
end
This will give you the value of the function for which integer multiples of x correspond to zero points for y (values of the function that are on the y=0 plane).
This is the equation I am trying to solve:
h = (X'*X)^-1*X'*y
where X is a matrix and y is a vector ((X'X)^-1 is the inverse of X-transpose times X). I have coded this in Matlab as:
h = (X'*X)\X'*y
which I believe is correct. The problem is that X is around 10000x10000, and trying to calculate that inverse is crashing Matlab on even the most powerful computer I can find (16 cores, 24GB RAM). Is there any way to split this up, or a library designed for doing such large inversions?
Thank you.
That looks like a pseudo inverse. Are you perhaps looking for just
h = X \ y;
I generated a random 10,000 by 10,000 matrix X and a random 10,000 by 1 vector y.
I just broke up my computation step by step. (Code shown below)
Computed the transpose and held it in matrix K
Then I computed Matrix A by multiplying K by X
Computed vector b by multiplying K by vector y
Lastly, I used the backslash operator on A and b to solve
I didn't have a problem with the computation. It took a while, but breaking up the operations into the smallest groups possible helped to prevent the computer from being overwhelmed. However, it could be the composition of the matrix that you are using (ie. Sparse, decimals, etc.).
X = randi(2000, [10000, 10000]);
y = randi(2000, 10000, 1);
K = X';
A = K*X;
b = K*y;
S = A\b;
If you have multiple machines at your disposal, and you can recast your problem into the form h = X\y as proposed by #Ben, then you could use distributed arrays. This demo shows how you can do that.
Jordan,
Your equation is exactly the definition for "Moore-Penrose Matrix Inverse".
Check: http://mathworld.wolfram.com/Moore-PenroseMatrixInverse.html
Directly using h = X \ y; should help.
Or check Matlab pinv(X)*y