Can't store values into array MATLAB - arrays

I have a 1x280 structure in Matlab. In order for me to use the values, I changed it to struct2cell array.
An example of how one of the structures among the 280 looks is below :
Field Value Min Max
point1 [29,469] 29 469
point2 [42,469] 42 469
-------------------------------------------
After changing to a cell array using the below code:
showlines = struct(lines);
cellData = struct2cell(showlines);
cellData{1,1}(1)
= 29
However, if I use this :
cellData{1,1:280}(1);
There is an error
Error:: bad cell reference operation
I would need to keep all the x values of point1 in each of the 280 structures into an array so as to find out the maximum X value of point1 in them. Any idea how to do it?
Thank you very much in advance.

Although not a direct answer to your question, you might be interested to know that
%# some example data
S(1).point1 = [29 469];
S(1).point2 = [42 469];
S(2).point1 = [30 470];
S(2).point2 = [43 470];
...
S(280).point1 = [130 870];
S(280).point2 = [243 970];
%# transform to regular array
pt1 = reshape([S.point1],[],2).';
pt2 = reshape([S.point2],[],2).';
will result in
pt1 = [29 469 pt2 = [42 469
30 470 43 470
... ...
130 870]; 243 970];
which enables you to do things like
>> pt1(:, 2)
ans =
469
470
..
870
>> min(pt1(:,1))
ans =
29
Does that solve your problem?
To any passers by: what is the notation [S.field] for non-scalar structs called? Does it even have a name? Questions involving this technique frequently pop-up, and it would help if I knew what it's called so I can post a link to the manual page in the answer...

Related

Importing the result of a MATLAB numeric array into a new MATLAB script

Consider that I have a code that returns a double array. When run, the result returned at the command window a result looks like this:
mpc.gen=
1 100 344 34 5
2 433 223 45 2
3 333 432 12 3
4 213 233 12 3
What I want to do is create a MATLAB script which would contain this array. In other words in this new MATLAB script I would have the following array, constructed like this:
mpc.gen= [ 1 100 344 34 5 ;
2 433 223 45 2 ;
3 333 432 12 3 ;
4 213 233 12 3 ;
] ;
Just calling the function would save the variable in the new script, however that is not what I need since I need to use this script for a simulation at a special power tool called MATPOWER. The array needs to be in the form shown at the new script.
The actual array is much bigger in size however I use this here for simplicity. Is there any way I can do this automatically, and not just pass the data from the command window to the new script one by one manually? Any help would be greatly appreciated. Thank you in advance for your time!
What you want to use is mat2str. It converts a matrix to a string representation that, when evaluated, results in the identical matrix.
For example:
>> result = [1 100 344 34 5;
2 433 223 45 2;
3 333 432 12 3;
4 213 233 12 3];
>> mat2str(result)
ans =
[1 100 344 34 5;2 433 223 45 2;3 333 432 12 3;4 213 233 12 3]
You could write this to a file like so:
f = fopen('test_script.m', 'w');
fprintf(f,'mpc.gen = %s\n', mat2str(result));
fclose(f);
The formatting is not identical to your example, but if the tool does proper MATLAB parsing, it shouldn't be a problem.
Is it intentional that mpc is a struct? (you are using dot in the name.) In the following, I use underscore instead, but it can certainly be adopted, if it is intentional.
This is what functions are for. So instead of making a script, you should create a new function. If I were to do what you want to do, I would have 2 functions and 1 script. Whereas the script looks like this
mpc_bus = function1;
function2(mpc_bus);
where function1 is the code that returns mpc.bus and function2 is the one where you want to work with mpc.gen, and the top would be something like this
function [] = function2(mpc_gen)
Alternatively: If you of some reason does not like functions, you can make the first code save the variable using save(*filename*.mat) and then you can load the file again in the script using dat=load(*filename*.mat); and mpc_gen = dat.mpc_bus;

How is an array sliced?

