Exemple #1
0
        /// <summary>
        /// 各ベクトルの相関を求める.
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static Matrix Correlate(Matrix X, Matrix Y, Target target)
        {
            MatrixChecker.SizeEquals(X, Y);
            Matrix ret = null;

            if (target == Target.EachRow)
            {
                ret = new Matrix(X.RowSize, X.RowSize);
                for (int ry = 0; ry < ret.RowSize; ++ry)
                {
                    for (int rx = 0; rx < ret.ColumnSize; ++rx)
                    {
                        ret[ry, rx] = Correlate(Y.Rows[ry], X.Rows[rx]);
                    }
                }
            }
            else
            {
                ret = new Matrix(X.ColumnSize, X.ColumnSize);
                for (int cy = 0; cy < ret.RowSize; ++cy)
                {
                    for (int cx = 0; cx < ret.ColumnSize; ++cx)
                    {
                        ret[cy, cx] = Correlate(Y.Columns[cy], X.Columns[cx]);
                    }
                }
            }
            return(ret);
        }
Exemple #2
0
        /// <summary>
        /// 逆行列を返す.
        /// </summary>
        /// <param name="m">逆行列を求める行列(書き換えられることはない)</param>
        /// <returns></returns>
        public static Matrix Inverse(Matrix m)
        {
            MatrixChecker.IsSquare(m);
            Solved result = Func.Solve(m, (new Matrix(m.RowSize, m.ColumnSize)).Identity());

            return(result.X);
        }
Exemple #3
0
        /// <summary>
        /// 指定された行列の逆行列を作成する.
        /// </summary>
        /// <param name="X">逆行列を求める行列(書き換えられることはない)</param>
        /// <returns>Xの逆行列</returns>
        public static Matrix Inverse(Matrix X)
        {
            MatrixChecker.IsSquare(X);
            Solver solver = new Solver(X, (new Matrix(X.RowSize, X.ColumnSize)).Identity());

            return(solver.X);
        }
Exemple #4
0
        /// <summary>
        /// 固有値分解
        /// </summary>
        /// <param name="x">正方行列</param>
        /// <returns></returns>
        public static Eigen Eigen(Matrix x)
        {
            MatrixChecker.IsSquare(x);

            if (x.RowSize < 2)
            {
                throw new ArgumentException("Matrix size is less than 2.");
            }

            Matrix tmp = new Matrix(x);

            Vector _reValues = new Vector();
            Vector _imValues = new Vector();

            double[][] r_vecs = null;
            double[][] i_vecs = null;

            krdlab.law.func.dgeev(tmp._body, tmp._rsize, tmp._csize,
                                  ref _reValues._body, ref _imValues._body, ref r_vecs, ref i_vecs);

            List <Vector> _reVectors = new List <Vector>();
            List <Vector> _imVectors = new List <Vector>();

            foreach (double[] vec in r_vecs)
            {
                _reVectors.Add(new Vector(vec));
            }

            foreach (double[] vec in i_vecs)
            {
                _imVectors.Add(new Vector(vec));
            }
            return(new Eigen(_reValues, _imValues, _reVectors, _imVectors));
        }
Exemple #5
0
 /// <summary>
 /// 直接スカラ値で除算する.
 /// <code>this /= d;</code> を表しているが,代入演算子のように結果オブジェクトが生成されることはない.
 /// </summary>
 /// <param name="d">スカラ値</param>
 /// <returns>除算後の自身への参照</returns>
 /// <exception cref="Exception.ValueIsLessThanLimitException">
 /// 指定されたスカラ値が,ライブラリで扱う値の下限値未満である場合に throw される.
 /// </exception>
 public Matrix Div(double d)
 {
     MatrixChecker.ValueIsLessThanLimit(d);
     for (int i = 0; i < this._body.Length; ++i)
     {
         this._body[i] /= d;
     }
     return(this);
 }
Exemple #6
0
 /// <summary>
 /// Matrixオブジェクトを直接減算する.
 /// <code>this -= m;</code> を表しているが,代入演算子のように結果オブジェクトが生成されることはない.
 /// </summary>
 /// <param name="m">減算するMatrixオブジェクト</param>
 /// <returns>減算後の自身への参照</returns>
 /// <exception cref="Exception.MismatchSizeException">
 /// 行列のサイズが一致しなかった場合に throw される.
 /// </exception>
 public Matrix Sub(Matrix m)
 {
     MatrixChecker.SizeEquals(this, m);
     for (int i = 0; i < this._body.Length; ++i)
     {
         this._body[i] -= m._body[i];
     }
     return(this);
 }
