create a new matrix from values obtained iterating through other matricies - matlab

In Matlab I have 4 matricies which are all 1(row) by 4(coloumns) (ABDC, EFGH, IJKL, MNOP)
Their names are also stored in a list
Stock_List2 = {'ABCD' 'EFGH' 'IJKL' 'MNOP'} and is a 1 by 4 cell.
I want to iterate through the list and create a new matrix called "display" which takes the values of the indvidual matricies and places them underneath each other)
I am trying something like
for e = 1:length(Stock_List2)
display(e) = eval(strcat(Stock_List2)(e))
end
Error: ()-indexing must appear last in an index expression.
However getting the following error expression which truthfully may well just be that I'm way off the mark.
As an example if the orginal matricies are as follows:
ABCD 1 2 3 4
DEFG 5 6 7 8
HIJK 9 8 7 6
LMNO 5 4 3 2
I would like the final output ie the 'display matrix to be a 4 by 4 matrix looking like
display
1 2 3 4
5 6 7 8
9 8 7 6
5 4 3 2

If I understood right you want to concatenate vertically the matrices ABDC, EFGH, IJKL and MNOP saving them in the matrix "display".
You could do:
display = [ABDC; EFGH; IJKL; MNOP]
or:
for i=1:length(Stock_List2)
display(i,:) = Stock_List2{i}
end

Apologies if what I wanted wasnt clear - I've got the following from a colleague which achieves the desired result
for e=1:length(Stock_List2)
eval(strcat('display_mat(e,:) = ',Stock_List2{e}));
end

Related

How to unnest a cell array with nested data and text content if the row and column dimensions do not agree with each other in MATLAB Rb2020?

I have a (72x1 cell) which content is defined by the following block/section:
COLUMN1
ROW1 Text Nr.1
ROW2 2345x3 double
ROW3 Text Nr.2
....times 24 to get the mentioned 72x1 cell array
My goal now is to unnest the 2345x3 double contents in a way, that I obtain the following data order:
COLUMN1 COLUMN2 COLUMN3
Text Nr.1 (empty) (empty)
value 1 value 1 value 1
value 2 value 2 value 2
value 3 value 3 value 3
value 4 value 4 value 4
value 5 value 5 value 5
value 6 value 6 value 6
value 7 value 7 value 7
etc. etc. etc.
Text Nr.2 (empty) (empty)
Text Nr.1 (empty) (empty)
value 1 value 1 value 1
value 2 value 2 value 2
value 3 value 3 value 3
value 4 value 4 value 4
value 5 value 5 value 5
value 6 value 6 value 6
value 7 value 7 value 7
etc. etc. etc.
Text Nr.2 (empty) (empty)
I would like to use a for loop for this, in case the amount of rows changes. However I am uncertain how to approach this problem even? (reshape, cellfun?)
That why I would like to ask you if you have a code in mind?
Note: I need this data structure for a macro which generates geometrical structures in CAD programms
You can use something like this:
x={'lorem';[1 2 3;4 5 6;7 8 9;2344*3+1 2344*3+2 2344*3+3];'ipsum'; ...
'dolor';-[1 2 3;4 5 6;7 8 9;2344*3+1 2344*3+2 2344*3+3];'sit amet'};
m={};
for i=1:floor(numel(x)/3) %ignore trailing garbage (incomplete entry)
k=x{3*(i-1)+2};
m=[ m ; ...
x(3*(i-1)+1) cell([1 size(k,2)-1]) ; ...
mat2cell( k, ones([size(k,1) 1]), ones([size(k,2) 1]) ) ; ...
x(3*(i-1)+3) cell([1 size(k,2)-1]) ];
end
Since the for-loop only performs 24 iterations in your use case, I believe this approach should be fairly efficient.

How is this MATLAB code (involving colon operator) resolved?

Recently, I wanted to calculate the next multiple of 5 of several values.
I was very confused by the output of this code, which should have done the trick:
7:11 - mod(7:11, 5) + 5
ans =
7 8 9 10 11 12 13 14
While the actual working solution was this:
(7:11) - mod(7:11, 5) + 5
ans =
10 10 10 15 15
So this seems to be related to operator precedence! But what exactly does the first command do, and why does it output a (1,8) vector?
Addendum: I have found that the first command can also be written as:
7:(11 - mod(7:11, 5) + 5)
Which already hints towards the explanation of the observed result, but I am still curious about the whole explanation.
Here's the list of MATLAB operator precedence
As you can see, parentheses, (), are solved first, meaning that mod(7:11,5) will be done first. Then point 6), the addition and subtraction are taken care of from left to right, i.e. 11-mod(7:11,5) and then 11-mod(7:11,5)+5. Then point 7), the colon, :, gets evaluated, thus 7:11-mod(7:11,5)+5.
As you noted correctly 7:11 - mod(7:11, 5) + 5 is the same as 7:(11 - mod(7:11, 5) + 5), as seen above using operator precedence.
Now to the second part: why do you obtain 8 values, rather than 5? The problem here is "making an array with an array". Basically:
1:3
ans =
1 2 3
1:(3:5)
ans =
1 2 3
This shows what's going on. If you initialise an array with the colon, but have the end point as an array, MATLAB uses only the first value. As odd as it may sound, it's documented behaviour.
mod(7:11,5) generates an array, [2 3 4 0 1]. This array is then subtracted from 11 and 5 is added [14 13 12 16 15]. Now, as we see in the documentation, only the first element is then considered. 7:[14 13 12 16 15] gets parsed as 7:14 and will result in 8 values, as you've shown.
Doing (7:11) - mod(7:11, 5) + 5 first creates two arrays: 7:11 and mod(7:11,5). It then subtracts the two arrays elementwise and adds 5 to each of the elements. Interesting to note here would be that 7:12 - mod(7:11, 5) + 5 would work, whereas (7:12) - mod(7:11, 5) + 5 would result in an error due to incompatible array sizes.

