示例#1
0
        /// <summary>
        /// 接続行列AとA^T*CAを表示。
        /// </summary>
        private void CalcConnectionMat()
        {
            var pList = mDGEditor.PointList();
            var eList = mDGEditor.EdgeList();

            if (pList.Count == 0 || eList.Count == 0)
            {
                return;
            }

            var A = CalcA();

            AddLog(string.Format("A: {0}", A.ToString()));

            var C = CalcC();

            AddLog(string.Format("C: {0}", C.ToString()));

            var CA = WWMatrix.Mul(C, A);

            var AT = A.Transpose();

            var AT_CA = WWMatrix.Mul(AT, CA);

            AddLog(string.Format("A^T*CA: {0}", AT_CA.ToString()));
        }
示例#2
0
        public void MatrixLU()
        {
            int N = 2;
            var A = new WWMatrix(N, N, new double[]
                                 { 4, 3,
                                   6, 3 });

            WWMatrix L;
            WWMatrix U;
            var      result = WWMatrix.LUdecompose(A, out L, out U);

            Assert.IsTrue(result == WWMatrix.ResultEnum.Success);

            // Lは下三角行列。
            var Ltype = L.DetermineMatType();

            Assert.IsTrue(0 != (Ltype & (ulong)WWMatrix.MatType.LowerTriangular));

            // Uは上三角行列。
            var Utype = U.DetermineMatType();

            Assert.IsTrue(0 != (Utype & (ulong)WWMatrix.MatType.UpperTriangular));

            // L * U = A
            WWMatrix Arecovered = WWMatrix.Mul(L, U);

            Assert.IsTrue(WWMatrix.IsSame(A, Arecovered));
        }
示例#3
0
        public void MatrixLPU_4x4()
        {
            int N = 4;

            var r = new Random();

            for (int i = 0; i < 1000; ++i)
            {
                var A = new WWMatrix(N, N, new double[]
                                     { r.Next(10), r.Next(10), r.Next(10), r.Next(10),
                                       r.Next(10), r.Next(10), r.Next(10), r.Next(10),
                                       r.Next(10), r.Next(10), r.Next(10), r.Next(10),
                                       r.Next(10), r.Next(10), r.Next(10), r.Next(10) });

                WWMatrix P;
                WWMatrix L;
                WWMatrix U;
                var      result = WWMatrix.LUdecompose2(A, out L, out P, out U);
                if (result == WWMatrix.ResultEnum.FailedToChoosePivot)
                {
                    continue;
                }
                Assert.IsTrue(result == WWMatrix.ResultEnum.Success);

                // Lは下三角行列。
                var Ltype = L.DetermineMatType();
                Assert.IsTrue(0 != (Ltype & (ulong)WWMatrix.MatType.LowerTriangular));

                // Uは上三角行列。
                var Utype = U.DetermineMatType();
                Assert.IsTrue(0 != (Utype & (ulong)WWMatrix.MatType.UpperTriangular));

                A.Print("A");
                L.Print("L");
                U.Print("U");
                P.Print("P");

                // P * A = L * U
                var LU = WWMatrix.Mul(L, U);
                var PA = WWMatrix.Mul(P, A);
                Assert.IsTrue(WWMatrix.IsSame(PA, LU));
            }
        }
示例#4
0
        public void MatrixLPU_3x3a()
        {
            int N = 3;

            var A = new WWMatrix(N, N, new double[]
                                 { 6, 4, 1,
                                   3, 3, 2,
                                   7, 7, 3 });

            WWMatrix P;
            WWMatrix L;
            WWMatrix U;
            var      result = WWMatrix.LUdecompose2(A, out L, out P, out U);

            Assert.IsTrue(result == WWMatrix.ResultEnum.Success);

            // Lは下三角行列。
            var Ltype = L.DetermineMatType();

            Assert.IsTrue(0 != (Ltype & (ulong)WWMatrix.MatType.LowerTriangular));

            // Uは上三角行列。
            var Utype = U.DetermineMatType();

            Assert.IsTrue(0 != (Utype & (ulong)WWMatrix.MatType.UpperTriangular));

            A.Print("A");
            L.Print("L");
            U.Print("U");
            P.Print("P");

            // P * A = L * U
            var LU = WWMatrix.Mul(L, U);
            var PA = WWMatrix.Mul(P, A);

            Assert.IsTrue(WWMatrix.IsSame(PA, LU));
        }
示例#5
0
        /// <summary>
        /// KKT行列を作って解く。
        /// </summary>
        private void SolveKKT()
        {
            var pList  = mDGEditor.PointList();
            var eList  = mDGEditor.EdgeList();
            var earthP = mDGEditor.EarthedPoint();

            if (pList.Count == 0 || eList.Count == 0)
            {
                return;
            }

            var A = CalcA();

            AddLog(string.Format("A: {0}", A.ToString()));

            var C = CalcC();

            // A^T
            var AT = A.Transpose();

            // K = A^T C Aを作る。
            var K = new WWMatrix(pList.Count - 1, pList.Count - 1);

            {
                var CA = WWMatrix.Mul(C, A);
                K = WWMatrix.Mul(AT, CA);
            }
            AddLog(string.Format("K: {0}", K.ToString()));

            var b = new WWMatrix(eList.Count, 1);

            {   // 電圧源b
                for (int i = 0; i < eList.Count; ++i)
                {
                    var e = eList[i];
                    b.Set(i, 0, e.B);
                }
            }
            AddLog(string.Format("b: {0}", b.ToString()));

            var f = new WWMatrix(pList.Count - 1, 1);

            {   // fを作る。
                int nP = 0;
                for (int i = 0; i < pList.Count; ++i)
                {
                    var point = pList[i];

                    if (point == earthP)
                    {
                        // アースされている点は除外。
                        continue;
                    }
                    f.Set(nP, 0, point.F);
                    ++nP;
                }
            }
            AddLog(string.Format("f: {0}", f.ToString()));

            WWMatrix KKT;

            {   // KKT行列
                var Cinv    = CalcCinv();
                var Cinv_A  = WWMatrix.JoinH(Cinv, A);
                var AT_zero = WWMatrix.JoinH(AT, new WWMatrix(A.Column, A.Column));
                KKT = WWMatrix.JoinV(Cinv_A, AT_zero);
            }
            AddLog(string.Format("KKT: {0}", KKT.ToString()));

            WWMatrix bf;

            {   // bとfを縦に連結した縦ベクトル。
                bf = WWMatrix.JoinV(b, f);
            }
            AddLog(string.Format("bf: {0}", bf.ToString()));

            var bfA = bf.ToArray();

            // KKT u = bfを解いて uを求める。
            var uA = WWLinearEquation.SolveKu_eq_f(KKT, bfA);
            var u  = new WWMatrix(uA.Length, 1, uA);

            AddLog(string.Format("u: {0}", u.ToString()));
        }