matlab: Adding square brackets to all individual numerical values within cell arrays - matlab

I wish to add a cell array (Ma) into another cell array. However both needs to be of the same format (individual cells in square brackets).
For instance I have an array..
Ma{1,:}.'
ans =
Columns 1 through 8
'83.6' '85.2' '91' '87.9' '91.8' '86.3' '90.6' '90.2'
How do i add square brackets to all the numerical values of very individual cells?
Below is what i wish to obtain, it is also a 1x8 cell.
ans =[83.6] [85.2] [91] [87.9] [91.8] [86.3] [90.6] [90.2]

Your cell values are strings (you can tell by the quote marks ' surrounding the values). You wish to convert them to numerical values ("add square brrckets around them" as you put it).
To convert string to double you can use str2double command:
M = str2double( M{1,:} );

You don't need to add the square brackets yourself. This just means that it is a numerical value in a cell.
In order to achieve this you should do the following, using both the num2cell as str2double functions:
newM = num2cell(str2double(Ma{1,:}))

Related

How to split cell array values into two columns in MATLAB?

I have data in a cell array as shown in the variable viewer here:
{[2.13949546690144;56.9515770543056],
[1.98550875192835;50.4110852121618],
...}
I want to split it into two columns with two decimal-point numbers as:
2.13 56.95
1.98 50.41
by removing opening and closing braces and semicolons such as [;]
(to do as like "Text to columns" in Excel).
If your N-element cell array C has 2-by-1 numeric data in each cell, you can easily convert that into an N-by-2 numeric matrix M like so (using the round function to round each element to 2 significant digits):
M = round([C{:}].', 2);
The syntax C{:} creates a comma-separated list of the contents of C, equivalent to C{1}, C{2}, ... C{N}. These are all horizontally concatenated using [ ... ], then the result is transposed using .'.
% let's build a matching example...
c = cell(2,1);
c{1} = [2.13949546690144; 56.9515770543056];
c{2} = [1.98550875192835; 50.4110852121618];
% convert your cell array to a double array...
m = cell2mat(c);
% take the odd rows and place them to the left
% take the even rows and place them to the right
m = [m(1:2:end,:) m(2:2:end,:)];
% round the whole matrix to two decimal digits
m = round(m,2);
Depending on your environment settings, you may still see a lot of trailing zeros after the first two decimal digits... but don't worry, everything is ok (on the precision point of view). If you want to display only the "real" digits of your numbers, use this command:
format short g;
you should use cell2mat
A={2.14,1.99;56.95,50.41};
B=cell2mat(A);
As for the rounding, you can do:
B=round(100*B)/100;

Concatenate symbol with cell array values in Matlab

I have a cell of double {52x1}, I would like to concatenate to each element the symbol ±.
The problem I am having is that sprintf doesn't support the Matlab code \pm for calling the symbol.
Any help is welcome!
\pm is a TeX/LaTeX command, which gives ± only if the interpreter used by Matlab understands LaTex. This occurs for example in axis labels when the TickLabelInterpreter property is set to 'tex'.
In sprintf you can directly use the ± symbol (code point 177). For example,
x = num2cell(rand(5,1)); % cell array of numbers
sprintf('±%f\n', [x{:}])
or
sprintf([177 '%f\n'], [x{:}])
gives
ans =
±0.126987
±0.913376
±0.632359
±0.097540
±0.278498
Note that I had to transform the cell array of numbers to a numeric vector in order to pass it to sprintf. Consider defining the data directly as a numeric vector to avoid that step.
If you want a cell array of strings as result:
cellfun(#(t) sprintf([177 '%f\n'], t), x, 'UniformOutput', false)

Allow non-numeric entries in matrix in MATLAB

I wrote a code that replaces non-numeric values in the matrix by some number.
Now, to test it I would like to allow MATLAB to accept non-numeric entries.
My code starts with prompt:
matrix_input = input('Please enter the matrix: x=');
If I enter something like [1,2,3;4,5,?], MATLAB gives an error: Unbalanced or unexpected parenthesis or bracket. Since all brackets seem to be balanced, I assume this is due to non-numeric entry. Is it possible to make MATLAB allow non-numeric entries?
You need a cell array. Each cell of a cell array can hold any type of data. Curly braces are used to create a cell array like this:
cell_array = {1, 2, 3; '4', '?', 6};
If you use regular braces to access an element in a cell array you get a cell. If you use curly braces you get the contents of the cell. It's this difference that tends to catch people out with cell arrays.
cell_array(1) % Returns a 1x1 cell containing the value 1.
cell_array{1} % Returns 1
EDIT
Out of curiosity, what code are you using to replace the non-numeric values? For a cell array I came up wit the following:
idx = cellfun(#isnumeric, cell_array);
cell_array(~idx) = {NaN};
matrix = cell2mat(cell_array);
As mentioned in the comments, you could also use a struct array:
struct_array = struct('v', {1, 2, 3; '4', '?', 6});
This would create an array of structures where the field v contains the value. However, I can't think of a neat way to perform the replacement at the minute.

How to compare two cell elements in matlab?

I am using two cells for storing the targeted and the expected value of a neural network process in matlab. I have used two 1*1 cell array for storing the values respectively. And here is my code.
cinfo=cell(1,2)
cinfo(1,1)=iter(1,10)%value is retrieved from a dataset iter
cinfo(1,2)=iter(1,11)
amp1=cinfo(1,1);
amp2=cinfo(1,2);
if amp1 == amp2
message=sprintf('NOT DETECTED BY THE DISEASE');
uiwait(msgbox(message));
But when i run the above code, the get the following error :
??? Undefined function or method 'eq' for input arguments of type 'cell'.
Error in ==> comparison at line 38
if amp1 == amp2
How to solve this problem?
The problem is how you indexed things. A 1x1 cell array does not make a lot of sense, instead get the actual element in the single cell, by indexing with curly brackets:
amp1=cinfo{1,1}; # get the actual element from the cell array, and not just a
amp2=cinfo{1,2}; # 1x1 cell array by indexing with {}
if (amp1 == amp2)
## etc...
However, note that if amp1 and amp2 are not scalars the above will act weird. Instead, do
if (all (amp1 == amp2))
## etc...
Use isequal. That will work even if the cell's contents have different sizes.
Example:
cinfo=cell(1,2);
cinfo(1,1) = {1:10}; %// store vector of 10 numbers in cell 1
cinfo(1,2) = {1:20}; %// store vector of 20 numbers in cell 2
amp1 = cinfo(1,1); %// single cell containing a length-10 numeric vector
amp2 = cinfo(1,2); %// single cell containing a length-20 numeric vector
if isequal(amp1,amp2)
%// ...
In this example, which parallels your code, amp1 and amp2 are cell arrays consisting of a single cell which contains a numeric vector. Another possibility is to directly store each cell's contents into amp1, amp2, and then compare them:
amp1 = cinfo{1,1}; %// length-10 numeric vector
amp2 = cinfo{1,2}; %// length-20 numeric vector
if isequal(amp1,amp2)
%// ...
Note that even in this case, the comparisons amp1==amp1 or all(amp1==amp2) would give an error, because the vectors have different sizes.

Substrings from a Cell Array in Matlab

I'm new to MATLAB and I'm struggling to comprehend the subtleties between array-wise and element wise operations. I'm working with a large dataset and I've found the simplest methods aren't always the fastest. I have a very large Cell Array of strings, like in this simplified example:
% A vertical array of same-length strings
CellArrayOfStrings = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'};
I'm trying to extract an array of substrings, for example:
'a1'
'b1'
'c1'
'd1'
I'm happy enough with an element-wise reference like this:
% Simple element-wise substring operation
MySubString = CellArrayOfStrings{2}(3:4); % Expected result is 'b1'
But I can't work out the notation to reference them all in one go, like this:
% Desired result is 'a1','b1','c1','d1'
MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!
I know that Matlab is capable of performing very fast array-wise operations, such as strcat, so I was hoping for a technique that works at a similar speed:
% An array-wise operation which works quickly
tic
speedTest = strcat(CellArrayOfStrings,'hello');
toc % About 2 seconds on my machine with >500K array elements
All the for loops and functions which use behind-the-scenes iteration I have tried run too slowly with my dataset. Is there some array-wise notation that would do this? Would somebody be able to correct my understanding of element-wise and array-wise operations?! Many thanks!
I can't work out the notation to reference them all in one go, like this:
MyArrayOfSubStrings = CellArrayOfStrings{:}(3:4); % Incorrect notation!
This is because curly braces ({}) return a comma-separated list, which is equivalent to writing the contents of these cells in the following way:
c{1}, c{2}, and so on....
When the subscript index refers to only one element, MATLAB's syntax allows to use parentheses (()) after the curly braces and further extract a sub-array (a substring in your case). However, this syntax is prohibited when the comma separated lists contains multiple items.
So what are the alternatives?
Use a for loop:
MyArrayOfSubStrings = char(zeros(numel(CellArrayOfStrings), 2));
for k = 1:size(MyArrayOfSubStrings, 1)
MyArrayOfSubStrings(k, :) = CellArrayOfStrings{k}(3:4);
end
Use cellfun (a slight variant of Dang Khoa's answer):
MyArrayOfSubStrings = cellfun(#(x){x(3:4)}, CellArrayOfStrings);
MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
If your original cell array contains strings of a fixed length, you can follow Dan's suggestion and convert the cell array into an array of strings (a matrix of characters), reshape it and extract the desired columns:
MyArrayOfSubStrings =vertcat(CellArrayOfStrings{:});
MyArrayOfSubStrings = MyArrayOfSubStrings(:, 3:4);
Employ more complicated methods, such as regular expressions:
MyArrayOfSubStrings = regexprep(CellArrayOfStrings, '^..(..).*', '$1');
MyArrayOfSubStrings = vertcat(MyArrayOfSubStrings{:});
There are plenty solutions to pick from, just pick the one that fits you most :) I think that with MATLAB's JIT acceleration, a simple loop would be sufficient in most cases.
Also note that in all my suggestions the obtained cell array of substrings cell is converted into an array of strings (a matrix). This is just for the sake of the example; obviously you can keep the substrings stored in a cell array, should you decide so.
cellfun operates on every element of a cell array, so you could do something like this:
>> CellArrayOfStrings = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'};
>> MyArrayofSubstrings = cellfun(#(str) str(3:4), CellArrayOfStrings, 'UniformOutput', false)
MyArrayofSubstrings =
'a1'
'b1'
'c1'
'd1'
If you wanted a matrix of strings instead of a cell array whose elements are the strings, use char on MyArrayOfSubstrings. Note that this is only allowed when each string is the same length.
You can do this:
C = {'aaa123'; 'bbb123'; 'ccc123'; 'ddd123'}
t = reshape([C{:}], 6, [])'
t(:, 3:4)
But only if your strings are all of equal length I'm afraid.
You can use char to convert them to a character array, do the indexing and convert it back to cell array
A = char(CellArrayOfStrings);
B = cellstr(A(:,3:4));
Note that if strings are of different lengths, char pads them with spaces at the end to create the array. Therefore if you index for a column that is beyond the length of one of the short strings you may receive some space characters.