Concatenate equivalent in MATLAB for a single value - matlab

I am trying to use MATLAB in order to generate a variable whose elements are either 0 or 1. I want to define this variable using some kind of concatenation (equivalent of Java string append) so that I can add as many 0's and 1's according to some upper limit.
I can only think of using a for loop to append values to an existing variable. Something like
variable=1;
for i=1:N
if ( i%2==0)
variable = variable.append('0')
else
variable = variable.append('1')
i=i+1;
end
Is there a better way to do this?

In MATLAB, you can almost always avoid a loop by treating arrays in a vectorized way.
The result of pseudo-code you provided can be obtained in a single line as:
variable = mod((1:N),2);
The above line generates a row vector [1,2,...,N] (with the code (1:N), use (1:N)' if you need a column vector) and the mod function (as most MATLAB functions) is applied to each element when it receives an array.

That's not valid Matlab code:
The % indicates the start of a comment, hence introducing a syntax error.
There is no append method (at least not for arrays).
Theres no need to increment the index in a for loop.
Aside of that it's a bad idea to have Matlab "grow" variables, as memory needs to be reallocated at each time, slowing it down considerably. The correct approach is:
variable=zeros(N,1);
for i=1:N
variable(i)=mod(i,2);
end
If you really do want to grow variables (some times it is inevitable) you can use this:
variable=[variable;1];
Use ; for appending rows, use , for appending columns (does the same as vertcat and horzcat). Use cat if you have more than 2 dimensions in your array.

Related

Why is the plot coming out empty for this Matlab code?

Code
clear;clc
T=800;
Pc=48.45;
Tc=375;
w=0.153;
R=82.06;
a=((0.45724)*(R^2)*(Tc^2))/Pc;
b=((0.07780)*R*Tc)/Pc;
B=(0.37464+(1.54226*w)-(0.26992*(w^2)));
Tr=T/Tc;
s=(1+(B*(1-sqrt(Tr))))^2;
for Vm=90:5:1000
P=((R*T)/(Vm-b))-((a*s)/((Vm)^2+(2*b*Vm)-b^2));
end
plot(Vm, P)
Problem
Every time I run this code, it comes out with a completely empty plot with just numbers on both axes as the image shown below. I've checked my code a few times, but I still can't find the problem, especially since the code runs with no errors. The result I am supposed to be getting on this plot is the behavior of P as the value of Vm increases.
The result of the code
Additional information about the source of the question
Here's the original question if you're interested (Exercise 1).
The original question (Exercise 1)
Try displaying your variables. You'll see Vm is not an array, rather it's a single-valued scalar. When you loop over Vm it takes one value at a time; it doesn't build an array.
MATLAB can do calculations on multiple values at once, so if you define Vm to be an array and drop the loop I'm guessing it'll work...
Try something like this (replace the for-loop with these lines):
Vm = 90:5:1000
P=((R*T)./(Vm-b))-((a*s)./((Vm).^2+(2*b.*Vm)-b^2));
P will then be an array. Notice we use .* rather than * when multiplying by the array Vm since we want to do element-wise multiplication, rather than matrix multiplication. Similarly we use ./ rather than / and .^ rather than ^.
EDIT: If you need to use a for-loop then you could define both P and Vm as arrays, and then work on each element separately within a loop:
Vm = 90:5:1000;
P = NaN(size(Vm));
for i=1:numel(Vm)
P(i)=((R*T)./(Vm(i)-b))-((a*s)./((Vm(i)).^2+(2*b.*Vm(i))-b^2));
end
Since the above is working on scalar values, it doesn't matter if you use .* or *...

How to do preallocation in storing field variables in matlab

I am storing the field variables calculated in a for loop in a vector by appending the values, However I would like to preallocate first for performance. I tried to vectorize this operation but it does not give me what I would like to accomplish. I have put the example of the operation below. How do I do the preallocation in this? For speed.
j=('load raw.mat');
var=fields(j);
val_mat=[];
kk=fieldnames(j);
for i=(length(kk)-Var_no)+1:Var_no+(length(kk)-Var_no)
val_mat=[val_mat j.(var{i})];
end
Based on your code it looks like you are trying to grab all variables stored in raw.mat and concatenate them. To do this, you can replace the loop with struct2cell to convert all field values to a cell array of values and then use cat to concatenate them
data = load('raw.mat');
values = struct2cell(data);
val_mat = cat(2, values{:});
Since we have removed the loop, there is no need to pre-allocate.
I've also taken the liberty to rewrite your code as valid MATLAB code.

Create a loop using part of variable name in MATLAB

I am a beginner in Matlab and have not been able to find an answer to my question so far. Your help will definitely be very much appreciated.
I have 70 matrices (100x100), named SUBJ_1, SUBJ_2 etc. I would like to create a loop so that I would calculate some metrics (i.e. max and min values) for each matrix, and save the output in a 70x2 result matrix (where each row would correspond to the consecutively named SUBJ_ matrix).
I am struggling with both stages - how to use the names of individual variables in a 'for' loop and how to properly save individual outputs in a combined array.
Many thanks and all the best!
Don't use such variable names, create a big cell array named SUBJ and put each Matrix in it.
r=zeros(numel(SUBJ),2)
for idx=1:numel(SUBJ)
r(idx,1)=min(min(SUBJ{idx}))
r(idx,2)=max(max(SUBJ{idx}))
end
min and max are called twice because first call creates maximum among rows, second call among columns.
Even though this is in principle possible in Matlab, I would not recommend it: too slow and cumbersome to implement.
You could instead use a 3-D matrix (100x100x70) SUBJ which would contain all the SUBJ_1 etc. in one matrix. This would allow you to calculate min/max etc. with just one line of code. Matlab will take care of the loops internally:
OUTPUT(:,1) = min(min(SUBJ,[],1)[],2);
OUTPUT(:,2) = max(max(SUBJ,[],1)[],2);
Like this, OUTPUT(1,1) contains min(min(SUBJ(:,:,1))) and so on...
As to how to use the names of individual variables in a 'for' loop, here gives an example:
SUBJ = [];
for idx = 1:70
term = eval(['SUBJ_',num2str(idx)]);
SUBJ = [SUBJ; max(max(term)),min(min(term))];
end

Matlab indexing within eval

I would like to change values within an dataset using eval. It shlould be in a way thet every second value is changed to the one before.
Short example:
A = magic(6)
ds = mat2dataset(A) % original dataset
ds.A1(2:2:end) = ds.A1(1:2:end) % dataset after change
That's the way I would like to do it. Now I need to use the variables letter and number which are assigned previous in the function.
letter = 'A'
number = '1'
eval([strcat('ds.', letter, number)]) % now gives me all values.
This is exactly the point where I would like to index the (1:2:end) to get just the indexed values.
Does one of you have a good idea how to index within the eval function? I would also prefer other ways of doing it if you have on.
Thanks a lot!
1) Don't use eval to achieve dynamic fieldnames:
h=ds.([letter, number])
2) Double indexing is not possible, you need two lines to achieve it.
h(1:2:end)