Exemple #7
0
        /// <summary>
        /// 行ベクトルと行列の乗算
        /// </summary>
        /// <param name="rv">行ベクトル</param>
        /// <param name="m">行列</param>
        /// <returns>乗算結果の行ベクトル</returns>
        public static RowVector operator *(RowVector rv, Matrix m)
        {
            MatrixChecker.CanMultiply(rv, m);
            RowVector ret = new RowVector();

            clapack.Function.dgemv(ref ret._body, rv._body, m._body, m._rsize, m._csize);

            return(ret);
        }
Exemple #8
0
        /// <summary>
        /// 行列と列ベクトルの乗算
        /// </summary>
        /// <param name="m">行列</param>
        /// <param name="cv">列ベクトル</param>
        /// <returns>乗算結果の列ベクトル</returns>
        public static ColumnVector operator *(Matrix m, ColumnVector cv)
        {
            MatrixChecker.CanMultiply(m, cv);
            ColumnVector ret = new ColumnVector();

            clapack.Function.dgemv(ref ret._body, m._body, m._rsize, m._csize, cv._body);

            return(ret);
        }
Exemple #9
0
        /// <summary>
        /// 行ベクトルと行列の乗算
        /// </summary>
        /// <param name="rv">行ベクトル</param>
        /// <param name="m">行列</param>
        /// <returns>乗算結果の行ベクトル</returns>
        public static RowVector operator *(RowVector rv, Matrix m)
        {
            MatrixChecker.CanMultiply(rv, m);
            RowVector ret = new RowVector();

            krdlab.law.func.dgemv(ref ret._body, rv._body, m._body, m._rsize, m._csize);

            return(ret);
        }
Exemple #10
0
 /// <summary>
 /// この行列を単位行列(I = diag(1,1,...,1))にする.
 /// </summary>
 /// <returns></returns>
 public Matrix Identity()
 {
     MatrixChecker.IsSquare(this);
     this.Zero();
     for (int i = 0; i < this.RowSize; ++i)
     {
         this[i, i] = 1;
     }
     return(this);
 }
Exemple #11
0
        /// <summary>
        /// AX = B を解く.
        /// </summary>
        /// <param name="a">[n, n] 行列</param>
        /// <param name="b">[n, *] 行列</param>
        /// <returns></returns>
        public static Solved Solve(Matrix a, Matrix b)
        {
            MatrixChecker.IsSquare(a);
            Matrix _a = new Matrix(a);
            Matrix _b = new Matrix(b);
            Matrix x  = new Matrix();

            krdlab.law.func.dgesv(ref x._body, ref x._rsize, ref x._csize,
                                  _a._body, _a._rsize, _a._csize, _b._body, _b._rsize, _b._csize);
            return(new Solved(x));
        }
Exemple #12
0
        /// <summary>
        /// 行列どうしを乗算する.
        /// </summary>
        /// <param name="m1">左項となる行列</param>
        /// <param name="m2">右項となる行列</param>
        /// <returns>乗算結果の行列</returns>
        public static Matrix operator *(Matrix m1, Matrix m2)
        {
            MatrixChecker.CanMultiply(m1, m2);
            double[] ret   = null;
            int      rsize = 0;
            int      csize = 0;

            clapack.Function.dgemm(ref ret, ref rsize, ref csize,
                                   m1._body, m1._rsize, m1._csize,
                                   m2._body, m2._rsize, m2._csize);

            return(new Matrix(ret, rsize, csize));
        }
Exemple #13
0
        /// <summary>
        /// 逆行列化する.
        /// </summary>
        /// <returns>逆行列化後の自身への参照</returns>
        /// <exception cref="Exception.NotSquareMatrixException">
        /// 正方行列でないときに throw される.
        /// </exception>
        public Matrix Inverse()
        {
            MatrixChecker.IsSquare(this);

            Matrix A = new Matrix(this);

            this.Identity();

            clapack.Function.dgesv(ref this._body, ref this._rsize, ref this._csize,
                                   A._body, A._rsize, A._csize, this._body, this._rsize, this._csize);

            return(this);
        }
