#ifndef __JBXL_CPP_MATRIX_H_ #define __JBXL_CPP_MATRIX_H_ /** マトリックス ライブラリ template class Matrix template void print_Matrix(Matrix a) */ #include "common++.h" #include "tools++.h" #include #include #ifndef va_start #include #endif // namespace jbxl { /** template class Matrix 多次元マトリックス型 Matrix の定義 int n 次元数 int r 全要素数 sz[0]*sz[1]*...*sz[n-1] int *sz 各次元の要素数 sz[0]〜sz[n-1] int *mx 要素 mx[0]〜mx[r-1] 注: Matrix型の引数は (行, 列, ....)となるので,直接メモリにアクセスする場合は注意が必要である.  2次元(3x3)の場合...., (1,1), (1,2), (1,3), (2,1), (2,2), (2,3), (3,1), .... 3次元(2x2x2)の場合... (1,1,1), (1,1,2), (1,2,1), (1,2,2), (2,1,1), .... */ template class Matrix { public: int n; int r; int* sz; T* mx; T err; // エラー時にこれを参照用として返す. public: Matrix() { init();} Matrix(int nn, ...); ~Matrix() {} // 関数にコピー渡しした場合に,関数内でディストラクトされても良い様に free() は使用しない. void init() { n=r=0; err=(T)0; sz=NULL; mx=NULL;} void init(int nn, ...); void getm(int nn, int* size); T& element(int i, ...); void clear(T v=T(0)) { for(int i=0;i Matrix::Matrix(int nn, ...) 機能: コンストラクタ 引数: n -- マトリックスの次元数. ... -- 各次元の要素数. 例: Matrix(2, 3, 4) --- 3x4 の2次元マトリックス Matrix(3, 2, 4, 3) -- 2x4x3 の3次元マトリックス */ template Matrix::Matrix(int nn, ...) { r = 0; n = nn; err = (T)0; mx = NULL; sz = (int*)malloc(n*sizeof(int)); if (sz==NULL) return; va_list argsptr; va_start(argsptr, nn); r = 1; for (int i=0; i void Matrix::init(int nn, ...) 機能: 現在のバッファ部をクリアして,任意(n)次元の実数マトリックスの バッファ部をつくり出す.要素自体は (T)0に初期化される. 現在のバッファ部をクリアする以外は,コンストラクタと同じ. 引数: n -- マトリックスの次元数. ... -- 各次元の要素数. */ template void Matrix::init(int nn, ...) { if (sz!=NULL) ::free(sz); if (mx!=NULL) ::free(mx); r = 0; n = nn; err = (T)0; mx = NULL; sz = (int*)malloc(n*sizeof(int)); if (sz==NULL) return; va_list argsptr; va_start(argsptr, nn); r = 1; for (int i=0; i void Matrix::getm(int nn, int* size) 機能: 現在のバッファ部をクリアして,任意(n)次元の実数マトリックスの バッファ部をつくり出す.要素自体は (T)0に初期化される. init() とは引数の形が違うだけ 引数: n -- マトリックスの次元数. sz[0]〜sz[n-1] -- 各次元の要素数. */ template void Matrix::getm(int nn, int* size) { if (sz!=NULL) ::free(sz); if (mx!=NULL) ::free(mx); r = 0; n = nn; err = (T)0; mx = NULL; sz = (int*)malloc(n*sizeof(int)); if (sz==NULL) return; r = 1; for (int i=0; i T& Matrix::element(int i, ...) Matrix の要素を返す.次元数に制限はない.インデックスは1から数える(0からではない). 参考:1次元配列へのアクセスインデックス 1次元: element(i) (i-1) 2次元: element(i,j) (j-1) + sz[1]*(i-1) 3次元: element(i,j,k) (k-1) + sz[2]*(j-1) + sz[1]*sz[2]*(i-1) 4次元: element(i,j,k,l) (l-1) + sz[3]*(k-1) + sz[2]*sz[3]*(j-1) + sz[1]*sz[2]*sz[3]*(i-1) ................... */ template T& Matrix::element(int i, ...) { int* args; va_list argsptr; args = (int*)malloc(n*sizeof(int)); if (args==NULL) return err; va_start(argsptr, i); args[0] = i; for (int m=1; m=r || dx<0) return err; return mx[dx]; } /** template void print_Matrix(FILE* fp, Matrix a) 機能: 実数マトリックスの要素を標準出力に書き出す.デバッグ用. 引数: a -- プリントするマトリックス. 戻り値: なし. */ template void print_Matrix(FILE* fp, Matrix a) { for (int i=0; i Matrix operator * (const Matrix a, const Matrix b) 機能: マトリックスのかけ算. マトリックス a, bをかけ算して,結果のマトリックスを返す. 引数: a -- かけられるマトリックス. b -- かけるマトリックス. 戻り値: かけ算結果のマトリックス. 掛け算不能,または失敗の場合は空のマトリックス. */ template Matrix operator * (const Matrix a, const Matrix b) { int i, j, k, n, ii, aa, bb; int *sz, *sa, *sb, *sc, *cx; T st; Matrix c; if (a.mx==NULL || b.mx==NULL) return c; if (a.sz[a.n-1]!=b.sz[0]) return c; n = a.n + b.n - 2; sz = (int*)malloc(n*sizeof(int)); if (sz==NULL) return c; sa = (int*)malloc(a.n*sizeof(int)); if (sa==NULL) {free(sz); return c;} sb = (int*)malloc(b.n*sizeof(int)); if (sb==NULL) {free(sz); free(sa); return c;} sc = (int*)malloc(n*sizeof(int)); if (sc==NULL) {free(sz); free(sa); free(sb); return c;} cx = (int*)malloc(n*sizeof(int)); if (cx==NULL) {free(sz); free(sa); free(sb); free(sc); return c;} for (i=0; i=0; i--) sa[i] = sa[i+1]*a.sz[i+1]; for (i=b.n-2; i>=0; i--) sb[i] = sb[i+1]*b.sz[i+1]; for (i=n-2; i>=0; i--) sc[i] = sc[i+1]*sz[i+1]; c.getm(n, sz); if (c.sz!=NULL) { for (i=0; i inline Matrix operator - (const Matrix a) { Matrix c(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline Matrix operator + (const Matrix a, const Matrix b) { Matrix c; if (!isSameDimension(a, b)) return c; c.getm(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline Matrix operator - (const Matrix a, const Matrix b) { Matrix c; if (!isSameDimension(a, b)) return c; c.getm(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline Matrix operator * (const R d, const Matrix a) { Matrix c(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline Matrix operator * (const Matrix a, const R d) { Matrix c(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline Matrix operator / (const Matrix a, const R d) { Matrix c(a.n, a.sz); if (c.mx!=NULL) for (int i=0; i inline bool operator == (const Matrix v1, const Matrix v2) { if (!isSameDimension(v1, v2)) return false; for (int i=0; i inline bool isSameDimension(const Matrix v1, const Matrix v2) { if (v1.n!=v2.n || v1.r!=v2.r) return false; for (int i=0; i