I would like to know what the most efficient c++ implementation of the following matlab idiom is.
Suppose I have 3 vectors in matlab, x, y and idx.
x = [13,2,5.5,22,107]
y = [-3,100,200]
idx = [1,2,5]
I want to replace positions 1,2 and 5 of x with the contents of y. In matlab I do
x[idx] = y
What is the best way to do this in c++?
In general, you can use indexing to access elements of any array in MATLAB regardless of its data type or dimensions.
In most programming languages, the first element of an array is element 0. In MATLAB, indexes start at 1.
MATLAB does not allow an index of zero into an array unless you are performing logical indexing using a vector including a logical 0 and want to ignore the corresponding element of the array into which you are indexing.
Usage in programming languages In these three, sequence types (C arrays, Java arrays and lists, and Lisp lists and vectors) are indexed beginning with the zero subscript.
The Armadillo library probably comes closest as one of its goals is to make things easy for folks used to Matlab.
Here is a short example (and uvec
is a typdef for vector of unsigned ints)
// set four specific elements of X to 1
uvec indices;
indices << 2 << 3 << 6 << 8;
X.elem(indices) = ones<vec>(4);
Obviously, the right-hand side could be any other vector of the same dimension as the index.
But there are few language-imposed constraints you cannot overcome:
[
A loop seems simple enough, although it can be made simpler with a helper function.
// helper function to get the size of an array
template<typename T, size_t S>
constexpr size_t size(T (&)[S])
{
return S;
}
// loop
for (size_t i = 0; i < size(idx); ++i) x[idx[i]] = y[i];
Of course, here you should check that y
is large enough:
If you want it in pretty basic C++ (with no prizes for elegance) try this:
double x[] = { 13.0, 2.0, 5.5, 22.0, 107.0 };
double y[] = { -3.0, 100.0, 200.0 };
size_t idx[] = { 1, 2, 5 };
for ( size_t i = 0; i < sizeof(x)/sizeof(double); ++i )
cout << x[i] << " ";
cout << endl;
// Make a mutable copy of x
double x1[ sizeof(x)/sizeof(double) ];
std::copy( x, x + sizeof(x)/sizeof(double), x1 );
// The transformation
for ( size_t i = 0; i < sizeof(idx)/sizeof(double); ++i )
x1[idx[i]] = y[i];
for ( size_t i = 0; i < sizeof(x)/sizeof(double); ++i )
cout << x1[i] << " ";
cout << endl;
Note exactly pretty, but it does give the following:
13 2 5.5 22 107
-3 100 5.5 22 200
(Note that I've assumed that the indexing starts from 1 rather than 0 in idx
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With