/// <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())); }
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)); }
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)); } }
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)); }
/// <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())); }