Exemple #14
0
        /// <summary>
        /// 逆行列化する.
        /// </summary>
        /// <returns>逆行列化後の自身への参照</returns>
        /// <exception cref="System.ArgumentException">
        /// 正方行列でないときに throw される.
        /// </exception>
        public Matrix Inverse()
        {
            MatrixChecker.IsSquare(this);

            Matrix A = new Matrix(this);

            this.Identity();

            krdlab.law.func.dgesv(ref this._body, ref this._rsize, ref this._csize,
                                  A._body, A._rsize, A._csize, this._body, this._rsize, this._csize);

            return(this);
        }
Exemple #15
0
        /// <summary>
        /// 指定されたベクトルから新しい行列を作成する.
        /// 指定された各ベクトルは,新しい行列の各列にコピーされる.
        /// </summary>
        /// <param name="arr"></param>
        public Matrix(params ColumnVector[] arr)
        {
            // 入力の検証
            VectorChecker.IsNotZeroSize(arr[0]);
            int rsize = arr[0].Size;

            MatrixChecker.EqualAllSizes(rsize, arr);
            // 構築
            int csize = arr.Length;

            Resize(rsize, csize);
            for (int c = 0; c < csize; ++c)
            {
                this.Columns[c] = arr[c];
            }
        }
Exemple #16
0
        /// <summary>
        /// ベクトル配列から新しい行列を作成する.
        /// 指定された各ベクトルは,新しい行列の各行にコピーされる.
        /// </summary>
        /// <param name="arr"></param>
        public Matrix(params RowVector[] arr)
        {
            // 入力の検証
            VectorChecker.IsNotZeroSize(arr[0]);
            int csize = arr[0].Size;

            MatrixChecker.EqualAllSizes(csize, arr);
            // 構築
            int rsize = arr.Length;

            Resize(rsize, csize);
            for (int r = 0; r < rsize; ++r)
            {
                this.Rows[r] = arr[r];
            }
        }
Exemple #17
0
        /// <summary>
        /// LU 分解
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public static Lud Lud(Matrix x)
        {
            MatrixChecker.IsNotZeroSize(x);

            Matrix lu = new Matrix(x);

            int[] p = new int[0];
            int   zeroValueIndex = -1;

            int ret = krdlab.law.func.dgetrf(lu._body, lu._rsize, lu._csize, ref p);

            if (0 < ret)
            {
                zeroValueIndex = ret - 1;
            }

            // 置換行列を構成

            /*
             * 配列 p には,例えば2行目と3行目が置換された場合に,
             *     p = {1, 3, 3};
             *            ↑1回だけ発生したということが解る
             * と格納されている.
             */
            int permutationCount = 0;

            Matrix _p = Matrix.Identity(lu.RowSize);

            // row==column, row < column の場合は p.Length == lu.RowSize
            // row > column              の場合は p.Length <  lu.RowSize

            // どうも下から入れ替えないといけないみたい
            // p[0] = 2
            // p[1] = 1
            // p[2] = 4 <- 「0と入れ替えた後の2と交換」なのか「入れ替える前の2と交換」なのか? => どうも後者のようだ
            for (int from = p.Length - 1; 0 <= from; --from)
            {
                int to = p[from];
                if (0 <= to && from != to)
                {
                    _p.Rows.Swap(from, to);
                    //this.p[from, from] = this.p[to, to] = 0;
                    //this.p[to, from] = 1;
                    //this.p[from, to] = 1;

                    if (to < p.Length && p[to] == from)
                    {
                        p[to] = -1;  // 置換が完了していることを示すフラグ
                    }

                    // 置換が発生したときだけカウントアップ
                    ++permutationCount;
                }
            }

            int    minSize = Math.Min(lu.RowSize, lu.ColumnSize);
            Matrix _l      = Matrix.Zero(lu.RowSize, minSize);
            Matrix _u      = Matrix.Zero(minSize, lu.ColumnSize);

            // set L
            for (int r = 0; r < lu.RowSize; ++r)
            {
                for (int c = 0; c <= r; ++c)
                {
                    if (_l.ColumnSize <= c)
                    {
                        break;
                    }
                    _l[r, c] = (r == c ? 1.0 : lu[r, c]);
                }
            }

            // set U
            for (int r = 0; r < _u.RowSize; ++r)
            {
                for (int c = r; c < lu.ColumnSize; ++c)
                {
                    _u[r, c] = lu[r, c];
                }
            }
            return(new Lud(_p, _l, _u, permutationCount, zeroValueIndex));
        }