public void MatrixJoinV() { int N = 2; var A = new WWMatrix(N, N, new double[] { 1, 2, 3, 4 }); var B = new WWMatrix(N, N, new double[] { 5, 6, 7, 8 }); var AB = WWMatrix.JoinV(A, B); var ABref = new WWMatrix(N * 2, N, new double[] { 1, 2, 3, 4, 5, 6, 7, 8 }); Assert.IsTrue(WWMatrix.IsSame(AB, ABref)); }
/// <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())); }