Function call in script and command line gets different result - matlab

I have a matlab-function tutorial_main(xalpha) that returns me a struc element with 2 entries (due to copyright, I can't provide you with the function :( )
Whenever I call the function from the command line with
fit_t = [];
alpha = 0.01;
fit_t = [fit_t tutorial_main(alpha)];
it works just fine.
Whenever I do the same in a script inside a loop, I get an error:
fit_t = []
for alpha = 0.01:0.01:1
tic;
fit_t = [fit_t tutorial_main(alpha)];
time = toc;
end
The error is:
Improper assignment with rectangular empty matrix.
Error in tutorial_main (line 286)
ML(1) = myvect(p{1}(max(marglik{1})==marglik{1}));
Error in ass5 (line 14)
fit_t = [fit_t tutorial_main(alpha)];
and sometimes it runs for a few iterations but after the third gives me
In an assignment A(I) = B, the number of elements in B and I must be the
Error in tutorial_main (line 286)
ML(1) = myvect(p{1}(max(marglik{1})==marglik{1}));
Error in ass5 (line 14)
fit_t = [fit_t tutorial_main(alpha)];same.
I really don't understand why I get this error message. The function should in both cases be called the same way. Running clear all before does not change anything.
Now the weirdest part:
When I set a breakpoint at time = toc, and continue manually after every loop, I do NOT get an error. Removing the tic/toc does not help.
Edit: Okay, sometimes I also get an error with breakpoints.

Are you positive that your function returns a scalar or at least a row vector?
The difference is that fit_t = [fit_t retval]; is always OK if initially fit_t=[], but if it already has a scalar/row vector value then you run into problems unless retval (the return value) is a scalar/row vector.
Your error saying In an assignment A(I) = B, the... also suggests this: your right-hand side is probably a vector in ML(1) = myvect()..., most likely marglik{1} doesn't have a unique maximum, so max(marglik{1})==marglik{1} returns a logical vector with multiple non-zeros, so p{1}(max...) is a vector, which collides with ML(1) on the left side. You need to choose one value from the ones in max(marglik{1})==marglik{1} in case there are several ones.
(This, or the magic fairies used the wrong kind of binary dust on your secret function. Really hard to debug a black box if we don't even know what it outputs.)

Related

How can I access my vectors indices when I am assigning values?

I am trying to code something in Matlab and it involves a lot of accessing elements in vectors. Below is a snippet of code that I am working on:
x(1)=1;
for i=2:18
x(i)=0;
end
for i=1:18
y(i)=1;
end
for i = 0:262124
x(i+18+1) = x(i+7+1) + mod(x(i+1),2);
y(i+18+1) = y(i+10+1) + y(i+7+1) + y(i+5+1) + mod(y(i+1), 2);
end
% n can be = 0, 1, 2,..., 262142
n = 2;
for i = 0: 262142
z(i+1) = x(mod(i+n+1, 262143)); %error: Subscript indices must either be real positive integers or logicals.
end
In the last "for" loop where I am initialising vector z(), I get an error saying: "Subscript indices must either be real positive integers or logicals." However, when I do not suppres z(i+1) by ommiting the semi colon, the program is able to run, and I can see the values of z in the workspace. Why is this?
The code I am writing in Matlab is based upon the series of instructions shown in the image below. However, I can't seem to track down my error which leads to me not being able to access the elements of x() (without not suppressing the output of z()).
I appreciate any ideas :-) Thank you!
The code breaks at that loop last iteration because , for i=262140 you get
(mod(i+n+1, 262143)) = 0
so you cant access x(0) in matlab. the first elements of any variable is x(1).
In addition, and not related to your question, this code doesn't use the advantages matlab has, instead of
for i=2:18
x(i)=0;
end
you can just write:
x(2:18)=0;
etc

Matlab invalid vector using lpsolve

I am using a function in Matlab based on lp_solve. In my case, lp_solve is structured as follows:
A = rand (13336,3); %A is made of real numbers between 0 and 1. For this mwe, I thought 'rand' was fine
W = [0; 0; 1];
C = A(:,3);
B = 1E+09;
e = -1;
m= 13336;
xint = linspace(1,13336,13336);
xint = xint';
obj = lp_solve(A*W,C,B,e,zeros(m,1),ones(m,1),xint)
But when I run it, I get this error:
Error using mxlpsolve
invalid vector.
Error in lp_solve (line 46)
mxlpsolve('set_rh_vec', lp, b);
Error in mylpsolvefunction (line 32) %This is my function that uses lp_solve
obj = lp_solve(A*W,C,B,e,zeros(m,1),ones(m,1),xint);
I looked in the documentation, and it say, under the chapter "Matrices" that:
[...] if a dense matrix is provided, the dimension must exactly match the dimension that is expected by mxlpsolve. Matrices with too few or too much elements gives an 'invalid vector.' error. Sparse matrices can off course provide less elements (the non provided elements are seen as zero). However if too many elements are provided or an element with a too large index, again an 'invalid vector.' error is raised.
I did not understand what they mean when they say that the dimension "must exactly match the dimensions that is expected by mxlpsolve". Anyway, since they say that the error my also occur "if too many elements are provided", I tried to "cut" my inputs from 13336 elements to 50 (I am sure it works with 58 and I am quite sure it does also with 2000), but also this way I receive the same error. What may the problem be?

Matlab Subscript Index Error

First of all the output of 'find_nbrs' is a row vector. I get the following error (Subscript indices must either be real positive integers or logicals.) at line 13 when evaluating the following code:
function [ N ] = componentt( A,m,found_list )
found_list=[m];
for i = find_nbrs(m,A)
found_list(length(found_list)+1)=i;
end
v=[];
for j=found_list
v=[v find_nbrs(j,A)];
end
v=unique(v);
while length(v)~= length(found_list)
found_list = [found_list v(end)];
for k=v
a=find_nbrs(k,A);
while ~ismember(a,found_list)
v(length(v)+1)=a;
end
end
end
N=sort(found_list); %The entries of the output vector are in increasing order.
end
There are two possible reasons for the
Subscript indices must either be real positive integers or logicals.
error being thrown by the line
found_list = [found_list v(end)];
The first is that you somehow created a variable called end. But since you have posted an entire function which should be scoped I don't think that this is the case.
The second is that v is an empty matrix. In this case what is end? It might be 0. It's definitely not a positive integer though. Try this
v = [];
v(end)
and you'll get the error.
So you need to ask yourself if v should ever be empty by the time you hit that line. If it is, then you need to wrap it in an if statement. So something like
if ~isempty(v)
found_list = [found_list v(end)];
end

Subscript indices must either be real positive integers or logicals error within Matlab decay program

I am having issues with a code of mine dealing with decay. The error "Subscript indices must either be real positive integers or logicals" continues to occur no matter how many times I attempt to fix the line of code: M=M(t)+h.*F
Here is the complete code so that it may be easier to solve the issue:
M=10000;
M=#(t) M*exp(-4.5*t);
F=-4.5*M(t);
h=.1;
t(1)=0;
tmax=20;
n=(tmax-t(1))/h;
i=1;
while h<=.5
while i<=n
t=t+h;
M=M(t)+h.*F;
data_out=[t,M];
dlmwrite('single_decay_euler_h.txt',data_out,'delimiter','\t','-append');
i=i+1;
end
h=h+.1;
end
Thanks for any help.
In the start, you're setting M = 5000;. In the following line, you're creating an anonymous function also called M:
M=#(t) M*exp(-4.5*t);
Now, your initial M = 5000 variable has been overwritten, and is substituted by the function:
M(t) = 5000 * exp(-4.5*t); %// Note that the first M is used to get 5000
Thereafter you do F = -4.5*M(t). I don't know what the value t is here, but you're giving F the value -4.5 * 5000 * exp(-4.5*t), for some value of t. You are not creating a function F.
In the first iteration of the loop, M=M(t)+h.*F; is interpreted as:
M = 5000 * exp(-4.5*0) + 0.1*F %// Where F has some value determined by previous
%// the function above and the previous value of t
%// -4.5*0 is because t = 0
M is now no longer a function, but a single scalar value. The next iteration t = 0.1. When you do: M=M(t)+h.*F; now, it interprets both the first and second M as a variable, not a function. t is therefore used as an index, instead of being an input parameter to the function M (since you have overwritten it).
When you are writing M(t), you are trying to access the 0.1'th element of the 1x1 matrix (scalar) M, which obviously isn't possible.
Additional notes:
The outer while loop has no purpose as it stands now, since i isn't reset after the inner loop. When you're finished with the first iteration of the outer loop, i is already >n, so it will never enter the inner loop again.
You shouldn't mix variable and function names (as you do with M. Use different names, always. Unless you have a very good reason not to.
data_out=[t,M]; is a growing vector inside a loop. This is considered very bad practice, ans is very slow. It's better to pre-allocate memory for the vector, for instance using data_out = zeros(k,1), and insert new values using indexes, data_out(ii) = M.
It's recommended not to use i and j as variable names in MATLAB as these also represent the imaginary unit sqrt(-1). This might cause some strange bugs if you're not paying attention to it.
You can almost certainly do what you're trying to do without loops. However, the function you have written is not functioning, and it's not explained all too well what you're trying to do, so it's hard to give advice as to how you can get what you want (but I'll give it a try). I'm skipping the dlmwrite-part, because I don't really understand what you want to output.
M = 5000;
t0 = 0;
tmax = 20;
h = 0.1; %// I prefer leading zeros in decimal numbers
t = t0: h: tmax;
data_out = M .* exp(-4.5 * t);
The problem is caused by M(t) in your code, because t is not an integer or logical (t=1,1.1,1.2,...)
You need to change your code to pass an integer as a subscript. Either multiply t by 10, or don't use the matrix M if you don't need it.

indexing error, MATLAB

keep getting an indexing error " ()-indexing must appear last in an index expression"
bascially im trying to create a matrix x made of randn(n,1000000) where every jth row is multiplied by matrix NV(i,j).
%monte carlo simulation
function [y1,y2,y3,y4]= ed1(SNRL,SNRS,SNRH,n) %ed is the energy detection
g1= SNRL:SNRS:SNRH;
g=10.^(g1/10);
beta=0.8; % is the probability pfa, it cannot be more than 1
pf1=zeros(1,length(g));
pd1=zeros(1,length(g));
pf2=zeros(1,length(g));
pd2=zeros(1,length(g));
x=zeros(n,length(g));
y=zeros(n,length(g));
for i=1 : length(g)
for j=1:n
NV=(i,j);
x(j,:) = randn(n,1000000)*sqrt(NV(i,j));
y(j,:)=randn(n,1000000*(j),:)*sqrt(g(i))+x(j,:);
end
%Tgam is the threshold of gamma distribution
Tgam = gaminv((1-beta),n/2,(2/n)*(1+g(i))); %probab of flase detection
pf1(i)= gamcdf(Tgam,n/2,(2/n)*(1+g(i))); %ho
pd1 (i) = gamcdf(Tgam,n/2,2/n); %h1 % prob of detection
pf2(i)= length (find(sum(y.^2)/n<Tgam))/1000000;
pd2 (i) = length (find(sum(x.^2)/n<Tgam))/1000000;
y1=pf1; y2=pd1; y3=pf2; y4=pd2;
end
You have three things giving you errors:
1) NV=(i,j) This syntax will give you an error message. If you are not getting an error message about this line, you have an error in the line calling this code and should post that too. Try NV=zeros(length(g),n); for a temporary fix until you know what NV should be.
2) randn(n,1000000*(j),:) is also bad syntax. Do you mean randn(n,1000000*(j))?
3) x(j,:) = randn(1,10000)*sqrt(NV(i,j));: x as written in your code is not the right size unless g is magically of length 10000.
Hopefully checking these 3 things will give you an idea of what is giving your specific error message (which is not the same as any of the messages these errors gave me.)