Matlab function with for, if and else - matlab

I have a variable var0=rand(50,1).
I need to write a function that changes the first 5 lines to 0 and the rest to 1.
Ofcourse, I can simply do this like
var0=rand(50,1)
var0(1:5,1)=0
var0(6:end,1)=1
However I need to do this by using one for, one if and one else clause.
I tried many ways but can't get it working with for, it and else.Can someone please help with this fairly basic fuction?

Here's one implementation that meets the requirements:
stupidexercise = true;
topborder = 5;
var0 = rand(50,1);
if stupidexercise
for ii = 1:topborder
var0(ii, 1) = 0;
end
var0((topborder + 1):end, 1) = 1;
else
spy
end

As pointed out by others, this seems a silly assignment. Your approach is more efficient.
var0 = rand(50,1);
for ii = 1:50
if ii <= 5
var0(ii) = 0;
else
var0(ii) = 1;
end
end

Related

Parallelizing MATLAB code

Hello I want to use parallelize my MATLAB code to run High computing server. It is code to make image database for Deep learning. To parallelize the code I found the I have to for parfor loop. But I used that with the first loop or with the second loop it shows me error parfor cannot be run due to the variable imdb and image_counter. Anyone please help me to change the code to work with parfor
for i = 1:length(cur_images)
X = sprintf('image Numb: %d ',i);
disp(X)
cur_image = load(cur_images{i,:});
cur_image=(cur_image.Image.crop);
%----------------------------------------------
cur_image = imresize(cur_image, image_size);
if(rgb < 1)
imdb.images.data(:,:,1,image_counter) = cur_image;
else
imdb.images.data(:,:,1,image_counter) = cur_image(:,:,1);
imdb.images.data(:,:,2,image_counter) = cur_image(:,:,2);
imdb.images.data(:,:,3,image_counter) = cur_image(:,:,3);
imdb.images.data(:,:,4,image_counter) = cur_image(:,:,4);
imdb.images.data(:,:,5,image_counter) = cur_image(:,:,5);
imdb.images.data(:,:,6,image_counter) = cur_image(:,:,6);
imdb.images.data(:,:,7,image_counter) = cur_image(:,:,7);
imdb.images.data(:,:,8,image_counter) = cur_image(:,:,8);
imdb.images.data(:,:,9,image_counter) = cur_image(:,:,9);
imdb.images.data(:,:,10,image_counter) = cur_image(:,:,10);
end
imdb.images.set( 1,image_counter) = set;
image_counter = image_counter + 1;
end
The main problem here is that you can't assign to fields of a structure inside parfor in the way that you're trying to do. Also, your outputs need to be indexed by the loop variable to qualify as "sliced" - i.e. don't use image_counter. Putting this together, you need something more like:
% Make a numeric array to store the output.
data_out = zeros([image_size, 10, length(cur_images)]);
parfor i = 1:length(cur_images)
cur_image = load(cur_images{i, :});
cur_image=(cur_image.Image.crop);
cur_image = imresize(cur_image, image_size);
% Now, assign into 'data_out'. A little care needed
% here.
if rgb < 1
data_tmp = zeros([image_size, 10]);
data_tmp(:, :, 1) = cur_image;
else
data_tmp = cur_image;
end
data_out(:, :, :, i) = data_tmp;
end
imdb.images.data = data_out;

How to transfer excel formula to octave?

As you can see the image (excel file) I would like to use that formula in Octave to get the desired result. I also uploaded the octave codes picture and the workspace picture too. In workspace my result/values for storage variable should be the same values like that in excel (storage column). I have a doubt that in the code the last part using (if statement with i-1 is seems to be the error).
Can someone help me to figure it out? Let me know if any further clarifications required. Also I am posting my code below too:
BM_max = 1236;
virtual_feed_max = 64;
operation = dlmread ('2020Operation.csv');
BM = ones (size (operation, 1), 1);
for i=1:size(operation,1)
if operation(i,1)==1
BM(i,1)=BM_max;
else
BM(i,1)=0;
end
end
virtual_feed = ones(size(operation,1),1);
virtual_feed(:,1) = 64;
storage = ones(size(BM,1),1);
c = ones(size(BM,1),1);
for i=1:size(BM,1)
c=(BM(:,1)-virtual_feed(:,1));
end
for i=1:size(BM,1)
if ((i=1)&& c)<0
storage(:,1)=0;
elseif ((i=1)&& c)>0
storage(:,1)=c;
else
# Issue is below (Taking the value from subsequent row is the problem)
if (c+(storage(i-1,1)))<0
storage(:,1)=0;
elseif (c+(storage(i-1,1)))>0
storage(:,1)=(c+(storage(i-1,1)));
end
end
end
Workspace Excel
I think what you want is the following (as seen from your Excel screenshot)
BM_max = 1236;
virtual_feed_max = 64;
operation = [0; 1; 1; 1; 1; 1; 1; 1; 0; 0; 0; 0; 0];
BM = BM_max * operation;
virtual_feed = repmat (virtual_feed_max, size (operation));
storage = zeros (size (operation));
for i=2:numel (storage)
storage (i) = max (BM(i) - virtual_feed(i) + storage(i-1), 0);
endfor
storage
which outputs:
storage =
0
1172
2344
3516
4688
5860
7032
8204
8140
8076
8012
7948
7884
I leave the part of vectorization to make it faster for you. (hint: have a look at cumsum)
From this point on
for i=1:size(BM,1)
if ((i=1)&& c)<0
storage(:,1)=0;
elseif ((i=1)&& c)>0
storage(:,1)=c;
else
# Issue is below (Taking the value from subsequent row is the problem)
if (c+(storage(i-1,1)))<0
storage(:,1)=0;
elseif (c+(storage(i-1,1)))>0
storage(:,1)=(c+(storage(i-1,1)));
end
end
end
you are not changing a single value in storage but all the row/column, so each iteration, all the row/column is being changed instead of a single "cell".
You should use something like this:
storage(i,1) = 0;
BTW, a lot of those 'for' loops can be changed to vector operations. Example:
for i=1:size(BM,1)
c=(BM(:,1)-virtual_feed(:,1));
end
Can be changed for:
c = BM - virtual_feed;

