Tips and tricks: Difference between revisions

From Octave
Jump to navigation Jump to search
m (→‎Changing BLAS: Should not write as if all Linux workstations used apt-get)
 
(4 intermediate revisions by 3 users not shown)
Line 59: Line 59:
=== 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 fewwer 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 fewer characters).


{{Code|alias to help|<pre>
{{Code|alias to help|<pre>
Line 78: Line 78:
<tr><td>element multiplication</td><td><code>A.*B</code></td><td><code>product(A,B) </code></td></tr>
<tr><td>element multiplication</td><td><code>A.*B</code></td><td><code>product(A,B) </code></td></tr>
<tr><td>element division</td><td><code>A./B</code></td><td><code>quotient(A,B) </code></td></tr>
<tr><td>element division</td><td><code>A./B</code></td><td><code>quotient(A,B) </code></td></tr>
<tr><td>transpose*</td><td><code>A'</code></td><td><code>A.transpose()</code></td></tr>
<tr><td>transpose*</td><td><code>A.'</code></td><td><code>A.transpose()</code></td></tr>
<tr><td>select element m,n of A**</td><td><code>A(m,n)</code></td><td><code>A(m-1,n-1)</code></td></tr>
<tr><td>select element m,n of A**</td><td><code>A(m,n)</code></td><td><code>A(m-1,n-1)</code></td></tr>
<tr><td>select row N of A**</td><td><code>A(N,:)</code></td><td><code>A.row(N-1)</code></td></tr>
<tr><td>select row N of A**</td><td><code>A(N,:)</code></td><td><code>A.row(N-1)</code></td></tr>
Line 113: Line 113:
<tr><td>number of rows</td><td><code>size(A,1)</code></td><td><code>A.rows()</code></td></tr>
<tr><td>number of rows</td><td><code>size(A,1)</code></td><td><code>A.rows()</code></td></tr>
<tr><td>number of columns</td><td><code>size(A,2)</code></td><td><code>A.cols()</code></td></tr>
<tr><td>number of columns</td><td><code>size(A,2)</code></td><td><code>A.cols()</code></td></tr>
<tr><td>range</td><td><code>0.1:0.2:0.9</code></td><td><code>Range (0.1, 0.9, 0.2).matrix_value ()</code></td></tr>
</table>
</table>


Line 169: Line 170:
====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: https://web.archive.org/web/20151030212438/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


[[Category:Tips and tricks]]
[[Category:Tips and tricks]]


===Changing BLAS===
===Changing BLAS===


Many Octave functions are wrappers to optimized numerical libraries, notably BLAS and ATLAS. It is possible to achieve impressive performance gains by simply using a library tuned to your platform. One example is using OpenBLAS to replace the default BLAS implementation ([http://www.stat.cmu.edu/~nmv/2013/07/09/for-faster-r-use-openblas-instead-better-than-atlas-trivial-to-switch-to-on-ubuntu/ further details]).
Many Octave functions are wrappers to optimized numerical libraries, notably BLAS and ATLAS. It is possible to achieve impressive performance gains by simply using a library tuned to your platform. One example is using OpenBLAS to replace the default BLAS implementation ([https://web.archive.org/web/20140217072457/http://www.stat.cmu.edu/~nmv/2013/07/09/for-faster-r-use-openblas-instead-better-than-atlas-trivial-to-switch-to-on-ubuntu/ further details]).


On some Linux distributions, this just takes a few commands. For instance, on Ubuntu, it usually suffices to run
On some Linux distributions, this just takes a few commands. For instance, on Ubuntu, it usually suffices to run

Latest revision as of 21:00, 14 August 2022

Preferences[edit]

Sometimes, Octave defaults are not the best for someone's specific use. To change the defaults, use the following on the .octaverc file.

Changing default figure size[edit]

The default size of a figure may be appropriate for simple figures but not so much when using subplot for example. This can be changed though.

Code: change default figure size
set (0, 'DefaultFigurePosition', [1 get(0, "screensize")(4:-1:3) get(0, "DefaultFigurePosition")(4)]);

The value of DefaultFigurePosition must be a four element vector with the x and y coordinates for the figure, followed by its width and height. The code above sets the default image to be placed at the top of the monitor, with the width of the monitor and the same height previously set as default.

Changing default font for axes[edit]

To display tex characters such as '\alpha' or '\lambda', a TrueType font ("arial" for instance) is better for the gnuplot backend [1]

Code: change default axes font name
set (0, "DefaultAxesFontName", "Arial")

It can then be necessary to change the font size as well

Code: change default axes font size
set(0, 'DefaultAxesFontSize', 10)


Shorten help message[edit]

To get rid of the long help message with the link to the Octave homepage place this in your startup file usually at ~/.octaverc (if it does not exist, create it). See the documentation for more information.

suppress_verbose_help_message(1)

Tiny helper functions[edit]

This is a list of tiny helper functions (the equivalent of e.g., shell aliases), the kind one would have on its .octaverc file.

Reload 'octave.rc' after 'clear'[edit]

When using clear, one may accidentally remove functions (alias) or other variables set on the octave.rc file. This can fixed by shadowing the clear function with the following:

Code: reload octave.rc after clear
function clear (varargin)
  args = sprintf (', "%s"', varargin{:});
  evalin ("caller", ['builtin ("clear"' args ')']);
  source ("~/.octaverc");
endfunction

The problem with this approach is if there's path manipulation on the octave.rc file, such as addpath. A workaround is needed for each case since it is not possible to obtain a reliable list of what's in Octave load path. But basically should be to undo what the file does, before source ("~/.octaverc").

If there's a pkg unload all on it, this would also unload all packages. The following adjustment will keep the packages loaded

Code: reload octave.rc after clear but keep packages loaded
function clear (varargin)
  args = sprintf (', "%s"', varargin{:});
  evalin ("caller", ['builtin ("clear"' args ')']);
  pkglist = pkg ("list");
  loadedpkg = cell (0);
  for ii = 1:numel (pkglist)
    if (pkglist{ii}.loaded)
      loadedpkg{end+1} = pkglist{ii}.name;
    endif
  endfor
  source ("~/.octaverc");
  if (numel (loadedpkg) != 0)
    pkg ("load", loadedpkg{:});
  endif
endfunction


replace help with man[edit]

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 fewer characters).

Code: alias to help
 function man (name)
   help (char (name))
 endfunction

C++[edit]

Real matrix operations[edit]

This is a table of matrix operations commonly performed in Octave and their equivalents in C++ when using the octave libraries.

OperationOctaveC++
addA+BA+B
subtractA-BA-B
matrix multiplicationA*BA*B
element multiplicationA.*Bproduct(A,B)
element divisionA./Bquotient(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 AA(a:b,c:d)A.extract(a-1,c-1,b-1,d-1)
absolute value of Aabs(A)A.abs()
comparison to scalar***A>2mx_el_gt(A,2)
A<2mx_el_lt(A,2)
A==2mx_el_eq(A,2)
A~=2mx_el_ne(A,2)
A>=2mx_el_ge(A,2)
A<=2mx_el_le(A,2)
matrix of zerosA=zeros(m,n)A.fill(0.0)
matrix of onesA=ones(m,n)A.fill(1.0)
identity matrixeye(N)identity_matrix(N,N)
inverse of Ainv(A)A.inverse()
pseudoinverse of Apinv(A)A.pseudo_inverse()
diagonal elements of Adiag(A)A.diag()
column vectorA(:)ColumnVector(A.reshape (dim_vector(A.length())))
row vectorA(:)'RowVector(A.reshape (dim_vector(A.length())))
check for Inf or NaNany(~isfinite(A))A.any_element_is_inf_or_nan()
stack two matrices verticallyA=[B;C]B.stack(C)
uniform random matrixrand(a,b)octave_rand::distribution("uniform"); octave_rand::matrix(a,b)
normal random matrixrandn(a,b)octave_rand::distribution("normal"); octave_rand::matrix(a,b)
sum squares of columnssumsq(A)A.sumsq()
sum along columnssum(A,1)A.sum(0)
sum along rowssum(A,2)A.sum(1)
product along columnsprod(A,1)A.prod(0)
product along rowsprod(A,2)A.prod(1)
cumsum along columnscumsum(A,1)A.cumsum(0)
cumsum along rowscumsum(A,2)A.cumsum(1)
cumproduct along columnscumprod(A,1)A.cumprod(0)
cumproduct along rowscumprod(A,2)A.cumprod(1)
number of rowssize(A,1)A.rows()
number of columnssize(A,2)A.cols()
range0.1:0.2:0.9Range (0.1, 0.9, 0.2).matrix_value ()

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[edit]

OperationOctaveC++
conjugate tranposeA'A.hermitian()

General[edit]

Vectorizing Tricks[edit]

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[edit]

Changing BLAS[edit]

Many Octave functions are wrappers to optimized numerical libraries, notably BLAS and ATLAS. It is possible to achieve impressive performance gains by simply using a library tuned to your platform. One example is using OpenBLAS to replace the default BLAS implementation (further details).

On some Linux distributions, this just takes a few commands. For instance, on Ubuntu, it usually suffices to run

sudo apt-get install libopenblas-base libatlas3gf-base

followed by

sudo update-alternatives --config libblas.so.3

and then selecting the openblas option.