How can I fix my code to do line by line conditional statements in Matlab - matlab

I just started learning Matlab roughly an hour ago after being told I had to convert my rscript into Matlab. I wrote a conditional statement below and it does not work. The reason I believe is because it is not currently going line by line. data is a Matlab table. Here is my current code:
if data.Year == data.initYear
data.initY = -1
else
data.initY = 0
end
in R it was:
workable$saleYear <- ifelse(workable$year == workable$initYear, -1,0)
Any help would be appreciated

You want to do this in a vector. That way you don't need for loops or if statements.
data.initY = zeros(size(data.Year));
data.initY(data.Year == data.initYear) = -1;

Related

Range checking fails for loading .txt files in Matlab

I have been struggling to write the code to read in .txt data. I am in a directory where all of the file names are ‘img0001.txt’ through ‘img4200.txt’. Each file is a 2-D array of the same size (480x640), eventually I want to fill a 3-D data cube, but first I need to be able to read in all the data.
for i = 1:4200
i
if i<10
A = csvread(['img000',num2str(i),'.txt']);
elseif 10<=i<100
A = csvread(['img00',num2str(i),'.txt']); ***
elseif 100<=i<1000
A = csvread(['img0',num2str(i),'.txt']);
else i>=1000
A = csvread(['img',num2str(i),'.txt']);
end
end
The code prints i=100, and then gives me an error message for a file not found in the line where I added ***. The code is looking for file img00100.txt which does not exist, but I’m not sure why it is doing this.
I have been playing with different versions of writing the if, elseif, statements and the greater than and less than operators. I have also tried using eval and load commands.
Thank you.
m7913d's answer explains your if statement's logic, but a nice way to avoid the confusion would be to remove the if statements entirely using sprintf.
for i = 1:4200
filenum = sprintf('%04d', i); % Zero pads the number e.g. 59 => 0059
disp(['i =', filenum]) % Display current i
A = csvread(['img', filenum, '.txt']); % Load CSV
end
Your condition to check the range is wrong. You should write it as follows:
elseif 10 <= i && i < 100
What you calculated is the following (explained for i == 100):
10 <= i < 100 <=> (10 <= i) < 100 <=> (1) < 100 <=> 1
Note that this is the case for a lot of programming languages (C++, java, js, ...).

If and elseif, only the first line work?

