Matlab stepwise fit wont run through loop - matlab

I am a relatively new Matlab user and possibly biting off more than I can chew with this code. Basically it loops through a stepwise regression time in all of the 1505 columns that have data (it is important that the columns without data are kept)
At the start of the code, the length of some columns is changed due to a lag (predetermined in another code). I think this is causing the problem as I get a dimension mismatch further down in the code (indicated below by a comment). I am quite stuck and not sure how to fix the problem. I would really appreciate anything that is obvious being pointed out to me.
Thanks in advance for any help!
for j = 1:1505
m = lag (1,j) %this is a number between 1 and 6 indicating the best lag
Nc=NDVI(m+1:end,j);
A1c=Approx1 (1:end-m,j);
A2c=Approx2 (1:end-m,j);
A3c=Approx3 (1:end-m,j);
A4c=Approx4 (1:end-m,j);
D1c=Det1 (1:end-m,j);
D2c=Det2 (1:end-m,j);
D3c=Det3 (1:end-m,j);
D4c=Det4 (1:end-m,j);
xx=[A1c, A2c, A3c, A4c, D1c, D2c, D3c, D4c];
yy = Nc;
%Begin Stepwise Regression
if isnan(Nc)
continue
else
[B,SE,PVAL,INMODEL,STATS,NEXTSTEP,HISTORY]= ...
stepwisefit(xx,yy,'penter',.05);
inApprox1(j)=INMODEL(1);
inApprox2(j)=INMODEL(2);
inApprox3(j)=INMODEL(3);
inApprox4(j)=INMODEL(4);
inDpprox7(j)=INMODEL(5);
inDpprox8(j)=INMODEL(6);
inDpprox9(j)=INMODEL(7);
inDpprox10(j)=INMODEL(8);
sstotApprox1(j)=STATS.SStotal; %calculate R^2
ssresidApprox1(j)=STATS.SSresid;
rsq = 1- ssresidApprox1./sstotApprox1
rsq(rsq==Inf) = NaN %Set Inf to NaN
rmse(j)=STATS.rmse; %Extract rmse
rmse(rmse==Inf) = NaN; %Set Inf to NaN
% repeat regresson only on the sigificant variables
if sum(INMODEL,2)>0
xip=0;
for k=1:8 %8 refers to previous 8 variables including intecept
if INMODEL(1,k)==1
xip=xip+1;
xxn(:,xip)=xx(:,k); %ERROR HERE, xip AND k DIMENSION MISMATCH. UNSURE HOW TO SOLVE
end
end
[Bn,SEn,PVALn,INMODELn,STATSn,NEXTSTEPn,HISTORYn]= ...
stepwisefit(xxn,yy,'penter',.05);
rmsen(j)=STATSn.rmse; %Extract rmse
rmsen(rmse==Inf) = NaN; %Set Inf to NaN
end
end
end

Your code bombs because you are not clearing your xxn variable for each new lag. Instead, because your xxn is persisting, I believe that it will end up having the wrong size (the wrong number of rows) the next time you go through the big outermost loop.
In my opinion, you should initialize your xxn variable to zeros of the right size. You could do it in this section of your code...
% repeat regresson only on the sigificant variables
if sum(INMODEL,2)>0
xxn = zeros(size(xx,1),8); %ADD THIS LINE! Initializes to zero.
xip=0;
for k=1:8 %8 refers to previous 8 variables including intecept
if INMODEL(1,k)==1
xip=xip+1;
xxn(:,xip)=xx(:,k); %these should now be the correct dimension
end
end

Related

Variables are continuously zero while creating matrice with for loop

Here is my code;
%Blasius solution by Euler Method
%---------------
g0=zeros(101,1);
g1=zeros(101,1);
g2=zeros(101,1);
%---------------
g0(1)=0;
g1(1)=0;
% g1(101)=1;
g2(1)=2;
%---------------
G=zeros(101,3);
T=zeros(101,3);
G=[g0 g1 g2];
T=[g1 g2 (-1)*g0.*g2];
%Euler method%
for i=1:100
G(i+1) = G(i) + (T(i)*0.1);
end
What am I missing? I am trying to create the G matrix but it is always a 101*3 zero matrix. It looks like for loop doesn't work but I couldn't figure out why.
I figured out why your code is not working:
First of all you need to call row indices, not linear indices, i.e. change your loop to:
for ii=1:100
G(ii+1,:) = G(ii,:) + (T(ii,:)*0.1);
end
note that I also used ii as opposed to i, since using that as a variable is bad.
This results in T remaining constant, obviously, since you do not change it. You initialise it as a zero array and set only the second element on the first row to 2, but leave the rest as zeros. Adding a row of T to a row of G will therefore not do anything, since you are adding zeros to an existing row. This is why the second row of G becomes [0 0.2 2] and does not change anymore , since you are only adding zeros to it.
You probably forgot to add the line of code which assigns a new value to rows of T. Adhering to your suggestion in the comments:
for ii=1:100
G(ii+1,:) = G(ii,:) + (T(ii,:)*0.1);
T(ii+1,:) = G(ii,:);
end
Here is the new solution, we have spend hours but finally figure it out.
%Blasius solution by Euler Method
%---------------
g0=zeros(101,1);
g1=zeros(101,1);
g2=zeros(101,1);
g2(1)=2;
%---------------
G=zeros(101,3);
T=zeros(101,3);
G=[g0 g1 g2];
T=[g1 g2 ((-1)*g0.*g2)];
%Euler method%
for i=1:100
A=[g0(i) g1(i) g2(i)] ;
B=[g1(i)*0.1 g2(i)*0.1 (-1).*g0(i)*g2(i)*0.1];
C(i,:)=A+B;
g0(i+1)=C(i,1);
g1(i+1) =C(i,2);
g2(i+1) =C(i,3);
end

