How to write a string in replace of a number in MATLAB? - matlab

I am trying to categorise the years based on some conditions. If any year has rainfall less than a specific number it will indicate as a dry year. I have tried the following, but it gives me error "In an assignment A(I) = B, the number of elements in B and I must be the same."
The code is
Year_Category = zeros(ny,1);
for i = 1:ny;
if (xy(i)< Lower_Limit)
Year_Category(i) = 'Dry';
elseif (xy(i)> Upper_Limit)
Year_Category(i) = 'Wet';
else
Year_Category(i) = 'Average';
end
end
Any help would be appreciated.
Best regards

You are trying to assign characters to a numeric array. That's why you're getting a dimension mismatch. Each character is a single slot and you can't do that in this case. Use cell arrays instead:
Year_Category = cell(ny,1); %// Change
for i = 1:ny;
if (xy(i)< Lower_Limit)
Year_Category{i} = 'Dry'; %// Change
elseif (xy(i)> Upper_Limit)
Year_Category{i} = 'Wet'; %// Change
else
Year_Category{i} = 'Average'; %// Change
end
end

Related

Not sure what to do about error message "Conversion to double from cell is not possible."

I'm writing a program that finds the indices of a matrix G where there is only a single 1 for either a column index or a row index and removes any found index if it has a 1 for both the column and row index. Then I want to take these indices and use them as indices in an array U, which is where the trouble comes. The indices do not seem to be stored as integers and I'm not sure what they are being stored as or why. I'm quite new to Matlab (but thats probably obvious) and so I don't really understand how types work for Matlab or how they're assigned. So I'm not sure why I',m getting the error message mentioned in the title and I'm not sure what to do about it. Any assistance you can provide would be greatly appreciated.
I forgot to mention this before but G is a matrix that only contains 1s or 0s and U is an array of strings (i think what would be called a cell?)
function A = ISClinks(U, G)
B = [];
[rownum,colnum] = size(G);
j = 1;
for i=1:colnum
s = sum(G(:,i));
if s == 1
B(j,:) = i;
j = j + 1;
end
end
for i=1:rownum
s = sum(G(i,:));
if s == 1
if ismember(i, B)
B(B == i) = [];
else
B(j,:) = i;
j = j+1;
end
end
end
A = [];
for i=1:size(B,1)
s = B(i,:);
A(i,:) = U(s,:);
end
end
This is the problem code, but I'm not sure what's wrong with it.
A = [];
for i=1:size(B,1)
s = B(i,:);
A(i,:) = U(s,:);
end
Your program seems to be structured as though it had been written in a language like C. In MATLAB, you can usually substitute specialized functions (e.g. any() ) for low-level loops in many cases. Your function could be written more efficiently as:
function A = ISClinks(U, G)
% Find columns and rows that are set in the input
active_columns=any(G,1);
active_rows=any(G,2).';
% (Optional) Prevent columns and rows with same index from being simultaneously set
%exclusive_active_columns = active_columns & ~active_rows; %not needed; this line is only for illustrative purposes
%exclusive_active_rows = active_rows & ~active_columns; %same as above
% Merge column state vector and row state vector by XORing them
active_indices=xor(active_columns,active_rows);
% Select appropriate rows of matrix U
A=U(active_indices,:);
end
This function does not cause errors with the example input matrices I tested. If U is a cell array (e.g. U={'Lorem','ipsum'; 'dolor','sit'; 'amet','consectetur'}), then return value A will also be a cell array.

Extracting values from a function

I have a loop within a function that spits out values similar to:
E = 3,2,1,-1,-2
for
i = 1,2,3,4,5
I'm trying to extract the position where E becomes negative and then identify the step before it.
My attempt was something like
finalPos = find(i(E<0));
Firstly, it just doesn't seem right (my matlab syntax knowledge is poor as)
but secondly even if it did work it would tell me all positions where E is less than 0, where I only want to know the position before where E is no longer positive. i.e. E = 1, i = 3
Any help would be greatly appreciated!
Check the below:
E = [3,2,1,-1,-2] ;
idx = find(sign(E)==-1) % Get the sign and get index
idx = find(E<0) % Get by value
for i = 1:length(E)
if sign(E(i)) == -1
fprintf('E is Negative\n')
else
fprintf('E is Positive\n')
end
end
For last positive value
you can use a variable to store the last value
Example:-
E=[3,2,1,-1,-2]
finalpos=-1
for i = 1:5
if ( E<0)
finalpos=E(i-1);
break;
end
end
finalpos

