次の matlab イディオムの最も効率的な C++ 実装を知りたいです。
matlab、x、y、および idx に 3 つのベクトルがあるとします。
x = [13,2,5.5,22,107]
y = [-3,100,200]
idx = [1,2,5]
x の位置 1、2、および 5 を y の内容に置き換えたい。matlabで私は
x[idx] = y
C ++でこれを行う最良の方法は何ですか?
Armadilloライブラリは、その目標の 1 つは、Matlab に慣れている人々にとって物事を簡単にすることであるため、おそらく最も近いものです。
以下に短い例を示します (uvec
これは unsigned int のベクトルの typdef です)。
// set four specific elements of X to 1
uvec indices;
indices << 2 << 3 << 6 << 8;
X.elem(indices) = ones<vec>(4);
明らかに、右側はインデックスと同じ次元の他のベクトルである可能性があります。
ただし、克服できない言語上の制約がいくつかあります。
[
ループは単純に見えますが、ヘルパー関数を使用して単純化することもできます。
// 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];
もちろん、ここでy
は十分な大きさであることを確認する必要があります。
かなり基本的な C++ (エレガンスの賞品なし) でそれが必要な場合は、これを試してください。
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;
正確にかなり注意してください、しかしそれは次を与えます:
13 2 5.5 22 107
-3 100 5.5 22 200
(インデックスは 0 ではなく 1 から始まると想定していることに注意してくださいidx
)