Why the number is not randomized using Matlab

I am trying to write a Matlab code to simulate a dice and compute its mean and standard deviation.
The problem is that no matter how many times we run this code, the result of randi(6) keeps the same. It made me crazy.
n=20;
m=0;
c=0;
for i=1:10000
while m<n
x=randi(6);
c=c+1;
m=m+x;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
end
I think you forgot to set m back to ZERO at the end of the for. If you want the sequence of randi to change you should take a look at the function "rng".
n=20;
m=0;
c=1;
for i=1:100
while m<n
x(i, c)=randi(6);
m=m+x(i,c);
c=c+1;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
m = 0;
end
You forgot to reset m and c back to 0 once the while loop terminates. m is set to 0 outside of the for loop only once, and so when m finally surpasses n, m never changes. As such, simply set m = 0 in your for loop before the while loop happens. You also need to set c to 0 because you want to count events each time the for loop iterates.
I'm also not sure how you could think that diff(i) = 2.5 for all i. This difference is a probabilistic value. Also, I don't see how you could get a floating point number in the difference because you are generating integers and accumulating integers for each trial. I think you need to examine what this value should be.
So:
n=20;
%//m=0;
%//c=0;
for i=1:10000
m = 0; %// Change here
c = 0; %// Change here too
while m<n
x=randi(6);
c=c+1;
m=m+x;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
end

Matlab Newton Raphson

I asked for help about Matlab task few weeks ago but removed it since it took me some time to solve. Unfortunately, I still have a problem.
Task is: Find a real root of the function f(x)=tanh(x^2 - 9) using at least 3 iterations, using Newton-Raphson method. x= 3.2 show each iteration graphically.
In code "pog" means min. mistake, "br" is counter.
If I don't put a counter, it immediately gives me "NaN", with counter it does write first few calculations.
My code:
clc
clear all
x=3.2;
fx=tanh(x^2-9);
iter=5;
pog=0.01;
br=1;
while br<10;
xk= x-((tanh(x^2-9))/(-2*x*(tanh(x^2 - 9)^2 - 1)));
fprintf ('x=%g\txk=%g\t%g\n', x,xk, abs(xk-x))
if pog>abs(xk-x);
break
end
x=xk;
br=br+1;
end
Thank you in advance!
As far as showing the iterations graphically, this is the best I can do:
clc
clear all
close
G=zeros(20,10);
X=linspace(2.5,3.5,20)
G(:,1)=X;
for i=1:length(X)
x=X(i)
fx=tanh(x^2-9);
pog=0.0001;
br=1;
while br<10;
xk= x-((tanh(x^2-9))/(2*x*sech(9-x^2)^2));
G(i,br+1)=xk;
x=xk;
br=br+1;
end
end
I=tanh(G(:,end).^2-9)<1e-5;
X(I)
plot(G,1:10)
hold off
axis([2.5 3.5 0 5])
X(I) is a list of starting values the converge to the root, and the plot shows iteration number on the y-axis, and the guess at that iteration on the x-axis. You can follow each starting value through and see what happens.
Here's another way of visualising Newton's method. It shows the tangent line that is constructed, and where it passes through 0 which gives you the new x values, from which a vertical line gives you the new function value, which defines a new tangent line for the next iteration. It might help.
clc
clear all
close
G=zeros(20,10);
X=linspace(2.75,3.25,20)
G(:,1)=X;
x2=2:.01:4;f2=#(x) tanh(x.^2-9); %// to help with plotting
for i=1:length(X)
x=X(i)
fx=tanh(x^2-9);
pog=0.0001;
br=1;
xk=x;
while br<10;
%// Newton method step
dx=((tanh(x^2-9))/(2*x*sech(9-x^2)^2));
xk=x-dx;
%// plotting everything
G(i,br+1)=xk;
plot(x2,f2(x2))
hold all
plot(G(i,br:br+1),f2(G(i,br:br+1)),'.','MarkerSize',16)
plot(x2,f2(x)+(x2-x)./(xk-x).*(-f2(x)))
plot(xk,0,'.','MarkerSize',16)
plot(x2,(x2-xk)*(2*xk*sech(9-xk^2)^2)+f2(xk))
plot([xk xk],[-1 1])
plot([2 4],[0 0],'k')
axis([2 4 -1 1])
drawnow
pause
hold off
%// finishing Newton step
x=xk;
br=br+1;
end
hold off
end