Implement huffmandict() function in matlab using arrays

I would like to implement the huffmandict() function in Matlab. I have already written a code in which I create an array with all the probabilities. Each time I add the 2 last probabilities , I update my array by adding the new sum probability at the next row in the right place. I also have an array with the sums only. The problem is I don't know how to continue to assign '0' and '1'. Any idea?
This is my code:
function code_words = my_huffmandict_func(init_symbols,probs)
my_symbol_array = [];
my_symbol_array = init_symbols;
my_probs = [];
my_probs = probs;
if length(my_symbol_array)~=length(my_probs)
error('Number of symbols and number of probabilities are not the same.');
end
for i=1:length(my_probs) %sorting the probabilities in descending order and
change the sequence of the symbols
for j=1:length(my_probs)
if (my_probs(i)> my_probs(j))
temp1=my_probs(i);
temp2=my_symbol_array(i);
my_probs(i)= my_probs(j);
my_symbol_array(i)= my_symbol_array(j);
my_probs(j)= temp1;
my_symbol_array(j)= temp2;
end
end
end
my_sum_array = [];
k=1;
init_lengthpr = length(my_probs);
all_occured_probs = [];
all_occured_probs(1,:) = my_probs;
while length(my_probs)>2 %we need this while loop as long as there are more
than 2 symbols left
my_temp_sum = my_probs(length(my_probs)) + my_probs(length(my_probs-1)); %we add the the possibilities of the two less possible outputs
my_sum_array = [my_sum_array,my_temp_sum]; %in this array we keep all the sums that occured
my_probs = [my_probs(1:length(my_probs)-2), my_temp_sum];%we update the possibilities' array
my_probs = sort(my_probs,'descend'); %we sort the array again
k=k+1;
all_occured_probs(k,:) = [my_probs,zeros(1,init_lengthpr-length(my_probs))];
end
end

matlab vectorization if statement

Can someone please tell me the vectorized implementation of following matlab code. Predicted is an array containing either of the two values "pos" or "neg". I have to copy the values when condition comes true.
p = 1;
box = zeros(size(bbox));
for k = 1: size(predicted)
if predicted(k) == 'pos'
box(p,:) = bbox(k,:);
p = p + 1;
end
end
bbox=rand(100); %demo data
predicted = rand(1,100)>0.5; %logical values
%You want to convert your array of strings into an array of logical values
%predicted=strcmp(predicted,'pos');
box=bbox(predicted,:);

MATLAB: Creating a matrix from for loop values?

I have the following code:
for i = 1450:9740:89910
n = i+495;
range = ['B',num2str(i),':','H',num2str(n)];
iter = xlsread('BrokenDisplacements.xlsx' , range);
displ = iter;
displ = [displ; iter];
end
Which takes values from an Excel file from a number of ranges I want and outputs them as matricies. However, this code just uses the final value of displ and creates the total matrix from there. I would like to total these outputs (displ) into one large matrix saving values along the way, how would I go about doing this?
Since you know the size of the block of data you are reading, you can make your code much more efficient as follows:
firstVals = 1450:9740:89910;
displ = zeros((firstVals(end) - firstVals(1) + 1 + 496), 7);
for ii = firstVals
n = ii + 495;
range = sprintf('B%d:H%d', ii, ii+495);
displ((ii:ii+495)-firstVals(1)+1,:) = xlsread('BrokenDiplacements.xlsx', range);
end
Couple of points:
I prefer not to use i as a variable since it is built in as sqrt(-1) - if you later execute code that assumes that to be true, you're in trouble
I am not assuming that the last value of ii is 89910 - by first assigning the value to a vector, then finding the last value in the vector, I sidestep that question
I assign all space in iter at once - otherwise, as it grows, Matlab keeps having to move the array around which can slow things down a lot
I used sprintf to generate the string representing the range - I think it's more readable but it's a question of style
I assign the return value of xlsread directly to a block in displ that is the right size
I hope this helps.
How about this:
displ=[];
for i = 1450:9740:89910
n = i+495;
range = ['B',num2str(i),':','H',num2str(n)];
iter = xlsread('BrokenDisplacements.xlsx' , range);
displ = [displ; iter];
end