Tips and tricks: Difference between revisions
(→Vectorizing Tricks: Use of brackets [] is unnecessary) |
No edit summary |
||
Line 1: | Line 1: | ||
=Tiny helper functions= | ==Tiny helper functions== | ||
This is a list of tiny helper functions (the equivalent of e.g., shell aliases), the kind one would have on its {{Path|.octaverc}} file. | This is a list of tiny helper functions (the equivalent of e.g., shell aliases), the kind one would have on its {{Path|.octaverc}} file. | ||
== replace help with man == | === replace help with man === | ||
If you use octave too much, you'll find yourself trying to use {{Codeline|help}} instead of {{Codeline|man}} on bash. This function will fix that so you can use {{Codeline|man}} in your octave instance (you can also do the opposite, create a {{Codeline|help}} alias in bash but {{Codeline|man}} has less characters). | If you use octave too much, you'll find yourself trying to use {{Codeline|help}} instead of {{Codeline|man}} on bash. This function will fix that so you can use {{Codeline|man}} in your octave instance (you can also do the opposite, create a {{Codeline|help}} alias in bash but {{Codeline|man}} has less characters). | ||
Line 10: | Line 12: | ||
endfunction</pre>}} | endfunction</pre>}} | ||
=C++= | ==C++== | ||
=== Real matrix operations=== | |||
This is a table of matrix operations commonly performed in Octave and their equivalents in C++ when using the octave libraries. | This is a table of matrix operations commonly performed in Octave and their equivalents in C++ when using the octave libraries. | ||
Line 66: | Line 69: | ||
* The names of Octave internal functions, such as mx_el_gt, are not documented and are subject to change. Functions such as mx_el_gt may eventually be available at both the scripting level and in C++ under more common names such as gt. | * The names of Octave internal functions, such as mx_el_gt, are not documented and are subject to change. Functions such as mx_el_gt may eventually be available at both the scripting level and in C++ under more common names such as gt. | ||
==Complex Matrix Operations== | ===Complex Matrix Operations=== | ||
<table> | <table> | ||
<tr><td><b>Operation</b></td><td><b>Octave</b></td><td><b>C++</b></td></tr> | <tr><td><b>Operation</b></td><td><b>Octave</b></td><td><b>C++</b></td></tr> | ||
Line 72: | Line 76: | ||
</table> | </table> | ||
==General== | |||
= | ===A funny formatting trick with fprintf found by chance=== | ||
==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? | 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? | ||
Line 89: | Line 93: | ||
Hello | World | Hello | World | ||
==Load Comma Separated Values (*.csv) files== | ===Load Comma Separated Values (*.csv) files=== | ||
A=textread("file.csv", "%d", "delimiter", ","); | A=textread("file.csv", "%d", "delimiter", ","); | ||
Line 100: | Line 104: | ||
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 | 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 | ||
==Using Variable Strings in Octave Commands== | ===Using Variable Strings in Octave Commands=== | ||
For example, to plot data using a string variable as a legend: | For example, to plot data using a string variable as a legend: | ||
Line 118: | Line 122: | ||
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. | ||
==Vectorizing Tricks== | ===Vectorizing Tricks=== | ||
You can easily fill a vector with an index: | You can easily fill a vector with an index: | ||
for i=1:n, x(i) = i; end | for i=1:n, x(i) = i; end | ||
Line 126: | Line 131: | ||
This works for expressions on the index by wrapping the index in an expression: | This works for expressions on the index by wrapping the index in an expression: | ||
for i=1:n, x(i) = sin(2*pi*i*f/r); end | for i=1:n, x(i) = sin(2*pi*i*f/r); end | ||
Line 131: | Line 137: | ||
You can also work with other vectors this way: | You can also work with other vectors this way: | ||
for i=1:n, x(i) = sin(2*pi*y(i)*f/r); end | for i=1:n, x(i) = sin(2*pi*y(i)*f/r); end | ||
Line 150: | Line 157: | ||
*tricks relying on fortran indexing | *tricks relying on fortran indexing | ||
===Other references=== | ====Other references==== | ||
*MATLAB array manipulation tips and tricks by Peter Acklam: http://home.online.no/~pjacklam/matlab/doc/mtt/index.html | *MATLAB array manipulation tips and tricks by Peter Acklam: http://home.online.no/~pjacklam/matlab/doc/mtt/index.html | ||
*The MathWorks: Code Vectorization Guide: http://www.mathworks.com/support/tech-notes/1100/1109.html | *The MathWorks: Code Vectorization Guide: http://www.mathworks.com/support/tech-notes/1100/1109.html |
Revision as of 23:40, 24 June 2012
Tiny helper functions
This is a list of tiny helper functions (the equivalent of e.g., shell aliases), the kind one would have on its .octaverc file.
replace help with man
If you use octave too much, you'll find yourself trying to use help
instead of man
on bash. This function will fix that so you can use man
in your octave instance (you can also do the opposite, create a help
alias in bash but man
has less characters).
Code: alias to help |
function man (name) help (char (name)) endfunction |
C++
Real matrix operations
This is a table of matrix operations commonly performed in Octave and their equivalents in C++ when using the octave libraries.
Operation | Octave | C++ |
add | A+B | A+B |
subtract | A-B | A-B |
matrix multiplication | A*B | A*B |
element multiplication | A.*B | product(A,B) |
element division | A./B | quotient(A,B) |
transpose* | A' | A.transpose() |
select element m,n of A** | A(m,n) | A(m-1,n-1) |
select row N of A** | A(N,:) | A.row(N-1) |
select column N of A** | A(:,N) | A.column(N-1) |
extract submatrix of A | A(a:b,c:d) | A.extract(a-1,c-1,b-1,d-1) |
absolute value of A | abs(A) | A.abs() |
comparison to scalar*** | A>2 | mx_el_gt(A,2) |
A<2 | mx_el_lt(A,2) | |
A==2 | mx_el_eq(A,2) | |
A~=2 | mx_el_ne(A,2) | |
A>=2 | mx_el_ge(A,2) | |
A<=2 | mx_el_le(A,2) | |
matrix of zeros | A=zeros(m,n) | A.fill(0.0) |
matrix of ones | A=ones(m,n) | A.fill(1.0) |
identity matrix | eye(N) | identity_matrix(N,N) |
inverse of A | inv(A) | A.inverse() |
pseudoinverse of A | pinv(A) | A.pseudo_inverse() |
diagonal elements of A | diag(A) | A.diag() |
column vector | A(:) | ColumnVector(A.reshape (dim_vector(A.length()))) |
row vector | A(:)' | RowVector(A.reshape (dim_vector(A.length()))) |
check for Inf or NaN | any(~isfinite(A)) | A.any_element_is_inf_or_nan() |
stack two matrices vertically | A=[B;C] | B.stack(C) |
uniform random matrix | rand(a,b) | octave_rand::distribution("uniform"); octave_rand::matrix(a,b) |
normal random matrix | randn(a,b) | octave_rand::distribution("normal"); octave_rand::matrix(a,b) |
sum squares of columns | sumsq(A) | A.sumsq() |
sum along columns | sum(A,1) | A.sum(0) |
sum along rows | sum(A,2) | A.sum(1) |
product along columns | prod(A,1) | A.prod(0) |
product along rows | prod(A,2) | A.prod(1) |
cumsum along columns | cumsum(A,1) | A.cumsum(0) |
cumsum along rows | cumsum(A,2) | A.cumsum(1) |
cumproduct along columns | cumprod(A,1) | A.cumprod(0) |
cumproduct along rows | cumprod(A,2) | A.cumprod(1) |
number of rows | size(A,1) | A.rows() |
number of columns | size(A,2) | A.cols() |
Notes:
- Transpose, addition, and multiplication operations also apply to RowVector, ComplexRowVector, ColumnVector, and ComplexColumnVector data types when the dimensions are in agreement.
- The difference is due to the fact that arrays are zero-based in C++, but one-based in Octave.
- The names of Octave internal functions, such as mx_el_gt, are not documented and are subject to change. Functions such as mx_el_gt may eventually be available at both the scripting level and in C++ under more common names such as gt.
Complex Matrix Operations
Operation | Octave | C++ |
conjugate tranpose | A' | A.hermitian() |
General
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
fprintf('%15.15s | %15.15s\n', Text{k,1}, Text{k,2});
The syntax '%<n>.<m>s' allocates '<n>' places to write chars and display the '<m>' first characters of the string to display.
Example:
octave:1> Text={'Hello','World'}; octave:2> fprintf('%15.15s | %15.15s\n', Text{1,1}, Text{1,2}) Hello | World
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 reshape
function
The next version of octave (3.6) implements the CollectOutput
switch as seen in example 8 here: http://www.mathworks.com/help/techdoc/ref/textscan.html
Using Variable Strings in Octave Commands
For example, to plot data using a string variable as a legend:
Option 1 (simplest):
legend = "-1;My data;"; plot(x, y, legend);
Option 2 (to insert variables):
plot(x, y, sprintf("-1;%s;", dataName));
Option 3 (not as neat):
legend = 'my legend'; plot_command = ['plot(x,y,\';',legend,';\')']; eval(plot_command);
These same tricks are useful for reading and writing data files with unique names, etc.
Vectorizing Tricks
You can easily fill a vector with an index:
for i=1:n, x(i) = i; end
x = 1:n;
This works for expressions on the index by wrapping the index in an expression:
for i=1:n, x(i) = sin(2*pi*i*f/r); end
x = sin(2*pi*(1:n)*f/r);
You can also work with other vectors this way:
for i=1:n, x(i) = sin(2*pi*y(i)*f/r); end
x = sin(2*pi*y*f/r);
Conditionals in the for loop are a little bit tricky. We need to create an index vector for the true condition, and another for the false condition, then calculate the two independently.
for i=1:n, if y(i)<1, x(i)=y(i); else x(i) = 2*y(i); endif
idx = y < 1; x(idx) = y(idx); x(!idx) = 2*y(!idx);
FIXME: add the following
- examples from matrices
- tricks with sort and cumsum (e.g., hist, lookup)
- counter-examples such as a tridiagonal solver
- sparse matrix tricks
- tricks relying on fortran indexing
Other references
- MATLAB array manipulation tips and tricks by Peter Acklam: http://home.online.no/~pjacklam/matlab/doc/mtt/index.html
- The MathWorks: Code Vectorization Guide: http://www.mathworks.com/support/tech-notes/1100/1109.html