Florian Oswald
Florian Oswald

Reputation: 5134

matlab style indexing of a C++ array

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

Answers (3)

juanchopanza
juanchopanza

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

Component 10
Component 10

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

Dirk is no longer here
Dirk is no longer here

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:

  • zero-based indexing at the C++ level (which you could alter, but few C / C++ programmers will consider it a good idea)
  • certain operators, including [

Upvotes: 14

Related Questions