3

Basic question from a newcomer to Armadillo and C++ from R.

I have a vector X and I want to set the entries below 0 to a given value and the ones larger than 0 to another. Armadillo has the find function for returning indices of elements of X that are non-zero or satisfy a relational condition (not logical!?) so I can do:

arma::uvec ind0 = find(X < 0);
arma::uvec ind1 = find(X >= 0);

X(ind0).zeros();
X(ind1).fill(1);

This is clearly not the best solution. What would be a better way that does not involve calling find two times?

epsilone
  • 745
  • 11
  • 23

2 Answers2

3

You can use the .transform() member function. Requires C++11 compiler.

mat X(100,100,fill::randu);

X -= 0.5;

X.transform( [](double val) { return (val < 0) ? double(0) : double(1); } );
hbrerkere
  • 1,561
  • 8
  • 12
  • Thank you, this worked perfectly! (+1) As a small comment, if you want to use an external variable inside the lambda function it is necessary to pass it inside the square brackets (http://stackoverflow.com/questions/30217956/error-variable-cannot-be-implicitly-captured-because-no-default-capture-mode-h/30217989). – epsilone Mar 11 '16 at 14:09
2

This is what you need! It will make values smaller than 0, equal to 0 and values bigger than 1 equal to 1.

 X = clamp(X, 0, 1); 

more info at: http://arma.sourceforge.net/docs.html#clamp

Stefanos
  • 909
  • 12
  • 19