0

「シミュレーション ドメイン」をボクセル (3D ピクセル) の配列に変換する機能があります。各ボクセルは 0 または 1、または少なくともfalseまたはtrueです。ドメインが非常に大きくなる可能性があるため、離散化ステップが非常に小さくなる可能性があるため、非常に大量のメモリが必要になります。

ボクセルの配列を使用して、FFTW3 を使用して散乱シミュレーションを実行します (その場合、関数がdouble[2](FFTW3 で知られている複雑なタイプの配列で動作し、インプレース変換を実行できるように) 機能する場合は素晴らしいことです)。しかし、私がボクセルの配列を使用して「単純な」操作を実行します(たとえば、体積分率の推定)。配列を使用できる最小のタイプにしたいので、ブール値の配列で十分です。

私は次のようなことを考えていました:

#include <iostream>
int N = 10 ;


template<typename T>
void voxelizator(T* & Voxels) {
    // N = total number of voxels, stored in a row-major 1D array
    if (Voxels==NULL) Voxels = new T[N] ; //
    for (int n = 0 ;  n < N ; n++) Voxels[n] = T(0) ;
    { // Code to voxelizate the space -- DUMB condition 
        for (int n = 0 ; n<N ; n++) if (n%2==0) Voxels[n] = T(1) ;
    }
}



int main()
{
    int * voxOfInt = NULL ;
    std::cout << "Array of int :" << std::endl ;
    voxelizator(voxOfInt) ;
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfInt[n] << std::endl ;
    delete[] voxOfInt ;

    bool * voxOfBool = NULL ;
    std::cout << "Array of boolean " << std::endl ;
    voxelizator(voxOfBool) ;
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfBool[n] << std::endl ;
    delete[] voxOfBool ;

}

しかし、ISO C++ forbids casting to an array type 'double[2]'この関数を double[2] (FFTW3 の複合体) (またはこの例のように int[2] の配列) で呼び出すと、エラーが発生します:)

...    
typedef double complex [2]  ;
...
// in main {}

    complex * voxOfArray = NULL ;
    std::cout << "Array of an array " << std::endl ;
    voxelizator(voxOfArray) ; // It fails to call the T(0) at compile time, but i would be more than happy to explain g++ what is T(0) for int[2] ...
    std::cout << "Done" << std::endl ;
    for (int n = 0 ; n < N ; n++)  std::cout << n << "\t" << voxOfArray[n] << std::endl ;
    delete[] voxOfArray ;

問題は: どこで g++ に型キャストのレシピを与えることができますか?

  • T が double[2] の場合、T(0) は {0,0} に、T(1) は {1,0} に変換されますか?
  • T がブール値の場合、T(0) を FALSE に、T(1) を TRUE にしますか?

注 : 型の関数呼び出し演算子は私には奇妙に思えますが、私が既に使用している次の符号関数で問題なく動作することはわかっています (化学を行っている犬の写真をここに挿入してください。やってます」)

template <typename T> int sign(T value) {
    return (T(0) < value) - (value < T(O)) ; 
}
4

1 に答える 1

0

C++11 を使用している場合: 次のようなヘルパー構造体を使用できます。

struct voxel_t {
    double val_[2];
    voxel_t() : val_{0.0, 0.0}{};
    explicit voxel_t(bool b): val_{double(b), 0.0}{};
};

template<typename T>
void voxelizator(T* Voxels) {
    // N = total number of voxels, stored in a row-major 1D array
    if (Voxels==NULL) Voxels = new T[N]{} ; // performs below initialization
    //for (int n = 0 ;  n < N ; n++) Voxels[n] = T(0) ;  // no longer needed
    { // Code to voxelizate the space 
        for (int n = 0 ; n<N ; n++) if (is_Matter(n)) Voxels[n] = T{true};
    }
}

ideoneでの使用例。

これにより double[2] のケースが解決され、bool の場合は特別なことをする必要はありません。

于 2013-04-22T12:49:18.427 に答える