MATLAB List values above threshold - matlab

I have a 3D matrix. I can use the below code to find the number of elements above 1.61. How can I actually list the elements that are above 1.61 and show what value they are? for instance, if I have a value of 8.1 and 9.1, I would like Matlab to tell me those two values. Can I do that?
for i = 1:5
A = ans.atom_data(:,5,i);
count(i,:) = sum(A(:)>1.61)
end

If you only want to know the values, use logical indexing, like this:
result = A(A>1.61);
If you want to obtain the result for each third-index-layer of a 3D array B, you can do it with cells:
result = cellfun(#(x) x(x>1.61), squeeze(mat2cell(B,size(B,1),size(B,2),ones(1,size(B,3)))),'uni',0);
Then result{1} gives the values corresponding to B(:,:,1), etc.

Related

Extract values from a vector and sort them based on their original squence

I have a vector of numbers (temperatures), and I am using the MATLAB function mink to extract the 5 smallest numbers from the vector to form a new variable. However, the numbers extracted using mink are automatically ordered from lowest to largest (of those 5 numbers). Ideally, I would like to retain the sequence of the numbers as they are arranged in the original vector. I hope my problem is easy to understand. I appreciate any advice.
The function mink that you use was introduced in MATLAB 2017b. It has (as Andras Deak mentioned) two output arguments:
[B,I] = mink(A,k);
The second output argument are the indices, such that B == A(I).
To obtain the set B but sorted as they appear in A, simply sort the vector of indices I:
B = A(sort(I));
For example:
>> A = [5,7,3,1,9,4,6];
>> [~,I] = mink(A,3);
>> A(sort(I))
ans =
3 1 4
For older versions of MATLAB, it is possible to reproduce mink using sort:
function [B,I] = mink(A,k)
[B,I] = sort(A);
B = B(1:k);
I = I(1:k);
Note that, in the above, you don't need the B output, your ordered_mink can be written as follows
function B = ordered_mink(A,k)
[~,I] = sort(A);
B = A(sort(I(1:k)));
Note: This solution assumes A is a vector. For matrix A, see Andras' answer, which he wrote up at the same time as this one.
First you'll need the corresponding indices for the extracted values from mink using its two-output form:
[vals, inds] = mink(array);
Then you only need to order the items in val according to increasing indices in inds. There are multiple ways to do this, but they all revolve around sorting inds and using the corresponding order on vals. The simplest way is to put these vectors into a matrix and sort the rows:
sorted_rows = sortrows([inds, vals]); % sort on indices
and then just extract the corresponding column
reordered_vals = sorted_rows(:,2); % items now ordered as they appear in "array"
A less straightforward possibility for doing the sorting after the above call to mink is to take the sorting order of inds and use its inverse to reverse-sort vals:
reverse_inds = inds; % just allocation, really
reverse_inds(inds) = 1:numel(inds); % contruct reverse permutation
reordered_vals = vals(reverse_inds); % should be the same as previously

In an assignment A(:) = B, the number of elements in A and B must be the same

if (hidden_layer>1)
for i =1 :hidden_layer
start_hidden_layer(i) = rand([gk(i+1),(gk(i)+1)])-0.5 ;
end
end
hi Friends.
I know every iteration was changed start_hidden_layer matrix dimensional.But all start_hidden_layer values must saved. How to solve this problem?
firstly hidden_layer>1
gk(i) is integer value for example 5 , 3, 8
Since you're calling rand with different matrix sizes on each iteration, you cannot save the results into a normal matrix. You need to use a cell matrix to store the result, like this:
%//preallocate the cell array
start_hidden_layer = cell(1, hidden_layer);
for i = 1:hidden_layer
start_hidden_layer{i} = rand([gk(i+1), (gk(i)+1)]) - 0.5;
end
For more on cell arrays and how to use them, see this Mathworks help doc.

How to split an array as argument values in matlab?

In my matlab script, I have a function handler
F=#(x1,x2)6+2*x1^1+3*x2^2;
This gives me an anonymous function as F that takes 2 arguments and returns the value. I also have an array of values
x = [1 2];
With the above, how can I do
F(x)
In other words, something like F(1, 2) but I want to use x, I don't want to hard code values, and it also needs to work for any dimension size, I don't want to hard code it for 2-dimension like in the above example. Basically what I'm looking for is a way to turn an array into arguments.
Can this be done in matlab?
Thanks
To turn an array into its arguments: first turn the array into a cell array (with num2cell), and then turn the cell array into a comma-separated list (with {:}):
xcell = num2cell(x);
F(xcell{:})
Does this work?
F=#(x)6+2*x(1)^1+3*x(2)^2;
xx = [1 2];
F(xx)
ans =
20

Mean value of multiple columns

I have searched a lot to find the solution, but nothing really works for me I think.
I have n data files containing two columns each (imported using uigetfile). To extract the data, I use a for loop like this:
for i=1:n
data{i}=load(filename{i});
x{i}=data{i}(:,1);
y{i}=data{i}(:,2);
end
Now, I want to get the mean value for each row of all the (let's say) x-values. E.g.:
x{1} = [1,4,7,8]
x{2} = [1,2,6,9]
Then I want something like
x_mean = [1,3,6.5,8.5]
I have tried (where k is number of rows)
for i=1:n
data{i}=load(filename{i});
x{i}=data{i}(:,1);
y{i}=data{i}(:,2);
j=1:k
x_mean=sum(x{i}(j))/n
end
But I can't use multiple counters in a for loop (as I understand). Moreover, I don't use mean as I don't see how I can use it in this case.
If someone could help me, it would be great!
You can capture the contents of each numeric array in the cell x into a new numeric array x_num like so:
x_num = [x{:}]
Computing the mean is then as simple as
mean_x = mean( [x{:}] )
For your example, that gives you the mean of all numbers in all arrays in x, which will therefore be a scalar.
If you want to compute the mean of all the rows (column-wise mean), as your example would indicate), you have to concatenate your arrays vertically, which you can do with cat:
mean_x_columnwise = mean( cat(1,x{:}) )
If you want to take the mean over all the columns (row-wise mean), you should only have to tell mean that you are looking at a different dimension:
mean_x_rowwise = mean( cat(1,x{:}), 2)

How to change row number in a FOR loop... (MATLAB newbie)

I have a set of data that is <106x25 double> but this is inside a struct and I want to extract the data into a matrix. I figured a simple FOR loop would accomplish this but I have hit a road block quite quickly in my MATLAB knowledge.
This is the only piece of code I have, but I just don't know enough about MATLAB to get this simple bit of code working:
>> x = zeros(106,25); for i = 1:106, x(i,:) = [s(i).surveydata]; end
??? Subscripted assignment dimension mismatch.
's' is a very very large file (in excess of 800MB), it is a <1 x 106 struct>. Suffice it to say, I just need to access a small portion of this which is s.surveydata where most rows are a <1 x 25 double> (a row vector IIRC) and some of them are empty and solely return a [].
s.surveydata obviously returns the results for all of the surveydata contained where s(106).surveydata would return the result for the last row. I therefore need to grab s(1:106).surveydata and put it into a matrix x. Is creating the matrix first by using x = zeros(106,25) incorrect in this situation?
Cheers and thanks for your time!
Ryan
The easiest, cleanest, and fastest way to write all the survey data into an array is to directly catenate it, using CAT:
x = cat(1,s.surveydata);
EDIT: note that if any surveydata is empty, x will have fewer rows than s has elements. If you need x to have the same amount of rows as s has elements, you can do the following:
%# find which entries in s have data
%# note that for the x above, hasData(k) contains the
%# element number in s that the k-th row of x came from
hasData = find(arrayfun(#(x)~isempty(x.surveydata),s));
%# initialize x to NaN, so as to not confuse the
%# real data with missing data entries. The call
%# to hasData when indexing makes this robust to an
%# empty first entry in s
x = NaN(length(s),length(s(hasData(1)).surveydata);
%# fill in only the rows of x that contain data
x(hasData,:) = cat(1,s(hasData).surveydata);
No, creating an array of zeroes is not incorrect. In fact it's a good idea. You don't have to declare variables in Matlab before using them, but for loops, pre-allocating has speed benefits.
x = zeros(size(s), size(s(1)));
for i = 1:106
if ~isempty(s(i).surveydata)
x(i, :) = s(i).surveydata;
end
end
Should accomplish what you want.
EDIT: Since OP indicated that some rows are empty, I accounted for that like he said.
what about this?
what s is?
if s(i).surveydata is scalar:
x = zeros(106,25);
for i = 1:106
x(i,1) = [s(i).surveydata];
end
I am guessing that is what you want tough it is not clear at all :
if s(i).surveydata is row vector:
x = zeros(106,25);
for i = 1:106
x(i,:) = [s(i).surveydata];
end
if s(i).surveydata is column vector:
x = zeros(106,25);
for i = 1:106
x(i,:) = [s(i).surveydata]';
end