Reputation: 5134
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++?
Upvotes: 8
Views: 3612
Reputation: 227508
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:
Upvotes: 3
Reputation: 10497
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
)
Upvotes: 2
Reputation: 368439
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:
[
Upvotes: 14