1

我不时使用以下代码生成矩阵样式数据结构

typedef double myType;

typedef struct matrix_t{                                                             |Compilation started at Mon Apr  5 02:24:15
  myType **matrix;                                                                   |
  size_t x;                                                                          |gcc structreaderGeneral.c -std=gnu99 -lz
  size_t y;                                                                          |
}matrix;                                                                             |Compilation finished at Mon Apr  5 02:24:15
                                                                                     |
                                                                                     |
matrix alloc_matrix(size_t x, size_t y){                                             |
  if(0)                                                                              |
    fprintf(stderr,"\t-> Alloc matrix with dim (%lu,%lu) byteprline=%lu bytetotal:%l\|
u\n",x,y,y*sizeof(myType),x*y*sizeof(myType));                                       |
                                                                                     |
  myType **m = (myType **)malloc(x*sizeof(myType **));                               |
  for(size_t i=0;i<x;i++)                                                            |
    m[i] =(myType *) malloc(y*sizeof(myType *));                                     |
                                                                                     |
  matrix ret;                                                                        |
  ret.x=x;                                                                           |
  ret.y=y;                                                                           |
  ret.matrix=m;                                                                      |
  return ret;                                                                        |
} 

然后,如果我的矩阵中的条目需要不同类型的类型,我会相应地更改我的 typedef。

现在我需要 2 个不同类型的矩阵,一个简单的解决方案是复制/粘贴代码,但是有什么方法可以做一个更通用的实现。

谢谢

编辑:我应该澄清它在 c 中而不是 c++ 中。很抱歉没有说清楚。

4

3 回答 3

3

在 C? 凌乱,但可以使用宏魔法。(您已经到了 C++ 是更好选择的地步,顺便说一句)。

#define DECL_MATRIX(type,name) \
    typedef struct matrix_##type##_t {             \
        type **matrix;                             \
        size_t x;                                  \
        size_t y;                                  \
    } name;                                        \
    name alloc_##name(size_t x,size_t y)

#define DEFINE_MATRIX_OPS(type,name) \
    struct matrix_##type##_t                       \
    alloc_##name(size_t x, size_t y) {             \
        size_t i;                                  \
        struct matrix_##type##_t ret;              \
        type **m;                                  \
                                                   \
        m = (type **)malloc(x*sizeof(type *));     \
        for(size_t i=0;i<x;i++)                    \
            m[i] =(type *) malloc(y*sizeof(type)); \
        ret.x=x;                                   \
        ret.y=y;                                   \
        ret.matrix=m;                              \
        return ret;                                \
    }

然后你会像这样使用这些:

// At the top level of the file
DECL_MATRIX(double, dmat);
DECL_MATRIX(int, imat);
DEFINE_MATRIX_OPS(double, dmat);
DEFINE_MATRIX_OPS(int, imat);

// In a function
dmat d = alloc_dmat(3,3);
imat i = alloc_imat(2,6);

作为设计说明,固定大小的矩阵最好将元素的内存分配为单个块,并使用一些数学来索引它们。因此,而不是ary[a][b]你使用ary[a*x_size+y]. 如果需要,您可以将所有这些都包含在更多的宏中,但是在内存管理和访问方面都更加高效。

于 2010-04-05T12:25:20.610 回答
1

我需要一个非常简单的矩阵来完成一次性项目,然后把它搞定了。这不是我所说的生产质量,但它可能会给你一些想法:

template <typename T>
class Matrix2D {

    public:

        Matrix2D( unsigned int  width, unsigned int  height,
                            const T & v  = T() ) {
            if ( width == 0 || height == 0 ) {
                throw std::out_of_range( "Invalid Matrix2D size ");
            }
            for ( unsigned int x = 0; x < width; x++ ) {
                mData.push_back( std::vector<T>( height, v ) );
            }
        }

        T & operator()( unsigned int x, unsigned int y ) {
            if ( x >= Width() || y >= Height() ) {
                throw std::range_error( "Invalid Matrix2D index" );
            }
            return mData[x][y];
        }

        const T & operator()( unsigned int x, unsigned int y ) const {
            if ( x >= Width() || y >= Height() ) {
                throw std::range_error( "Invalid Matrix2D index" );
            }
            return mData[x][y];
        }


        void Clear( const T & v  = T() ) {
            for ( unsigned int x = 0; x < Width(); x++ ) {
                for ( unsigned int y = 0; y < Height(); y++ ) {
                    mData[x][y] = v;
                }
            }
        }

        unsigned int Width() const {
            return mData.size();
        }

        unsigned int Height() const {
            return mData[0].size();
        }

        void DumpOn( std::ostream & os ) {
            for ( unsigned int y = 0; y < Height(); y++ ) {
                for ( unsigned int x = 0; x < Width(); x++ ) {
                    os << '[' << mData[x][y] << ']';
                }
                os << "\n";
            }
        }

    private:

        std::vector <std::vector  <T> > mData;
};
于 2010-04-05T09:53:31.730 回答
0

正如之前的评论所建议的,使用线性内存的行主矩阵:

template<typename T, unsigned int DIM>
class matrix {
    public:
        matrix<T,DIM>() {
            matrix(0);
        }
        matrix<T,DIM>(const T* v) {
            for (unsigned int i=0; i<DIM*DIM; ++i)
                value[i] = v[i];
        }
        matrix<T,DIM>(T v) {
            for (unsigned int i=0; i<DIM*DIM; ++i)
                value[i] = v;
        }
        T& operator[](int index) {
            assert(index >= 0 && index < (int)(DIM*DIM));
            return value[index];
        }

        // and so on...

    private:
        T value[DIM * DIM];
}
于 2010-04-05T11:52:51.023 回答