Editing Cookbook
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 17: | Line 17: | ||
This is a list of possible tests to check for features: | This is a list of possible tests to check for features: | ||
## support for 64 bit indexing | |||
## support for 64 bit indexing | sizemax () > intmax ("int32") | ||
sizemax () > intmax ("int32") | |||
## built with support for java | ## built with support for java | ||
usejava ("jvm") | usejava ("jvm") | ||
## Image IO with support for tif files | ## Image IO with support for tif files | ||
any (cellfun (@(x) ismember ("tif", x), {imformats.ext})) | any (cellfun (@(x) ismember ("tif", x), {imformats.ext})) | ||
## Image IO with support for png files | ## Image IO with support for png files | ||
any (cellfun (@(x) ismember ("png", x), {imformats.ext})) | any (cellfun (@(x) ismember ("png", x), {imformats.ext})) | ||
=== Find if a package is installed === | === Find if a package is installed === | ||
Line 41: | Line 39: | ||
Use {{codeline|pkg ("list", pkg-name)}} like so: | Use {{codeline|pkg ("list", pkg-name)}} like so: | ||
if (! isempty (pkg ("list", "foo"))) | |||
if (! isempty (pkg ("list", "foo"))) | ## use functions from package foo, the prefered way | ||
elseif (! isempty (pkg ("list", "bar"))) | |||
elseif (! isempty (pkg ("list", "bar"))) | ## use functions from package bar, not so optimal | ||
else | |||
else | ## default case | ||
endif | |||
endif | |||
==== Discussion ==== | ==== Discussion ==== | ||
Line 62: | Line 58: | ||
then you might as well not catch it in the first place. | then you might as well not catch it in the first place. | ||
## This contraption doesn't add anything. If 'pkg load' fails, it | |||
## This contraption doesn't add anything. If 'pkg load' fails, it | ## will already give an error message to the user. | ||
## will already give an error message to the user. | try | ||
try | pkg load foo; | ||
catch | |||
catch | error ("failed to load foo: %s", lasterr ()); | ||
end_try_catch | |||
end_try_catch | |||
## Again, doesn't add anything. The failure of 'pkg load' is enough | ## Again, doesn't add anything. The failure of 'pkg load' is enough | ||
if (isempty (pkg ("list", "foo"))) | if (isempty (pkg ("list", "foo"))) | ||
error ("program: package foo is not installed"); | |||
endif | endif | ||
Beware that an installed package is not always a guarantee that a function | Beware that an installed package is not always a guarantee that a function | ||
Line 101: | Line 95: | ||
== Structures == | == Structures == | ||
=== 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 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: | 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"}, | "age", { 45 , 52 , 45 , 23 }, | ||
"protein", {"H2B", "CDK2" , "CDK2", "Tip60" }, | |||
"tube" , { 3 , 5 , 2 , 18 } | |||
); | |||
==== Solution ==== | ==== Solution ==== | ||
Indexing the struct returns a comma separated list so use them to create a matrix. | Indexing the struct returns a comma separated list so use them to create a matrix. | ||
[samples(:).age] | |||
[samples(:).age] | |||
This however does not keep the original structure of the data, instead returning all values in a single column. To fix this, use {{Codeline|reshape()}}. | This however does not keep the original structure of the data, instead returning all values in a single column. To fix this, use {{Codeline|reshape()}}. | ||
reshape ([samples(:).age], size (samples)) | |||
reshape ([samples(:).age], size (samples)) | |||
==== Discussion ==== | ==== Discussion ==== | ||
Returning all values in a comma separated lists allows you to make anything out of them. If numbers are expected, create a matrix by enclosing them in square brackets. But if strings are to be expected, a cell array can also be easily generated with curly brackets | |||
{samples(:).patient} | |||
{samples(:).patient} | |||
You are also not limited to return all elements, you may use logical indexing from other fields to get values from the others: | You are also not limited to return all elements, you may use logical indexing from other fields to get values from the others: | ||
[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 == | == Array manipulation == | ||
Line 152: | Line 130: | ||
==== Problem ==== | ==== Problem ==== | ||
For an array {{Codeline|A}} with arbitrary number of dimensions, select, for example, the first column. | 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. | ||
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 ==== | ==== Solution ==== | ||
One possibility is to use {{ | 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: | ||
This can be written as a function: | |||
<syntaxhighlight lang=" | |||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
function [B]= array_slice (A,k,d) | function [B]= array_slice (A,k,d) | ||
#return the k-th slice (row, column...) of A, with d specifying the dimension to slice on | #return the k-th slice (row, column...) of A, with d specifying the dimension to slice on | ||
Line 179: | Line 156: | ||
%! A=rand(2, 3, 4, 5, 6); | %! A=rand(2, 3, 4, 5, 6); | ||
%!assert (array_slice (A,2,3), A(:, :, 2, :, :)) | %!assert (array_slice (A,2,3), A(:, :, 2, :, :)) | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
To remove the singleton dimension {{Codeline|d}} from the result {{Codeline|B}}, use | To remove the singleton dimension {{Codeline|d}} from the result {{Codeline|B}}, use | ||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
<syntaxhighlight lang=" | |||
B = reshape(B, [size(B)([1:d-1 d+1:end])]); | B = reshape(B, [size(B)([1:d-1 d+1:end])]); | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
== Input/output == | == Input/output == | ||
=== Display matched elements from different arrays === | === Display matched elements from different arrays === | ||
==== Problem ==== | ==== Problem ==== | ||
You have two, or more, arrays with paired elements and want to print out a string about them. For example: | You have two, or more, arrays with paired elements and want to print out a string about them. For example: | ||
keys = {"human", "mouse", "chicken"}; | |||
keys = {"human", "mouse", "chicken"}; | values = [ 64 72 70 ]; | ||
values = [ 64 72 70 ]; | |||
and you want to display: | and you want to display: | ||
Calculated human genome GC content is 64% | |||
Calculated mouse genome GC content is 72% | |||
Calculated chicken genome GC content is 70% | |||
==== Solution ==== | ==== Solution ==== | ||
Make a two rows cell array, with each paired data in a column and supply a cs-list to printf | |||
values = num2cell (values); | |||
new = {keys{:}; values{:}}; | |||
printf ("Calculated %s genome GC content is %i%%\n", new{:}) | |||
values = num2cell (values); | |||
new = {keys{:}; values{:}}; | |||
printf ("Calculated %s genome GC content is %i%%\n", new{:}) | |||
or in a single line: | or in a single line: | ||
printf ("Calculated %s genome GC content is %i%%\n", {keys{:}; num2cell(values){:}}{:}) | |||
printf ("Calculated %s genome GC content is %i%%\n", {keys{:}; num2cell(values){:}}{:}) | |||
==== Discussion ==== | ==== Discussion ==== | ||
{{Codeline|printf}} and family do not accept cell arrays as values. However, they keep repeating the template given as long as it has enough arguments to keep going. As such, the trick is on supplying a cs-list of elements which can be done by using a cell array and index it with {{Codeline|<nowiki>{}</nowiki>}}. | |||
Since values are stored in column-major order, paired values need to be on the same column. A new row of data can then be added later with {{Codeline|new(end+1,:) <nowiki>= {"Andrew", "Bob", "Kevin"}</nowiki>}}. Note that normal brackets are now being used for indexing. | |||
Since values are stored in column-major order, paired values need to be on the same column. | |||
A new row of data can then be added later with | |||
new(end+1,:) = {"Andrew", "Bob", "Kevin"} | |||
</ | |||
Note that normal brackets are now being used for indexing. | |||
=== Swap values === | === Swap values === | ||
If you want to exchange the value between two variables without creating a dummy one, you can simply do: | If you want to exchange the value between two variables without creating a dummy one, you can simply do: | ||
<syntaxhighlight lang=" | {{Code|Swap values without dummy variable|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
[b,a] = deal (a,b); | [b,a] = deal (a,b); | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
=== Collect all output arguments of a function === | === Collect all output arguments of a function === | ||
If you have a function that returns several values, e.g. | If you have a function that returns several values, e.g. | ||
<syntaxhighlight lang=" | {{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | ||
function [a b c]= myfunc () | function [a b c]= myfunc () | ||
[a,b,c] = deal (1,2,3); | [a,b,c] = deal (1,2,3); | ||
endfunction | endfunction | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
and you want to collect them all into a single cell (similarly to Python's zip() function) you can do: | and you want to collect them all into a single cell (similarly to Python's zip() function) you can do: | ||
<syntaxhighlight lang=" | {{Code|Collect multiple output arguments|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
outargs = nthargout (1:3, @myfunc) | outargs = nthargout (1:3, @myfunc) | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
=== Create a text table with fprintf=== | === Create a text table with fprintf=== | ||
(a.k.a. A funny formatting trick with fprintf found by chance) | |||
Imagine that you want to create a text table with | Imagine that you want to create a text table with fprintf with 2 columns of 15 characters width and both right justified. How to do this thing? | ||
How to do this thing? | |||
That's easy: | That's easy: | ||
If the variable Text is a cell array of strings (of length < 15) with two columns and a certain number of rows, simply type for the | If the variable Text is a cell array of strings (of length <15) with two columns and a certain number of rows, simply type for the kth row of Text | ||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
<syntaxhighlight lang=" | fprintf('%15.15s | %15.15s\n', Text{k,1}, Text{k,2}); | ||
fprintf('%15.15s | %15.15s\n', Text{k,1}, Text{k,2}); | </syntaxhighlight>}} | ||
</syntaxhighlight> | The syntax '%<n>.<m>s' allocates '<n>' places to write chars and display the '<m>' first characters of the string to display. | ||
The syntax | |||
Example: | Example: | ||
{{Code|Example create a text table with fprintf|<syntaxhighlight lang="octave" style="font-size:13px"> | |||
<syntaxhighlight lang=" | octave:1> Text={'Hello','World'}; | ||
Text = { | octave:2> fprintf('%15.15s | %15.15s\n', Text{1,1}, Text{1,2}) | ||
fprintf('%15.15s | %15.15s\n', Text{1,1}, Text{1,2}) | |||
Hello | World | Hello | World | ||
</syntaxhighlight>}} | |||
===Load comma separated values (*.csv) files=== | ===Load comma separated values (*.csv) files=== |