Char array to numeric array in matlab - matlab

I have the following matrix A of size 3x2:
A = [12; 34; 56];
But the data is stored as chars. I want to convert it to the numeric array. str2num doesn't. Is there another method to do that?

Well, your array doesn't look like a 3-by-2 array. In any case, you are looking for a casting function:
A = double(A);
should convert your chars in double.

If I understand correctly, you have
A = ['12'; '34'; '56']; %// strings
and want to get
B = [1 2; 3 4; 5 6]; %// numbers
This could be done as follows: convert A to double to produce each character's ASCII code, and then subtract the code of character '0' to obtain the desired numbers. In fact, conversion to double is done implicitly when you subtract chars, so you can just use
B = A-'0';

Related

Adding each element in a vector yields no number

I have a vector,
a2 = [8 10 18 18]
I want to add all individual digits in this vector, i.e.
8 + 1+0 + 1+8 + 1+8 = 27
I decided to use the following piece of code:
a3 = num2str(a2)
sum2 = 0;
for k = 1:numel(a3)
sum2 = sum2 + str2num(a3(k));
end
sum2
However, when I output this I get sum2 = []. What exactly is going wrong here? Apparently, a3 has 13 elements, which means the spaces must be 2 elements wide. Does the issue lie there?
Recommended Solution:
Use num2str, cellstr, str2double, and sum with the omitnan flag.
req = num2str(a2);
req = sum(str2double(cellstr(req(:))),'omitnan');
num2str converts the given matrix a2 into a character array. req(:) reshapes the character array req into a column vector. It still contains spaces. cellstr is applied to convert the column character array into a cell array so that str2double can be applied. str2double converts the spaces into NaN and the char numbers into respective doubles. sum with the omitnan flag ignores the NaN while addition.
Just another Solution:
It can also be done using just num2str, str2num, and sum. But str2num uses eval and hence it should be avoided. Anyhow just for the fun of it:
req = num2str(a2);
req = sum(str2num(req(:)));
Just like the previous solution, when str2num is applied on the column character array containing spaces, spaces get removed and the remaining char numbers are converted into respective doubles. The operation of the sum function is obvious.
Why does your code not work?
When str2num is applied on the space character, [] is returned. When [] is added into any number, the result is also []. Since in your code a3 contains spaces, hence you get [] as output.
You can exploit the ASCII mapping:
b = uint64(num2str(a2') - '0')
b =
4×2 uint64 matrix
0 8
1 0
1 8
1 8
and then sum:
sum(b(:))
ans =
27
Just for fun, a shorter, faster, less robust and less readable solution:
sum2 = sum(sprintf('%d',a2)-'0');
Breakdown:
sprintf to convert all elements of a2 to a string without space as delimiter, like num2str would do
subtracting '0' implicitly casts the character array to the ASCII code equivalents. Subtracting the ASCII value for 0 then results in numbers 0-10
sum() to complete the operation.
Note that if a2 was a string to begin with, this solution will not give an error (same for the other answer, by the way)

How to perform XOR in a recursive scenario

I have a 1x5 char matrix. I need to perform a bitwise XOR operation on all the elements in the matrix.If T is the char matrix , I need a matrix T' such that
T'= T XOR (T-1)' for all T
T for T=1
Let the char matrix be T
T=['0000000000110111' '0000000001000001' '0000000001001010' '0000000010111000' '0000000000101111']
T'=['0000000000110111' '0000000001110110' '0000000000111100' '0000000010000100' '0000000010101011']
ie; Leaving the first element as such , I need to XOR all the other elements with the newly formed matrix. I tried the following code but I'm unable to get the correct result.
Yxor1d = [T(1) cellfun(#(a,b) char((a ~= b) + '0'), T(2:end), T'(1:end-1), 'UniformOutput', false)]
I need to perform the XOR operation such that , for obtaining the elements of T'
T' (2)= T(2) XOR T' (1)
T' (3)= T(3) XOR T' (2)
It'll be really helpful to know where I went wrong.Thanks.
You are using cellfun when a cell array is expected as the input. You are using a character array, and what you're actually doing is taking each of those 5 strings and creating a single character array out of them. Chaining those strings together is actually performing a character concatenation.
You probably don't want that. To fix this, all you have to do is make T a cell array by placing {} characters instead of array ([]) characters to declare your characters:
T={'0000000000110111' '0000000001000001' '0000000001001010' '0000000010111000' '0000000000101111'};
Because you have edited your post after I provided my answer, my previous answer using cellfun is now incorrect. Because you are using a recurrence relation where you are referring to the previous output rather than input, you can no longer use cellfun. You'll need to use a for loop. There are probably more elegant ways to do it, but this is the easiest if you want to get something working.
As such, initialize an output cell array that is the same size as the input cell array like above, then you'll need to initialize the first cell to be the first cell of the input, then iterate through each pair of input and output elements yourself.
So do something like this:
Yxor1d = cell(1,numel(T));
Yxor1d{1} = T{1};
for idx = 2 : numel(T)
Yxor1d{idx} = char(double(T{idx} ~= Yxor1d{idx-1}) + '0');
end
For each value i of T', we XOR with the current input at T{i} with the previous output of T'{i-1}.
Use the above and your input cell array T, we get:
Yxor1d =
Columns 1 through 3
'0000000000110111' '0000000001110110' '0000000000111100'
Columns 4 through 5
'0000000010000100' '0000000010101011'
This matches with your specifications in your modified post.
Edit: There is a solution without a loop:
T=['0000000000110111';'0000000001000001';'0000000001001010';'0000000010111000' ;'0000000000101111'];
Yxor = dec2bin(bi2de(mod(cumsum(de2bi(bin2dec(T))),2)),16)
Yxor =
0000000000110111
0000000001110110
0000000000111100
0000000010000100
0000000010101011
This uses the fact that you effectively want a cumulative xor operation on the elements of your array.
For N booleans it should be either any one of them or else all of them. So if you do a cumulative sum of each of your bits, the sum should be an odd number for a true answer to 'xor'.
The one liner above can be decomposed like that:
Y = bin2dec(T) ; %// convert char array T into decimal numbers
Y = de2bi( Y ) ; %// convert decimal array Tbin into array of "bit"
Y = cumsum(Y) ; %// do the cumulative sum on each bit column
Y = mod(Y,2) ; %// convert all "even" numbers to '0', and 'odd' numbers to '1'
Y = bi2de(Y) ; %// re-assemble the bits into decimal numbers
Yxor = dec2bin(Y,16) ; %// get their string representation
Note that if you are happy to handle arrays of bits (boolean) instead of character arrays, you can shave off a few lines from above ;-)
Initial answer (simpler to grasp, but with a loop):
You can use the bitxor function, but you have to convert your char array in numeric value first:
T=['0000000000110111';'0000000001000001';'0000000001001010' ;'0000000010111000' ;'0000000000101111'];
Tbin = bin2dec(T) ; %// convert to numeric values
Ybin = Tbin ; %// pre-assign result, then loop ...
for idx = 2 : numel(Tbin)
Ybin(idx) = bitxor( Ybin(idx) , Ybin(idx-1) ) ;
end
Ychar = dec2bin(Ybin,16) %// convert back to 16bit char array representation if necessary
Ychar =
0000000000110111
0000000001110110
0000000000111100
0000000010000100
0000000010101011
edited answer after you redefined your problem

Combine matrix elements into a hexadecimal number on Matlab

For example I have a matrix command = ['01';'03';'0B';'00';'00';'02';'C6';'2F']. I want to combine its elements in a hexadecimal number 01030C000002C62F. I have tried a lot of different methods but haven't figured it out.
So, this is a char array:
A = ['01';'03';'0B';'00';'00';'02';'C6';'2F'];
Convert it to cell, then to string:
B = strjoin(cellstr(A))
01030B000002C62F
Now convert from hexadecimal to decimal:
hex2dec(B)
ans =
7.2914e+16

Convert an array of strings to a vector of numbers

I have this:
d = {'2.5', '3.5'};
d =
'2.5' '3.5'
How do I convert it to a vector of numbers?
d = 2.5 3.5
Given that you have a cell array of string values, you can use cellfun to apply str2num conversion on each entry. The output will be a vector/matrix of the converted values.
d = {'2.3','3.5'}
dVec = cellfun(#str2num, d);
However, you are better using str2double than str2num. From the documentation:
Note: str2num uses the eval function to convert the input argument.
Side effects can occur if the string contains calls to functions.
Using str2double can avoid some of these side effects.
dVec = cellfun(#str2double, d);
Update: As #yuk points out, you can call str2double() directly on the cell array for the same output.
dVec = str2double(d);
Note that the same call with str2num() will give the "must be a string or string array" error.

Matlab binary encoding

I have a vector containing a series of integers, and what I want to do is take all numbers, convert them into their corresponding binary forms, and concatenate all of the resulting binary values together. Is there any easy way to do this?
e.g. a=[1 2 3 4] --> b=[00000001 00000010 00000011 00000100] --> c=00000001000000100000001100000100
Try:
b = dec2bin(a)
As pointed out by the other answers, the function DEC2BIN is one option that you have to solve this problem. However, as pointed out by this other SO question, it can be a very slow option when converting a large number of values.
For a faster solution, you can instead use the function BITGET as follows:
a = [1 2 3 4]; %# Your array of values
nBits = 8; %# The number of bits to get for each value
nValues = numel(a); %# The number of values in a
c = zeros(1,nValues*nBits); %# Initialize c to an array of zeroes
for iBit = 1:nBits %# Loop over the bits
c(iBit:nBits:end) = bitget(a,nBits-iBit+1); %# Get the bit values
end
The result c will be an array of zeroes and ones. If you want to turn this into a character string, you can use the function CHAR as follows:
c = char(c+48);
Yes, use dec2bin, followed by string concatenation.