Splitting a list of strings using cut - KDB

For the following list:
q)a:("ua#1100#1";"sba#2220#2";"r#4444#a")
I want following output :
("1100#1";"2220#2";"4444#a")
? gives first index of #
q)(a?\:"#")
2 3 1`
but using cut does not give the desired result :
q)(a?\:"#")cut'a
(("ua";"#1";"10";"0#";"1");("sba";"#22";"20#";"2");("r";"#";"4";"4";"4";"4";"#";"a"))`
You can also parse the data rather than drop chars from each string.
It'll be somewhat more efficient if your dataset is large.
q)("J#*"0:/:a)[;1]
"1100#1"
"2220#2"
"4444#a"
Notice I've set the 'key' to 'J' which will result in nulls in your example case, but you only care about the values anyway.
If you can join (sv) the strings together, it'll be even better too
q)last "J#;"0:";" sv a
"1100#1"
"2220#2"
"4444#a"
HTH,
Sean
When the left argument of cut is atom , cut behaves differently than _.
q)2 cut 2 3 4 5 6
(2 3;4 5;,6)
q)2 _ 2 3 4 5 6
4 5 6
Use _ to cut the string
q)(1+a?\:"#")_'a
("1100#1";"2220#2";"4444#a")
or
q)"#"sv/:1_/:"#" vs/:a
("1100#1";"2220#2";"4444#a")

Problems Using Textscan to Read Multiple Lines

I'm a bit new to data import using Matlab.
Basically, I have an Ascii file. It has 13 Header Lines, along with 765 columns and ~3500 rows of data. I am attempting to import the data into a 3500 x 765 matrix in Matlab. I've tried the following:
fileID = fopen('filename');
formatspec = [repmat('%f ', [1,765])];
raw_data=textscan(fileID,formatspec, 'Headerlines',13,'delimiter','\t');
It successfully skips the 13 header lines. However, it only gives me a 1 x 765 matrix containing only the data from the first row.
Perhaps I have misunderstood just how I am supposed to use textscan, so any help in getting my other ~3499 rows of data would be very well appreciated.
~Thank You
NOTE
The Data File itself is formatted as follows. The First 13 lines do not contain the data itself. All lines following that contain sets of data similar to what will be pasted below, extending for 700+ columns and 3000+ rows.
Wyko ASCII Data File Format 0 1 1
X Size 3571
Y Size 765
Block Name Type Length Value
Wavelength 7 4 72.482628
Aspect 7 4 1
Pixel_size 7 4 0.00196
StageY 7 4 -0.048055
Magnification 8 8 5.05
StageX 7 4 0.214484
ScannerPosition 7 4 3490.000732
ScannerSpeed 7 4 3.165393
RAW_DATA 3 10927260
-10976.61035 -10977.07324 -10981.07422 -10985.6084 ...
-10967.41309 -10963.31836 -10966.75195 -10980.40723 ...
-10969.08496 -10976.03711 -10976.62988 -10964.23731 ...
-10974.12695 -10976.61133 -10979.2627 -10973.57813 ...
-10969.21094 -10966.56543 -10973.74512 -10983.41797 ...
-10970.18359 -10980.82715 -10968.00195 -10975.58594 ...
-10980.41016 -10982.39356 -10982.74316 -10974.51563 ...
-10972.31641 -10984.00488 -10987.89453 -10976.23633 ...
I think the following should work, but I don't have Matlab on this machine to test it out.
fileID = fopen('filename');
formatspec = [repmat('%f ', [1,765])];
raw_data = new_data = textscan(fileID,formatspec, 'Headerlines',13,'delimiter','\t');
while ~feof(fileID)
new_data = textscan(fileID,formatspec,'delimiter','\t');
raw_data = [raw_data; new_data];
end
fclose(fileID);
Note that this is not a particularly efficient way to do it. If your header lines give you the size of your array, you may want to use zeros to create an array of the appropriate size and then read the data into your array.

Matlab, how to convert a string of integers into a vector? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
convert string to number array in matlab
Is there a simple way in Matlab to convert a string like this
'123456789'
into a vector like this ?
[1 2 3 4 5 6 7 8 9]
If all you have is contiguous characters from 0 to 9:
v = double(s)-'0';
double(s) converts a string into an array where each element is the ASCII code of the corresponding character. To obtain the numberic values we subtract '0' (which is in fact 48 in ASCII) and since digits have a sequential representation in ASCII code ('1' = 49, '2' = 50, etc.) we end up with intended result.
one way would be using regexp for this. But of course it only works for single digit numbers.
>> str = '123456789';
>> num = regexp(str,'\d')
num =
1 2 3 4 5 6 7 8 9