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

How to declare functions inside a test block

function experience
%!test
%! experience_design_mat
%! experience_obs_eqs
%! assert (experience_design_mat == pi);
%! assert (experience_obs_eqs == exp(1));
%!
%! endfunction  % this is a trick.
%! % now we can declare functions to be used by the test above.
%!
%! function a = experience_design_mat
%!     a = pi;
%! endfunction
%!
%! function b = experience_obs_eqs
%!     b = exp(1);
%! % endfunction: don't add it here. Let test() do it.

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