I have some sample code where the array is sliced as follows:
A = X(:,2:300)
What does this mean about the slice of the array?
: stands for 'all' if used by itself and 2:300 gives an array of integers from 2 to 300 with a spacing of 1 (1 is implicit) in MATLAB. 2:300 is the same as 2:1:300 and you can even use any spacing you wish, for example 2:37:300 (result: [2 39 76 113 150 187 224 261 298]) to generate equally spaced numbers.
Your statement says - select every row of the matrix A and columns 2 to 300. Suggested reading

How can I find minimum values from array in matlab?

I want to extract the two points (i.e their values) which are marked with black outline in figure. These minima points are 2 and 5. Then after extraction these marked points coordinates I want to calculate the distance between them.
The code that I am using to plot average values of image, calculate minimas and locations is
I1=imread('open.jpg');
I2=rgb2gray(I1);
figure, title('open');
plot(1:size(I2,1), mean(I2,2));
hold on
horizontalAverages = mean(I2 , 2);
plot(1:size(I2,1) , horizontalAverages)
[Minimas locs] = findpeaks(-horizontalAverages)
plot(locs , -1*Minimas , 'r*')
Minima
-86.5647
-80.3647
-81.3588
-106.9882
-77.0765
-77.8235
-92.2353
-106.2235
-115.3118
-98.3706
locs =
30
34
36
50
93
97
110
121
127
136
It is a bit unclear from your question what you are actually looking for, but the following one liner will get you the local minima:
% Some dummy data
x = 1:11;
y = [3 2 1 0.5 1 2 1 0 1 2 3];
min_idx = ([0 sign(diff(y))] == -1) & ([sign(diff(y)) 0] == 1);
figure
plot(x, y);
hold on;
scatter(x(min_idx), y(min_idx))
hold off;
Use the 'findpeaks' function, if you have the signal processing toolbox.
[y,locs]=findpeaks(-x)
will find the local minima. This function has a ton of options to handle all kinds of special cases, so is very useful.

Getting the array sorted in relation to a value Matlab

Let's say I have an array arr of doubles:
arr = 120,121,118,119,117,123,120
And a value x
x = 120
I want to get this value
newarr = 120,120,119,121,118,117,123
Which is a new array, the same size of arr, but the values are sorted in relation to the value x, having the closest value first (doesn't matter if it's ascending or descending).
Any idea?
One approach -
[~,idx] = sort(abs(x-arr))
out = arr(idx)
Output -
out =
120 120 121 119 118 117 123
Since, 191 & 121 are equidistant from x = 120, the output values appear to be different than the ones listed in the expected output of the problem. In this approach, when two such equidistant values appear in arr, the ones appearing at the start are put at the start in the output array too, thus the order of elements is maintained or it's stable in the output array. As, an example to demonstrate this "stability", here's a sample run with modified arr and keeping x the same at 120 -
>> arr
arr =
120 121 118 119 117 123 121 119
>> out
out =
120 121 119 121 119 118 117 123
Note: If you would like to have an ascending order for the equidistant elements, you can first sort arr and then use this approach.

How to store the Centroid values of blobs in one Array?

My picture has a certain number of various shapes of blobs. I want to store those centroid values in one array for the future use. So I tried the following code, but it did not work. So can anyone help me?
Sample:
for i = 1:length(STATS)
centroid = STATS(i).Centroid;
array = zeros(length(STATS));
array(i) = centroid;
end
I want to store the centroid data in one array like below
array=
145 145
14 235
145 544
14 69
74 55
Try the following:
for i = 1:length(STATS)
array{i} = STATS(i).Centroid;
end
You can print the entire array using the following:
array{:}
You can read more about cell arrays here. Also, in your older code, you were trying to assign an array (Centroid) to an element of an array(array(i)).
How about:
array=cell2mat({STATS.Centroid});
Assuming
STATS(1).Centroid = [145 145];
STATS(2).Centroid = [14 235]; % Etc...
Try:
array = reshape([STATS.Centroid],2,size(STATS,2))'
array =
145 145
14 235
145 544
14 69
74 55
How this works:
[STATS.Centroid] is a short version of [STATS(1).Centroid, STATS(2).Centroid, .. STATS(n).Centroid]. This will give you the values as a vector. reshape is then used to make it into your desired size.

Resources