Cookbook: Difference between revisions

1,370 bytes added ,  5 May 2014
array slice tips
(array slice tips)
Line 4: Line 4:
=== Retrieve a field value from all entries in a struct array ===
=== Retrieve a field value from all entries in a struct array ===
==== Problem ====
==== Problem ====
You have a struct array with multiple fields, and you want to acess the value from a specific field from all elements. For example, you want to return the age from all patients in the following case:
You have a struct array with multiple fields, and you want to access the value from a specific field from all elements. For example, you want to return the age from all patients in the following case:


   samples = struct ("patient", {"Bob", "Kevin", "Bob" , "Andrew"},
   samples = struct ("patient", {"Bob", "Kevin", "Bob" , "Andrew"},
Line 30: Line 30:
   [samples([samples(:).age] > 34).tube]                ## return tube numbers from all samples from patients older than 34
   [samples([samples(:).age] > 34).tube]                ## return tube numbers from all samples from patients older than 34
   [samples(strcmp({samples(:).protein}, "CDK2")).tube]  ## return all tube numbers for protein CDK2
   [samples(strcmp({samples(:).protein}, "CDK2")).tube]  ## return all tube numbers for protein CDK2
== Array manipulation ==
=== Select a slice from an n-D array ===
==== Problem ====
For an array {{Codeline|A}} with arbitrary number of dimensions, select, for example, the first column. This would be {{Codeline|A(:, 1)}} if {{Codeline|A}} was 2-D, {{Codeline|A(:, 1, :)}} if {{Codeline|A}} was 3-D, and so on.
==== Solution ====
One possibility is to use {{Codeline|subsref}} with the input {{Codeline|idx}} created dynamically with {{Codeline|repelems}} to have the right number of dimensions. This can be written as a function:
{{Code||<syntaxhighlight lang="octave" style="font-size:13px">
function [B]= array_slice (A,k,d)
#return the k-th slice (row, column...) of A, with d specifying the dimension to slice on
  idx.type = "()";
  idx.subs = repelems ({':'}, [1;ndims(A)]);
  idx.subs(d) = k;
  B = subsref (A,idx);
endfunction
#test cases
%!shared A
%! A=rand(2, 3);
%!assert (array_slice (A,1,2), A(:, 1))
%! A=rand(2, 3, 4);
%!assert (array_slice (A,2,1), A(2, :, :))
%! A=rand(2, 3, 4, 5);
%!assert (array_slice (A,1,2), A(:, 1, :, :))
%! A=rand(2, 3, 4, 5, 6);
%!assert (array_slice (A,2,3), A(:, :, 2, :, :))
</syntaxhighlight>}}
To remove the singleton dimension {{Codeline|d}} from the result {{Codeline|B}}, use
{{Code||<syntaxhighlight lang="octave" style="font-size:13px">
B = reshape(B, [size(B)([1:d-1 d+1:end])]);
</syntaxhighlight>}}


== Input/output ==
== Input/output ==
281

edits