1,852
edits
(Some refactoring using <syntaxhighlight>.) |
(Some more refactoring.) |
||
Line 266: | Line 266: | ||
===Load comma separated values (*.csv) files=== | ===Load comma separated values (*.csv) files=== | ||
{{ | # Using {{manual|textread}} gets you a one column cell array. The original size can be restored by using the {{manual|reshape}} function. <syntaxhighlight lang="Octave"> | ||
A=textread("file.csv", "%d", "delimiter", ","); | A = textread("file.csv", "%d", "delimiter", ","); | ||
B=textread("file.csv", "%s", "delimiter", ","); | B = textread("file.csv", "%s", "delimiter", ","); | ||
inds = isnan(A); | inds = isnan(A); | ||
B(!inds) = num2cell(A(!inds)) | B(! inds) = num2cell (A(! inds)) | ||
</syntaxhighlight>}} | </syntaxhighlight> | ||
# Another option is to use the function {{manual|csvread}}. However, this function can't handle non-numerical data. | |||
# The probably best option is to use the function [https://octave.sourceforge.io/io/function/csv2cell.html <code>csv2cell</code>] from the [[IO package]]. This function can read mixed-type (numerical and text) .csv files, allows to specify other field separators than a comma and other text protection characters (default: <code>"</code> double quote) and can skip header lines. If you have the [[IO package]] installed and loaded, type <code>help csv2cell</code> at the Octave prompt for more info. | |||
===Load XML files=== | |||
Reading XML in octave can be achieved using the java library [https://xerces.apache.org/ Apache Xerces]. | |||
It seems that the Matlab's <code>xmlread</code> is just a thin wrapper around the Apache Xerces library. | |||
One should note however, that Java functions have the working directory set to the working directory when octave starts and the working directory is not modified by a {{manual|cd}} in octave. | |||
Matlab has the same behavior, as Java does not provide a way to change the current working directory (http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4045688). | |||
To avoid any issues, it is thus better to use the absolute path to the XML file. | |||
You need the jar files {{Path|xercesImpl.jar}} and {{Path|xml-apis.jar}} from e.g. https://xerces.apache.org/mirrors.cgi#binary (check for the latest version). | |||
Use {{manual|javaaddpath}} to include these files: | |||
= | <syntaxhighlight lang="Octave"> | ||
javaaddpath ("/path/to/xerces-2_11_0/xercesImpl.jar"); | |||
javaaddpath ("/path/to/xerces-2_11_0/xml-apis.jar"); | |||
</syntaxhighlight> | |||
Example: | |||
<syntaxhighlight lang="Octave"> | |||
filename = "sample.xml"; | |||
## These three lines are equivalent to xDoc = xmlread(filename) in Matlab | |||
parser = javaObject("org.apache.xerces.parsers.DOMParser"); | |||
parser.parse(filename); | |||
xDoc = parser.getDocument(); | |||
elem = xDoc.getElementsByTagName("data").item(0); ## get first data element | |||
data = elem.getFirstChild.getTextContent(); ## get text from child | |||
att = elem.getAttribute("att"); ## get attribute named att | |||
</syntaxhighlight> | </syntaxhighlight> | ||
{{File|sample.xml| | |||
<syntaxhighlight lang="xml"> | |||
{{ | <root> | ||
<data att="1">hello</data> | |||
</root> | |||
</syntaxhighlight>}} | </syntaxhighlight>}} | ||
Line 325: | Line 318: | ||
For example, to plot data using a string variable as a legend: | For example, to plot data using a string variable as a legend: | ||
# Static string as legend (simplest): <syntaxhighlight lang="Octave"> | |||
x = linspace (-1, 3, 100); | |||
y = sin (x); | |||
legend = "-1;My data;"; | legend = "-1;My data;"; | ||
plot(x, y, legend); | plot (x, y, legend); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
# Variable string as legend (moderate): <syntaxhighlight lang="Octave"> | |||
x = linspace (-1, 3, 100); | |||
y = sin (x); | |||
plot(x, y, sprintf("-1;%s;", dataName)); | dataName = "My data"; | ||
</syntaxhighlight>}} | plot (x, y, sprintf("-1;%s;", dataName)); | ||
</syntaxhighlight> | |||
# Variable string as legend using {{manual|eval}} (not as neat): <syntaxhighlight lang="Octave"> | |||
legend = "My data"; | |||
legend = | plot_command = ["plot (x, y, '-1;", legend, ";')"]; | ||
plot_command = [ | eval (plot_command); | ||
eval(plot_command); | </syntaxhighlight> | ||
</syntaxhighlight> | |||
These same tricks are useful for reading and writing data files with unique names, etc. | These same tricks are useful for reading and writing data files with unique names, etc. | ||
== Combinatorics == | == Combinatorics == | ||
=== Combinations with string characters === | === Combinations with string characters === | ||
==== Problem ==== | ==== Problem ==== | ||
You want to get all combinations of different letters but {{ | |||
You want to get all combinations of different letters but {{manual|nchoosek}} only accepts numeric input. | |||
==== Solution ==== | ==== Solution ==== | ||
Convert your string to numbers and then back to characters. | Convert your string to numbers and then back to characters. | ||
<syntaxhighlight lang="Octave"> | |||
string = "Hello"; | |||
n = 4; | |||
char (nchoosek (uint8 (string), n)) | char (nchoosek (uint8 (string), n)) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Discussion ==== | ==== Discussion ==== | ||
A string in Octave is just a character matrix and can easily be converted to numeric form back and forth. Each character has an associated number (the {{codeline|asci}} function of the {{forge|miscellaneous}} package displays a nicely formatted conversion table). | |||
A string in Octave is just a character matrix and can easily be converted to numeric form back and forth. | |||
Each character has an associated number (the {{codeline|asci}} function of the {{forge|miscellaneous}} package displays a nicely formatted conversion table). | |||
=== Permutations with repetition === | === Permutations with repetition === | ||
==== Problem ==== | ==== Problem ==== | ||
You want to generate all possible permutations of a vector with repetition. | You want to generate all possible permutations of a vector with repetition. | ||
==== Solution ==== | ==== Solution ==== | ||
{{ | Use {{manual|ndgrid}}: | ||
[x y z] = ndgrid ([1 2 3 4 5]); | |||
[x(:) y(:) z(:)] | <syntaxhighlight lang="Octave"> | ||
</syntaxhighlight> | [x, y, z] = ndgrid ([1, 2, 3, 4, 5]); | ||
[x(:), y(:), z(:)] | |||
</syntaxhighlight> | |||
==== Discussion ==== | ==== Discussion ==== | ||
It is possible to expand the code above and make it work for any length of permutations. | It is possible to expand the code above and make it work for any length of permutations. | ||
<syntaxhighlight lang="Octave"> | |||
cart = nthargout ([1:n], @ndgrid, vector); | cart = nthargout ([1:n], @ndgrid, vector); | ||
combs = cell2mat (cellfun (@(c) c(:), cart, "UniformOutput", false)); | combs = cell2mat (cellfun (@(c) c(:), cart, "UniformOutput", false)); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Mathematics == | == Mathematics == | ||
=== Test if a number is | |||
=== Test if a number is an integer === | |||
The simplest method is probably {{manual|fix}}: | |||
<syntaxhighlight lang="Octave"> | |||
fix (x) == x | |||
</syntaxhighlight> | |||
=== 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 even. | Check the remainder of a division by two. If the remainder is zero, the number is even. | ||
<syntaxhighlight lang="Octave"> | |||
mod (value, 2) ## 1 if odd, zero if even | |||
</syntaxhighlight> | |||
Since {{ | Since {{manual|mod}} accepts a matrix, the following can be done: | ||
<syntaxhighlight lang="Octave"> | |||
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 (!logical (mod (values, 2))) ## true if at least one number in values is even | |||
all (!logical (mod (values, 2))) ## true if all numbers in values are even | |||
</syntaxhighlight> | |||
==== Discussion ==== | ==== Discussion ==== | ||
Since we are checking for the remainder of a division, the first choice would be to use {{manual|rem}}. | |||
However, in the case of negative numbers {{manual|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 <code>0.5</code> or <code>4.201</code> 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 <code>NaN</code>, <code>Inf</code>, or non-integer values. | |||
=== Parametrized Functions === | === Parametrized Functions === | ||
==== Problem ==== | ==== Problem ==== | ||
Line 416: | Line 438: | ||
==== Solution ==== | ==== Solution ==== | ||
We could solve the problem with the following code to solve the spring equation for different values of the spring constant: | |||
<syntaxhighlight lang="Octave"> | |||
t = linspace (0, 10, 100); | t = linspace (0, 10, 100); | ||
function sprime = spring (s, t, k) | function sprime = spring (s, t, k) | ||
Line 432: | Line 455: | ||
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 441: | Line 464: | ||
The [http://www.gnu.org/software/octave/doc/interpreter/Anonymous-Functions.html#Anonymous-Functions anonymous function] | The [http://www.gnu.org/software/octave/doc/interpreter/Anonymous-Functions.html#Anonymous-Functions anonymous function] | ||
is a function of only <math>x, t</math> where the parameter <math>k</math> is | <syntaxhighlight lang="Octave"> | ||
@(x, t) sprime (x, t, k) | |||
</syntaxhighlight> | |||
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. | |||
=== 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>. | |||
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>. | |||
Assume that the points are saved in a matrix <code>P</code> with <code>m</code> rows (one for each point) and <code>n</code> columns, one for each component. | |||
==== 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. | |||
The square distance between the points can be calculated with the code: | |||
[ | |||
Dsq = zeros ( | <syntaxhighlight lang="Octave"> | ||
for i = 1: | [m, n] = size (P); | ||
Dsq = zeros (m); | |||
for i = 1:n | |||
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 lang="Octave"> | |||
R | R = zeros (m, m, n); | ||
for i = 1: | for i = 1:n | ||
R(:,:,i) = P(:,i) - P(:,i)'; | R(:,:,i) = P(:,i) - P(:,i)'; | ||
endfor | endfor | ||
</syntaxhighlight> | </syntaxhighlight> | ||
The relation between <code>Dsq</code> and <code>R</code> is | |||
<syntaxhighlight lang="Octave"> | |||
Dsq = sumsq (R, 3); | |||
</syntaxhighlight> | |||
Dsq = sumsq (R,3); | |||
</syntaxhighlight> | |||
==== Discussion ==== | ==== Discussion ==== | ||
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 < | The calculation can be implemented using functions like {{manual|cellfun}} 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 <code>Dsq</code> 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 <code>vech</code> and <code>unvech</code> (this one is in the Forge package {{Forge|general}}). | |||
Two functions that haven't seen the light yet are <code>sub2ind_tril</code> and <code>ind2sub_tril</code> (currently private functions in the [[Mechanics_package | Forge package mechanics]]) that are useful to index the elements of a vector constructed with the function <code>vech</code>. | |||
Each page (the third index) of the multidimensional array <code>R</code> 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.). | Check the [[Geometry package]] for many more distance functions (points, lines, polygons, etc.). |