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 1: | Line 1: | ||
An Octave cookbook. Each entry should go in a separate section and have the following subsection: problem, solution, discussion and maybe a see also. | An Octave cookbook. Each entry should go in a separate section and have the following subsection: problem, solution, discussion and maybe a see also. | ||
== 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 | 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: | ||
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 | |||
== 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>}} | ||
== Mathematics == | == Mathematics == | ||
=== Find if a number is even/odd === | === Find if a number is even/odd === | ||
==== Problem ==== | ==== Problem ==== | ||
You have a number, or an array or matrix of them, and want to know if any of them is an odd or even number, i.e., their parity. | You have a number, or an array or matrix of them, and want to know if any of them is an odd or even number, i.e., their parity. | ||
==== Solution ==== | ==== Solution ==== | ||
Check the remainder of a division by two. If the remainder is zero, the number is odd. | |||
mod (value, 2) ## 1 if odd, zero if even | |||
Since {{Codeline|mod()}} acceps a matrix, the following can be done: | |||
mod ( | |||
any (mod (values, 2)) ## true if at least one number in values is even | |||
all (mod (values, 2)) ## true if all numbers in values are odd | |||
any (mod (values, 2)) | any (!logical (mod (values, 2))) ## true if at least one number in values is even | ||
all (mod (values, 2)) | all (!logical (mod (values, 2))) ## true if all numbers in values are even | ||
any (!logical (mod (values, 2))) | |||
all (!logical (mod (values, 2))) | |||
==== Discussion ==== | ==== Discussion ==== | ||
Since we are checking for the remainder of a division, the first choice would be to use {{Codeline|rem()}}. However, in the case of negative numbers {{Codeline|mod()}} will still return a positive number making it easier for comparisons. Another alternative is to use {{Codeline|bitand (X, 1)}} or {{Codeline|bitget (X, 1)}} but those are a bit slower. | |||
Note that this solution applies to integers only. Non-integers such as 1/2 or 4.201 are neither even nor odd. If the source of the numbers are unknown, such as user input, some sort of checking should be applied for NaN, Inf, or non-integer values. | |||
==== See also ==== | |||
Find if a number is an integer. | |||
=== Parametrized Functions === | === Parametrized Functions === | ||
==== Problem ==== | ==== Problem ==== | ||
Line 459: | Line 116: | ||
==== Solution ==== | ==== Solution ==== | ||
We could solve the problem with the following code: | |||
{{Code|Solve spring equation for different values of the spring constant|<syntaxhighlight lang="octave" style="font-size:13px"> | |||
<syntaxhighlight lang=" | |||
t = linspace (0, 10, 100); | t = linspace (0, 10, 100); | ||
function sprime = spring (s, t, k) | function sprime = spring (s, t, k) | ||
Line 476: | Line 132: | ||
plot (t, x1, t, x2) | plot (t, x1, t, x2) | ||
legend ('x1', 'x2') | legend ('x1', 'x2') | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
[[File:solparfun.png|400px]] | [[File:solparfun.png|400px]] | ||
Line 484: | Line 140: | ||
In the above example, the function "sprime" represents a family of functions of the variables <math>x, t</math> parametrized by the parameter <math>k</math>. | In the above example, the function "sprime" represents a family of functions of the variables <math>x, t</math> parametrized by the parameter <math>k</math>. | ||
The [http://www.gnu.org/software/octave/doc/interpreter/Anonymous-Functions.html#Anonymous-Functions | The [http://www.gnu.org/software/octave/doc/interpreter/Anonymous-Functions.html#Anonymous-Functions anonympus function] | ||
<pre> | |||
@(x, t) sprime (x, t, k) | |||
</pre> | |||
is a function of only <math>x, t</math> where the parameter <math>k</math> is 'frozen' to the value it has at the moment in the current scope. | |||
is a function of only <math>x, t</math> where the parameter <math>k</math> is | |||
=== Distance between points === | === Distance between points === | ||
==== Problem ==== | ==== Problem ==== | ||
Given a set of points in space we want to calculate the distance between all of them. Each point is described by its components <math> (x_i,y_i,\ldots)</math>. Asusme that the points are saved in a matrix '''<tt>P</tt>''' with '''<tt>N</tt>''' rows (one for each point) and '''<tt>D</tt>''' columns, one for each component. | |||
Given a set of points in space we want to calculate the distance between all of them. | |||
Each point is described by its components <math> (x_i,y_i,\ldots)</math>. | |||
==== Solution ==== | ==== Solution ==== | ||
One way of proceeding is to use the broadcast properties of operators in GNU Octave. The square distance between the points can be calculated with the code | |||
One way of proceeding is to use the broadcast properties of operators in GNU Octave. | <!-- {{SyntaxHighlight| --> | ||
The square distance between the points can be calculated with the code | {{Code|Calculate square distance between points|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
[N, dim] = size (P); | |||
<syntaxhighlight lang=" | Dsq = zeros (N); | ||
[ | for i = 1:dim | ||
Dsq = zeros ( | |||
for i = 1: | |||
Dsq += (P(:,i) - P(:,i)').^2; | Dsq += (P(:,i) - P(:,i)').^2; | ||
endfor | endfor | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
This matrix is symmetric with zero diagonal. | This matrix is symmetric with zero diagonal. | ||
Similarly the vectors pointing from one point to the another is | Similarly the vectors pointing from one point to the another is | ||
<!-- {{SyntaxHighlight| --> | |||
<syntaxhighlight lang=" | {{Code|Calculate radius vector between points|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
R = zeros ( | R = zeros (N,N,dim); | ||
for i = 1: | for i = 1:dim | ||
R(:,:,i) = P(:,i) - P(:,i)'; | R(:,:,i) = P(:,i) - P(:,i)'; | ||
endfor | endfor | ||
</syntaxhighlight> | </syntaxhighlight>}} | ||
The relation between < | The relation between <tt>Dsq</tt> and <tt>R</tt> is | ||
<!-- {{SyntaxHighlight| --> | |||
{{Code|Calculate square distance from radius vector between points|<syntaxhighlight lang="octave" style="font-size:13px"> | |||
Dsq = sumsq (R,3); | |||
</syntaxhighlight>}} | |||
==== Discussion ==== | ==== Discussion ==== | ||
The calculation can be implemented using functions like <tt>cellfun</tt> and avoid the loop over components of the points. However in most cases we will have more points than components and the improvement, if any, will be minimal. | |||
Another observation is that the matrix Dsq is symmetric and we could store only the lower or upper triangular part. To use this optimization in a practical way check the help of the functions <tt>vech</tt> and <tt>unvech</tt> (this one is in the Forge package ''general''). Two functions that haven't seen the light yet are <tt>sub2ind_tril</tt> and <tt>ind2sub_tril</tt> (currently private functions in the [[Mechanics_package | Forge package mechanics]]) that are useful to index the elements of a vector constructed with the function <tt>vech</tt>. Each page (the third index) of the multidimensional array <tt>R</tt> is an anti-symmetric matrix and we could also save some memory by keeping only one of the triangular submatrices. | |||
Check the [[Geometry package]] for many more distance functions (points, lines, polygons, etc.). | |||
== Plotting == | |||
== Input/Output == | |||
=== Create a text table with fprintf=== | |||
(A funny formatting trick with fprintf found by chance) | |||
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? | |||
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 kth row of Text | |||
{{Code||<syntaxhighlight lang="octave" style="font-size:13px"> | |||
fprintf('%15.15s | %15.15s\n', Text{k,1}, Text{k,2}); | |||
</syntaxhighlight>}} | |||
The syntax '%<n>.<m>s' allocates '<n>' places to write chars and display the '<m>' first characters of the string to display. | |||
Example: | |||
{{Code|Example create a text table with fprintf|<syntaxhighlight lang="octave" style="font-size:13px"> | |||
octave:1> Text={'Hello','World'}; | |||
octave:2> fprintf('%15.15s | %15.15s\n', Text{1,1}, Text{1,2}) | |||
Hello | World | |||
</syntaxhighlight>}} | |||
===Load comma separated values (*.csv) files=== | |||
A=textread("file.csv", "%d", "delimiter", ","); | |||
B=textread("file.csv", "%s", "delimiter", ","); | |||
inds = isnan(A); | |||
B(!inds) = num2cell(A(!inds)) | |||
This gets you a 1 column cell array. You can reshape it to the original size by using the <code>reshape</code> function | |||
The next version of octave (3.6) implements the <code>CollectOutput</code> switch as seen in example 8 here: http://www.mathworks.com/help/techdoc/ref/textscan.html |