Is there a way to optimize or maybe even vectorize this? (MATLAB)

I have an if statement within two loops, it runs too slow and I think it can be optimized. NF_zeta is a 2D logical array.
for k = 2:Nx
for l = 2:Ny
if NF_zeta(l,k)
z2(l,k) = z1(l,k) - optVar2*(U2(l,k) - U2(l,k-1) + V2(l,k) - V2(l-1,k));
end
end
end
Here are the results of a profiler
http://i.imgur.com/oMropeL.png
I tried with single loop in which the conditional statement was taken care of. Something similar to what is done for one loop for [1 4 5], I wrote
for idx = NF_zeta_v
z2(idx(1),idx(2)) = z1(idx(1),idx(2)) - optVar2*(U2(idx(1),idx(2)) - U2(idx(1),idx(2)-1) + V2(idx(1),idx(2)) - V2(idx(1)-1,idx(2)));
end
where NF_zeta_v is created in advance like this
c_z = 1;
for l = 1:Ny
for k = 1:Nx
if NF_zeta(l,k)
NF_zeta_v(:,c_z) = [l;k];
c_z = c_z + 1;
end
end
end
It took almost twice as long. The results of a profiler http://i.imgur.com/OegeEOC.png
What else can I try, any suggestions?
Here's one vectorized solution using diff -
diffs = diff(U2(2:end,:),[],2) + diff(V2(:,2:end),[],1);
allvals = z1(2:end,2:end) - optVar2*diffs;
z2(2:Ny,2:Nx) = NF_zeta(2:Ny,2:Nx).*allvals;
May be you want something like this if N_x and N_y are the size values:
Z2 = (z1-optVar2*(U2-circshift(U2, [0 1])+V2-circshift(V2, [1 0]))).*(double(NF_zeta));
Z2(1,:) = 0;
Z2(:,1) = 0;

Avoid for loop for setting the matrix element in Matlab

In a matrix, how does one set an adjacent and diagonal element to 1 if the values in these locations are the same avoiding a for loop?
An attempt made with for loop is given
[r,c] = size(mat1);
Sval = zeros(size(mat1));
for i = 1:r
for j = 1:c-1
if(mat1(i,j) == mat1(i,j+1))
Sval(i,j) = 1;
Sval(i,j+1) = 1;
else
Sval(i,j) = 0;
Sval(i,j+1) = 0;
end;
end;
end;
To receive the exact same output without the loops the code is the following. However it is not quite clear what you want to achieve with this code. Please elaborate further if this doesn't answer your question.
Sval = mat1(:,1:c-1) == mat1(:,2:c);
Sval(:,c) = Sval(:,c-1);
If I interpret your sentence right what you actually want is to shift/copy the equal values to the right as well. This could be achived by:
Sval = mat1(:,1:c-1) == mat1(:,2:c);
Sval(:,c) = zeros(r,1);
Sval(:,2:c) = Sval(:,1:c-1) | Sval(:,2:c);

faster sparse matric indexing in matlab

I had a question before but it was not as complete as this one! Actually, what I meant was that I have a nested if-for loop which I did not make it very clear before.
So, I have a very long code which is full of the following "if"s and matlab editor gives me a suggestion as follow:
this sparse indexing expression is likely to be slow
Is there any way by which I can make the code faster and do the matlab's suggestion? (The code may not run, because I just picked a few lines and tried to show the issue)
In my previous question, I did not explain that I need to use the i,j as index, so the answer was not convincing. But, as you can see here, I need to use the i and j as index which make the problem a little different from the previous post.
template = rand(200,200);
grid = rand(200,200);
T = size(template);
rws = size(grid,1);
cols = size(grid,2);
ind = "it is a matrix";
A = sparse(rws*cols,rws*cols);
T = sparse(rws*cols,2);
border_grid = 0;
border_template = 0;
template_comp = 0;
grid_comp = 0;
for i = 1:cols
for j = 1:rws
if(ind(j,i)==255)
Asr=grid(j,i,1);
Bsr=template(((j-posy)+1),((i-posx)+1),1);
Snorm= ((Asr-Bsr)^2)^(1/2);
if (( (j+1) > 0) && ((j+1) <= rws))
if ( ind(j+1,i)==0)
T((i-1)*rws+j,1)=100000;
border_grid=border_grid+1;
end
if ( ind(j+1,i)==128)
border_template=border_template+1;
T((i-1)*rws+j,2)=100000;
end
if( (ind(j+1,i)==255))
Atr=grid(j+1,i,1);
Btr=template(((j+1)-posy)+1,(i-posx)+1,1);
Tnorm= ((Atr-Btr)^2)^(1/2);
A((i-1)*rws+j,(i-1)*rws+(j+1))=Snorm+Tnorm;
end
end
end;
**+ some other similar if-loops**
end
end