For loops in Matlab

I run through a for loop, each time extracting certain elements of an array, say element1, element2, etc. How do I then pool all of the elements I've extracted together so that I have a list of them?
John covered the basics of for loops, so...
Note that matlab code is often more efficient if you vectorize it instead of using loops (this is less true than it used to be). For example, if in your loop you're just grabbing the first value in every row of a matrix, instead of looping you can do:
yourValues = theMatrix(:,1)
Where the solo : operator indicates "every possible value for this index". If you're just starting out in matlab it is definitely worthwhile to read up on matrix indexing in matlab (among other topics).
Build the list as you go:
for i = 1:whatever
' pick out theValue
yourList(i) = theValue
end
I'm assuming that you pick out one element per loop iteration. If not, just maintain a counter and use that instead of i.
Also, I'm not assuming you're pulling out your elements from the same position in your array each time through the loop. If you're doing that, then look into Donnie's suggestion.
In MATLAB, you can always perform a loop operation. But the recommended "MATLAB" way is to avoid looping:
Suppose you want to get the subset of array items
destArray = [];
for k=1:numel(sourceArray)
if isGoodMatch(sourceArray(k))
destArray = [destArray, sourceArray(k)]; % This will create a warning about resizing
end
end
You perform the same task without looping:
matches = arrayfun(#(a) isGoodMatch(a), sourceArray); % returns a vector of bools
destArray = sourceArray(matches);