0

何千もの補間関数を多次元配列に格納したいと思います。主な問題は、私が使用する補間関数がデフォルトのコンストラクタを持たないクラスだということです。これは多次元配列を初期化することを禁じます。私は私が行うことがしたい何デフォルトのコンストラクタを使用しないでC++、boost、多次元配列にオブジェクトを格納

double func(const double& x1, const double& x2, const double& x3) 
{ 
    return x1 + x2 + x3; 
}; 

int main() 
{ 
    std::vector<double> x1 {0, 1, 2, 3}; 
    std::vector<double> x2 {1.1, 1.2, 1.3, 1.4, 1.5}; 
    std::vector<double> x3 {0, 10, 20, 30, 40}; 
    std::vector<double> y(20, std::vector<double>(5)); 

    boost::multi_array<Linear_interp, 2> Storage(boost::extents[4][5]); 

    typedef std::vector<double>::size_type vd_sz; 
    int n = 0; 
    for (vd_sz i_x1 = 0; i_x1 < x1.size(); ++i_x1) { 
    for (vd_sz i_x2 = 0; i_x2 < x2.size(); ++i_x2) { 
     for(vd_sz i_x3 = 0; i_x3 < x3.size(); ++i_x3) { 
     y[n][i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]); 
     } 
     Linear_interp myInterp(x3, y); 
     Storage[i_x1][i_x2] = myInterp; 
     ++n; 
    } 
    } 

    // Sample usage 
    double z = Storage[3][2].interp(23); 

    return 0; 
} 

問題はクラスLinear_interpにはデフォルトコンストラクタを持っていないということである(クラスがこのクラス1に似ている)、そのためには、後押し:: multi_arrayは、配列を初期化することはできません。

ループ内のすべての補間を初期化するので、これらのオブジェクトを保存する必要があります。各ループでオブジェクトが上書きされるため、オブジェクトへの単純なポインタは機能しません。

実際には、もっと多くのディメンション(atmが10個あります)があり、multi_arrayはこれを処理するのに最適なコンテナです。さらに、後のループでの補間は、以前のループから補間を取ります(つまり、再帰的な問題があります)。

EDIT 1:マイナーコード修正。

EDIT 2:コード修正:以前のバージョンでは、私は不要な結果につながる "y"を保存しませんでした。

答えて

0

よくポインタが動作します。配列を以下のように宣言する場合:

multi_array<Linear_interp*, 2> 

オブジェクト自体の代わりにオブジェクトへのポインタを格納する場合。 ループでは、必要になるたびに新しいオブジェクトを割り当てて、配列の適切な場所に配置することができます。新しいキーワードを使用して、ループ内に新しいLinear_interpオブジェクトを作成してください。ループ内部で使用するコードは次のとおりです。

Storage[i_x1][i_x2] = new Linear_interp(x3, y); 
+0

ありがとうございます。私は多かれ少なかれC + +の新しいし、 "新しい"キーワードに精通していない。ループの中に書かれたコードと、コード内のzのようなサンプル要素にどうやってアクセスするのか、いくつかのコードを投稿できますか? – USC

+0

@USC私は自分の答えを更新しました。 – fatherOfWine

+0

コードを更新した後、 'printf("%f \ n "、ストレージ[0] [0] - > interp(20))を使用して値(0,1.1,20)を評価しようとすると、 私は24.5を得るが、それは21.1でなければならない。 ループ内で結果を印刷すると、正しい結果が得られるので、最後のものを持つすべての要素をループが上書きするようです。ループの後で、私は最後の補間の結果を不変にします。 – USC

0

私はブーストエキスパートではありませんが、同等の解決策があると確信しています。以下の手順を実行できます:

空の最内側の配列で完全な「マトリックス」を構築してください。 Storage[i][j]は、既存のですが、空のstd::vector<Linear_interp>、この時点で

std::vector<std::vector<std::vector<Linear_interp>>> Storage; 
Storage.resize(x1.size()); 
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) { 
    Storage[i_x1].resize(x2.size()); 
} 

:(std::vectorを使用して)次のような何かが3寸法のために動作します。これで、Storageを記入するのにstd::vector::emplace_backまたは(::push_backとC++ 11)を使用することができます。のみコピーc'torを呼び出し、したがって、あなたのデフォルト以外の、構成可能タイプのために働くだろうpush_backまたは類似の方法を使用して

typedef std::vector<double>::size_type vd_sz; 
for (vd_sz i_x1 = 0; i_x1 < x1.size(); i_x1++) { 
    for (vd_sz i_x2 = 0; i_x2 < x2.size(); i_x2++) { 
     for(vd_sz i_x3 = 0; i_x3 < x3.size(); i_x3++) { 
     y[i_x3] = func(x1[i_x1], x2[i_x2], x3[i_x3]); 
     } 
     Storage[i_x1][i_x2].emplace_back(x3, y); 
     // or: Storage[i_x1][i_x2].push_back(Linear_interp(x3, y)); 
    } 
} 

:2次元と元のコードに戻って行くことは、このようなものは、仕事をしますLinear_interp

関連する問題