public void Test02()
        {
            const double angle = Math.PI / 6;
            Matrix X = new Matrix(new RowVector(Math.Cos(angle), -Math.Sin(angle), 0),
                                    new RowVector(Math.Sin(angle), Math.Cos(angle), 0),
                                    new RowVector(0, 0, 1));

            EigenvalueDecomposition evd = new EigenvalueDecomposition(X);
            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            Assert.IsTrue(evd.HasComplexValue);

            List<Complex> cv = new List<Complex>();
            int count = evd.RealEigenvalues.Size;
            for (int i = 0; i < count; ++i)
            {
                cv.Add(new Complex(evd.RealEigenvalues[i], evd.ImaginaryEigenvalues[i]));
            }

            Assert.AreEqual(1, (cv[0] * cv[1] * cv[2]).Size, LisysConfig.CalculationLowerLimit);

            Assert.AreEqual(new Complex(1, 0), cv[0]);
            Assert.AreEqual(new Complex(Math.Cos(angle), -Math.Sin(angle)), cv[1]);
            Assert.AreEqual(new Complex(Math.Cos(angle),  Math.Sin(angle)), cv[2]);
        }
        /// <summary>
        /// �s�� X �Ɏ听�����͂�K�p����D
        /// </summary>
        /// <param name="X">
        /// <para>[n, d]�̍s��i�����������邱�Ƃ͂Ȃ��j</para>
        /// <para>�f�[�^���Fn�C�������Fd�Ƃ����Ƃ��C�s�� X �̌`���� n�~d �łȂ���΂Ȃ�Ȃ��D</para>
        /// </param>
        /// <param name="varType">���U�̎��</param>
        public PrincipalComponentAnalysis(Matrix X, VarianceType varType)
        {
            Matrix _X = new Matrix(X);

            // �e�ϐ��̕��ϒl��0�ɂ���
            Vector colAvg = _X.ColumnAverages;
            _X.Columns.ForEach(delegate(int i, IVector v)
            {
                v.ForEach(delegate(ref double val)
                {
                    val -= colAvg[i];
                });
            });

            // ���U�E�����U�s��
            Matrix S = Matrix.Transpose(_X) * _X;
            if (varType == VarianceType.DivN)
            {
                S /= _X.RowSize;
            }
            else
            {
                S /= (_X.RowSize - 1);
            }

            // �ŗL�l����
            EigenvalueDecomposition evd = new EigenvalueDecomposition(S);
            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            this.eigenvalues = evd.RealEigenvalues;
            this.eigenvectors = evd.RealEigenvectors;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 行列 X に主成分分析を適用する.
        /// </summary>
        /// <param name="X">
        /// <para>[n, d]の行列(書き換えられることはない)</para>
        /// <para>データ数:n,次元数:dとしたとき,行列 X の形式は n×d でなければならない.</para>
        /// </param>
        /// <param name="varType">分散の種類</param>
        public PrincipalComponentAnalysis(Matrix X, VarianceType varType)
        {
            Matrix _X = new Matrix(X);

            // 各変数の平均値を0にする
            Vector colAvg = _X.ColumnAverages;

            _X.Columns.ForEach(delegate(int i, IVector v)
            {
                v.ForEach(delegate(ref double val)
                {
                    val -= colAvg[i];
                });
            });

            // 分散・共分散行列
            Matrix S = Matrix.Transpose(_X) * _X;

            if (varType == VarianceType.DivN)
            {
                S /= _X.RowSize;
            }
            else
            {
                S /= (_X.RowSize - 1);
            }

            // 固有値分解
            EigenvalueDecomposition evd = new EigenvalueDecomposition(S);

            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            this.eigenvalues  = evd.RealEigenvalues;
            this.eigenvectors = evd.RealEigenvectors;
        }
        /// <summary>
        /// 判別関数(係数ベクトル)を求める.
        /// </summary>
        /// <param name="Xs">
        /// <para>各郡のMatrixオブジェクト(各行はデータに,各列は各変数に対応する)の配列</para>
        /// <para>
        /// 1つの群データは,1つの<see cref="Matrix"/>オブジェクトであらわされており,
        /// 本処理により書き換えられることはない(read-only).
        /// </para>
        /// </param>
        public MultipleDiscriminantAnalysis(Matrix[] Xs)
        {
            int C = Xs.Length;           // 群数

            int[] ns = new int[C];       // 各群のデータ数
            int   p  = Xs[0].ColumnSize; // 次元数

            // 各郡のデータ数を取得
            for (int k = 0; k < C; ++k)
            {
                ns[k] = Xs[k].RowSize;
            }

            Vector tAvg = new Vector(p);    // 全データにおける各次元の平均値

            tAvg.Zero();

            int tN = 0;                    // 全データ数

            Vector[] avgs = new Vector[C]; // 各群における各次元の平均値
            for (int k = 0; k < C; ++k)
            {
                tN     += Xs[k].RowSize;
                avgs[k] = Xs[k].ColumnAverages;

                tAvg.ForEach(delegate(int i, ref double val)
                {
                    val += Xs[k].Columns[i].Sum;
                });
            }
            tAvg /= tN;

            Matrix B = new Matrix(p, p);

            for (int k = 0; k < C; ++k)
            {
                IVector dv = avgs[k] - tAvg;
                B += (ns[k] * new ColumnVector(dv) * new RowVector(dv));
            }

            Matrix W = new Matrix(p, p);

            for (int k = 0; k < C; ++k)
            {
                for (int i = 0; i < ns[k]; ++i)
                {
                    IVector dv = Xs[k].Rows[i] - avgs[k];
                    W += (new ColumnVector(dv) * new RowVector(dv));
                }
            }

            EigenvalueDecomposition evd = new EigenvalueDecomposition(Matrix.Inverse(W) * B);

            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            this.eigenvalues  = evd.RealEigenvalues;
            this.eigenvectors = evd.RealEigenvectors;
        }
        /// <summary>
        /// ���ʊ֐��i�W���x�N�g���j����߂�D
        /// </summary>
        /// <param name="Xs">
        /// <para>�e�S��Matrix�I�u�W�F�N�g�i�e�s�̓f�[�^�ɁC�e��͊e�ϐ��ɑΉ�����j�̔z��</para>
        /// <para>
        /// 1�‚̌Q�f�[�^�́C1�‚�<see cref="Matrix"/>�I�u�W�F�N�g�ł���킳��Ă���C
        /// �{�����ɂ�菑���������邱�Ƃ͂Ȃ��iread-only�j�D
        /// </para>
        /// </param>
        public MultipleDiscriminantAnalysis(Matrix[] Xs)
        {
            int C = Xs.Length;          // �Q��
            int[] ns = new int[C];      // �e�Q�̃f�[�^��
            int p = Xs[0].ColumnSize;   // ������

            // �e�S�̃f�[�^����擾
            for (int k = 0; k < C; ++k)
            {
                ns[k] = Xs[k].RowSize;
            }

            Vector tAvg = new Vector(p);    // �S�f�[�^�ɂ�����e�����̕��ϒl
            tAvg.Zero();

            int tN = 0; // �S�f�[�^��

            Vector[] avgs = new Vector[C];  // �e�Q�ɂ�����e�����̕��ϒl
            for (int k = 0; k < C; ++k)
            {
                tN += Xs[k].RowSize;
                avgs[k] = Xs[k].ColumnAverages;

                tAvg.ForEach(delegate(int i, ref double val)
                {
                    val += Xs[k].Columns[i].Sum;
                });
            }
            tAvg /= tN;

            Matrix B = new Matrix(p, p);
            for (int k = 0; k < C; ++k)
            {
                IVector dv = avgs[k] - tAvg;
                B += (ns[k] * new ColumnVector(dv) * new RowVector(dv));
            }

            Matrix W = new Matrix(p, p);
            for (int k = 0; k < C; ++k)
            {
                for (int i = 0; i < ns[k]; ++i)
                {
                    IVector dv = Xs[k].Rows[i] - avgs[k];
                    W += (new ColumnVector(dv) * new RowVector(dv));
                }
            }

            EigenvalueDecomposition evd = new EigenvalueDecomposition(Matrix.Inverse(W) * B);
            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            this.eigenvalues = evd.RealEigenvalues;
            this.eigenvectors = evd.RealEigenvectors;
        }
        public void Test01()
        {
            Matrix X = new Matrix(  new RowVector(1, 0, 2),
                                    new RowVector(0, 1, 0),
                                    new RowVector(2, 0, 1));

            Assert.IsTrue(X.IsSymmetric);

            EigenvalueDecomposition evd = new EigenvalueDecomposition(X);
            evd.Sort(EigenvalueDecomposition.SortOrder.Descending);

            Assert.AreEqual( 3, evd.RealEigenvalues[0], LisysConfig.CalculationLowerLimit);
            Assert.AreEqual( 1, evd.RealEigenvalues[1], LisysConfig.CalculationLowerLimit);
            Assert.AreEqual(-1, evd.RealEigenvalues[2], LisysConfig.CalculationLowerLimit);

            Assert.AreEqual(new Vector(1 / Math.Sqrt(2), 0, 1 / Math.Sqrt(2)), evd.RealEigenvectors[0]);
            Assert.AreEqual(new Vector(0, 1, 0), evd.RealEigenvectors[1]);
            Assert.AreEqual(new Vector(-1 / Math.Sqrt(2), 0, 1 / Math.Sqrt(2)), evd.RealEigenvectors[2]);
        }