L=1; Nx=51; PeriodicFlag=1; T=15; Nt=51;
spacedef='Pade6FirstDeriv'; casedef='LinearAdvection';
if (spacedef == 'Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
else
error(sprintf('Unknown spacedef = %s',spacedef));
end
In the above code, the if section is a small segment from a function I've constructed. I'm trying to get the function to know which methods to use based on my input (spacedef). Central2, Central4, Upwind3, and Pade6 are other functions I've written. The weird thing is that when spacedef =/= to 'Pade6FirstDeriv', I would get an error stating Error using ==, Matrix dimensions must agree. I've tried swapping the order of the if loop (by placing Central4, Central2, Pade6, and Upwind3 in the first line of the loop), and it seems like only the top line of the loop will work (the elseifs are not working). I'd greatly appreciate it if anybody can help me out. Thanks!
As has been noted in the comments, this is a common error when people first start comparing strings in MATLAB, and strcmp or strcmpi is generally the solution.
However, one solution the questions links in the comments don't present, and a solution I think looks much nicer, is the switch statement:
switch (spacedef)
case('Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
case('Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
case('Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
case('Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
otherwise
error(sprintf('Unknown spacedef = %s',spacedef));
end
Note: if I expect others to use my code with string comparisons, I usually lower the input such that the comparison is case-insensitive, although I have not done that here.

Matlab Create an array with element of a for loop

Here's my code:
N = 1:999;
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(i,1) = i
end
end
Te problem is that I get an Array with some zeros in, but I just want an an arraywith the values comforming to my conditions.
How can I fix it?
Thank you!
I think the OP is looking for a result like:
v= N( (rem(N,3)==0) | (rem(N,5)==0) );
though without looping... :-)
I'm assuming that you're using a loop for a reason, and am not removing it from my solution. However, loops should be avoided where possible.
If I understand your question, you're trying to store only those values of i which correspond to a true conditional evaluation. You're problem is that you're using i as your index value inside the assignment statement. Use the end index keyword. Like so:
N = 1:999;
v = [];
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(end+1) = i
end
end

IDL equivalent of MATLAB function accumarray()

I've been given the task of translating a piece of MATLAB code into IDL and have
hit a roadblock when I came across the MATLAB function accumarry(). The
function, described here
is used to sum elements in one array, based on indices given in another. Example
1 perhaps explains this better than the actual function description at the top
of the page. In trying to reproduce Example 1 in IDL, I haven't been able to avoid a for loop, but I'm confident that it is possible. My best attempt is the following:
vals = [101,102,103,104,105]
subs = [0,1,3,1,3]
n = max(subs)+1
accum = make_array(n)
for i = 0, n-1 do begin
wVals = where(subs eq i,count)
accum[i] = count eq 0 ? 0 : total(vals[wVals])
endfor
print,accum
; 101.000 206.000 0.00000 208.000
Any advice on improving this would be greatly appreciated! I expected IDL to have a similar built-in function, but haven't been able to track one down. Perhaps some magic with histogram binning?
I found a number of possible solutions to this problem on Coyote's IDL site (not surprisingly.)
http://www.idlcoyote.com/code_tips/drizzling.html
I ended up using the following, as a compromise between performance and readability:
function accumarray,data,subs
mx = max(subs)
accum = fltarr(mx+1)
h = histogram(subs,reverse_indices=ri,OMIN=om)
for j=0L,n_elements(h)-1 do if ri[j+1] gt ri[j] then $
accum[j+om] = total(vals[ri[ri[j]:ri[j+1]-1]])
return,accum

'Undefined function or variable' in Matlab

Here is my code:
function [im,sindx,end1]=alln(im,i,j,secret,sindx,end1)
slen=length(secret);
p=im(i,j);
neigh= [im(i-1,j) im(i+1,j) im(i,j-1) im(i,j+1) im(i-1,j-1) im(i+1,j-1) im(i-1,j+1) im(i+1,j+1)];
minpix = min (neigh)
maxpix = max (neigh)
if minpix < p < maxpix
lowlim = minpix+1;
highlim = maxpix-1;
range = highlim-lowlim+1;
nbits=floor(log2(abs(range)));
if sindx+nbits-1>slen
end1=1;
return
end
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
b = bin2dec(bin);
newvalue1 = abs (minpix + b);
newvalue2 = abs (maxpix - b);
if abs(p-newvalue1)<= abs(p-newvalue2)
im(i,j) = newvalue1;
else
im(i,j) = newvalue2;
end
sindx=sindx+nbits;
end
end
My main program calls this function. When I run the program, I get the following error message:
??? Undefined function or variable "bin".
Error in ==> alln at 34
b = bin2dec(bin);
I know there are many experts for whom this is not a problem at all. I am new to MATLAB. Please guys, show me the way, which type of modification in the code can overcome this problem?
First of all, are there some lines missing from the file? Perhaps you've stripped some comments from the top? Because the error message says that
b = bin2dec(bin);
is line 34, but it's line 22 in the code you present.
OK, that aside...
The error message says that 'bin' isn't defined, but I see that it's being set on the line...
bin(k)=secret(sindx+k-1);
That suggests to me that THAT line isn't being run.
I see that that bin = ... line is inside of a 'for' loop, so I suspect that the for loop is run zero times, meaning that 'bin' never gets defined. What is nbits? Is it 1, or perhaps less than 1? THAT would prevent the loop from running at all.
Try removing the semicolon from the end of the
nbits=floor(log2(abs(range)));
line and run your code again.
Leaving off the semicolon will force the value of nbits to be printed in the Command Window. I bet you'll find that it's 1 or less. If that's the case, then start looking at HOW nbits is calculated, and I bet you'll find the problem.
At what input arguments to the function alln, are you getting the error?
Lets suppose that nbits is 0, then the following loop will not run:
for k=1:nbits
bin(k)=secret(sindx+k-1);
end
So, bin will be undefined. So, the error happens. This is one of the cases where the error can happen. There are many such possible cases.