Loop seems to go forever when plotting a graph

I have written the following piece of code:
M = [3 0 0; 0 2 0; 0 0 0.5] % mass matrix
i_vals = 1:1000:60e06; % values of k_12 from 1 to 600 million in steps of 1000
modes = zeros(3, length(i_vals));
for n=1:length(i_vals)
i = i_vals(n) % i is the value of k_12
K = [i+8e06 -i -2e06; -i i+2e06 -1e06; -2e06 -1e06 5e06]; % stiffness matrix
[V,L]=eig(K,M);
V(:,I)=V;
A = V(:, [1])
transpose(A)
modes(:, n) = A
end
loglog(i_vals, modes')
But the loop seems to go forever and I do now know what is wrong with it. The idea was to get the first column from matrix V, and see what happens to the 3 elements in this column when value of k_12 is changed.
I don't know how you make this run forever. To me it looks as if it won't run at all. This won't answer your question, but will hopefully help you on the way =)
What do you want to do with this line? V(:,I)=V; What is I? Was it supposed to be i? Btw, using i and j as variables in MATLAB is not recommended (however, if you don't use complex numbers in your field, you shouldn't care too much).
You have a loop that goes 60,000 times, with calculations of eigenvalues etc. That is bound to take time (although not forever, as you state it does). You should get the answer eventually (if only the rest of the code worked). The resolution of your plot would be more than accurate enough with 10,000 or even 100,000 steps at a time.
This part:
A = V(:, [1])
transpose(A)
modes(:, n) = A
could simply be written as:
modes(:,n) = V(:,1)';
assuming you want the transposed of A. transpose(A) does nothing in this context actually. You would have to do A = transpose(A) (or rather A = A') for it to work.
There are all kinds of problems with your code - some of which may contribute to your issue.
You are computing values of i on a linear scale, but ultimately will be plotting on a log scale. You are doing a huge amount of work towards the end, when there is nothing visible in the graph for your effort. Much better to use a log scale for i_vals:
i_vals = logspace(0, 7.778, 200); % to get 200 log spaced values from
% 1 to approx 60E6`
You are using a variable I that has not been defined (in the code snippet you provide). Depending on its size, you may find that V is growing...
You are using a variable name i - while that is legal, it overwrites a built in (sqrt(-1)) which I personally find troublesome.
Your transpose(A); line doesn't do anything (You would have to do A = transpose(A);).
You don't have ; after several lines - this is going to make Matlab want to print to the console. This will take a huge amount of resource. Suppress the output with ; after every statement.
EDIT the following program runs quickly:
M = [3 0 0.0;
0 2 0.0;
0 0 0.5]; % mass matrix
i_vals = logspace(0, 7.78, 200); % values of k_12 from 1 to 600 million in steps of 1000
modes = zeros(3, length(i_vals));
for n=1:length(i_vals)
i = i_vals(n); % i is the value of k_12
K = [i+8e06 -i -2e06; -i i+2e06 -1e06; -2e06 -1e06 5e06]; % stiffness matrix
[V,L]=eig(K,M);
modes(:, n) = V(:,1);
end
loglog(i_vals, modes')
Resulting graph:
If I didn't break anything (hard to know what you were doing with I), maybe this can be helpful.

Matlab inverse operation and warning

Not quite sure what this means.
"Warning: Matrix is singular to working precision."
I have a 3x4 matrix called matrix bestM
matrix Q is 3x3 of bestM and matrix m is the last column of bestM
I would like to do C = -Inverse matrix of Q * matrix m
and I get that warning
and C =[Inf Inf Inf] which isn't right because i am calculating for the camera center in the world
bestM = [-0.0031 -0.0002 0.0005 0.9788;
-0.0003 -0.0006 0.0028 0.2047;
-0.0000 -0.0000 0.0000 0.0013];
Q = bestM(1:3,1:3);
m = bestM(:,4);
X = inv(Q);
C = -X*m;
disp(C);
A singular matrix can be thought of as the matrix equivalent of zero, when you try to invert 0 it blows up (goes to infinity) which is what you are getting here. user 1281385 is absolutely wrong about using the format command to increase precision; the format command is used to change the format of what is shown to you. In fact the very first line of the help command for format says
format does not affect how MATLAB computations are done.
As found here, a singular matrix is one that does not have an inverse. As dvreed77 already pointed out, you can think of this as 1/0 for matrices.
Why I'm answering, is to tell you that using inv explicitly is almost never a good idea. If you need the same inverse a few hundred times, it might be worth it, however, in most circumstances you're interested in the product C:
C = -inv(Q)*m
which can be computed much more accurately and faster in Matlab using the backslash operator:
C = -Q\m
Type help slash for more information on that. And even if you happen to find yourself in a situation where you really need the inverse explicitly, I'd still advise you to avoid inv:
invQ = Q\eye(size(Q))
Below is a little performance test to demonstrate one of the very few situations where the explicit inverse can be handy:
% This test will demonstrate the one case I ever encountered where
% an explicit inverse proved useful. Unfortunately, I cannot disclose
% the full details without breaking the law, but roughly, it came down
% to this: The (large) design matrix A, a result of a few hundred
% co-registrated images, needed to be used to solve several thousands
% of systems, where the result matrices b came from processing the
% images one-by-one.
%
% That means the same design matrix was re-used thousands of times, to
% solve thousands of systems at a time. To add to the fun, the images
% were also complex-valued, but I'll leave that one out of consideration
% for now :)
clear; clc
% parameters for this demo
its = 1e2;
sz = 2e3;
Bsz = 2e2;
% initialize design matrix
A = rand(sz);
% initialize cell-array to prevent allocating memory from consuming
% unfair amounts of time in the first loop.
% Also, initialize them, NOT copy them (as in D=C,E=D), because Matlab
% follows a lazy copy-on-write scheme, which would influence the results
C = {cellfun(#(~) zeros(sz,Bsz), cell(its,1), 'uni', false) zeros(its,1)};
D = {cellfun(#(~) zeros(sz,Bsz), cell(its,1), 'uni', false) zeros(its,1)};
E = {cellfun(#(~) zeros(sz,Bsz), cell(its,1), 'uni', false) zeros(its,1)};
% The impact of rand() is the same in both loops, so it has no
% effect, it just gives a longer total run time. Still, we do the
% rand explicitly to *include* the indexing operation in the test.
% Also, caching will most definitely influence the results, because
% any compiler (JIT), even without optimizations, might recognize the
% easy performance gain when the code computes the same array over and
% over again. It probably will, but we have no control over when and
% wherethat happens. So, we prevent that from happening at all, by
% re-initializing b at every iteration.
% The assignment to cell is a necessary part of the demonstration;
% it is the desired output of the whole calculation. Assigning to cell
% instead of overwriting 'ans' takes some time, which is to be included
% in the demonstration, again for cache reasons: the extra time is now
% guaranteed to be equal in both loops, so it really does not matter --
% only the total run time will be affected.
% Direct computation
start = tic;
for ii = 1:its
b = rand(sz,Bsz);
C{ii,1} = A\b;
C{ii,2} = max(max(abs( A*C{ii,1}-b )));
end
time0 = toc(start);
[max([C{:,2}]) mean([C{:,2}]) std([C{:,2}])]
% LU factorization (everyone's
start = tic;
[L,U,P] = lu(A, 'vector');
for ii = 1:its
b = rand(sz,Bsz);
D{ii,1} = U\(L\b(P,:));
D{ii,2} = max(max(abs( A*D{ii,1}-b )));
end
time1 = toc(start);
[max([D{:,2}]) mean([D{:,2}]) std([D{:,2}])]
% explicit inv
start = tic;
invA = A\eye(size(A)); % NOTE: DON'T EVER USE INV()!
for ii = 1:its
b = rand(sz,Bsz);
E{ii,1} = invA*b;
E{ii,2} = max(max(abs( A*E{ii,1}-b )));
end
time2 = toc(start);
[max([E{:,2}]) mean([E{:,2}]) std([E{:,2}])]
speedup0_1 = (time0/time1-1)*100
speedup1_2 = (time1/time2-1)*100
speedup0_2 = (time0/time2-1)*100
Results:
% |Ax-b|
1.0e-12 * % max. mean st.dev.
0.1121 0.0764 0.0159 % A\b
0.1167 0.0784 0.0183 % U\(L\b(P,;))
0.0968 0.0845 0.0078 % invA*b
speedup0_1 = 352.57 % percent
speedup1_2 = 12.86 % percent
speedup0_2 = 410.80 % percent
It should be clear that an explicit inverse has its uses, but just as a goto construct in any language -- use it sparingly and wisely.