题
我不时使用以下代码生成矩阵样式数据架构
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?凌乱,但有可能带有宏观魔术。 (您要达到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]
. 。如果需要的话,您可以将所有内容包装在更多的宏中,但是在内存管理和访问方面,它效率更高。
其他提示
我需要一个非常简单的矩阵来进行一次性项目,然后将这个矩阵击倒。这不是我所说的生产质量,但它可能会给您一些想法:
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;
};
如先前的注释所建议的,使用线性内存的行矩阵:
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];
}
不隶属于 StackOverflow