protected override SayeQuadRule SetGaussQuadratureNodes(SayeSquare arg) { //Aquire needed data //------------------------------------------------------------------------------------------------------------ QuadRule gaussRule_2D = Square.Instance.GetQuadratureRule(order); MultidimensionalArray nodes_GaussRule_2D = ((MultidimensionalArray)gaussRule_2D.Nodes).CloneAs(); MultidimensionalArray weights_GaussRule_2D = gaussRule_2D.Weights.CloneAs(); double[] diameters = arg.Diameters; MultidimensionalArray centerArr = arg.GetCellCenter().ExtractSubArrayShallow(new int[] { 0, -1 }); double jacobian = diameters[0] * diameters[1]; //AffineTransformation of nodes, scale weights //------------------------------------------------------------------------------------------------------------ //Scale Nodes for (int i = 0; i < 2; ++i) { nodes_GaussRule_2D.ColScale(i, diameters[i]); } //Scale Weights weights_GaussRule_2D.Scale(jacobian); //Move Nodes int[] index = new int[] { 0, -1 }; for (int i = 0; i < gaussRule_2D.NoOfNodes; ++i) { index[0] = i; nodes_GaussRule_2D.AccSubArray(1, centerArr, index); } //Set return data //------------------------------------------------------------------------------------------------------------ SayeQuadRule transformed_GaussRule_2D = new SayeQuadRule(nodes_GaussRule_2D, weights_GaussRule_2D); return(transformed_GaussRule_2D); }
static void SymmInv(MultidimensionalArray M, MultidimensionalArray L, MultidimensionalArray R) { L.Clear(); R.Clear(); L.AccEye(1.0); #if DEBUG var Mbefore = M.CloneAs(); #endif int n = M.NoOfRows; for (int i = 0; i < n; i++) { double M_ii = M[i, i]; if (M_ii == 0.0) { throw new ArithmeticException("Zero diagonal element at " + i + "-th row."); } double scl = 1.0 / Math.Sqrt(Math.Abs(M_ii)); M.RowScale(i, scl); L.RowScale(i, scl); M.ColScale(i, scl); double diagsign = Math.Sign(M[i, i]); if (diagsign == 0.0) { throw new ArithmeticException("Zero diagonal element at " + i + "-th row."); } if (Math.Abs(Math.Abs(M[i, i]) - 1.0) > 1.0e-8) { throw new ArithmeticException("Unable to create diagonal 1.0."); } for (int k = i + 1; k < n; k++) { double M_ki = M[k, i]; M.RowAdd(i, k, -M_ki * diagsign); L.RowAdd(i, k, -M_ki * diagsign); M.ColAdd(i, k, -M_ki * diagsign); Debug.Assert(Math.Abs(M[k, i]) < 1.0e-8); Debug.Assert(Math.Abs(M[i, k]) < 1.0e-8); } } L.TransposeTo(R); #if DEBUG var Test = MultidimensionalArray.Create(M.Lengths); //var Q = MultidimensionalArray.Create(M.Lengths); //Test.AccEye(1.0); Test.Multiply(-1.0, L, Mbefore, R, 1.0, "ij", "ik", "kl", "lj"); for (int i = 0; i < n; i++) { //Debug.Assert((Test[i, i].Abs() - 1.0).Abs() < 1.0e-8); //Test[i, i] -= Math.Sign(Test[i, i]); Test[i, i] = 0; } double TestNorm = Test.InfNorm(); double scale = Math.Max(Mbefore.InfNorm(), R.InfNorm()); Debug.Assert(TestNorm / scale < 1.0e-4); /* * if(TestNorm / scale >= 1.0e-8) { * var MM = Mbefore.CloneAs(); * MultidimensionalArray Lo = MultidimensionalArray.Create(n, n); * * for(int j = 0; j < n; j++) { * double Lo_jj = MM[j, j]; * for(int k = 0; k < j; k++) { * Lo_jj -= Lo[j, k].Pow2(); * } * * double sig = Math.Abs(Lo_jj); * Lo[j, j] = Math.Sqrt(Lo_jj * sig); * * * for(int i = j; i < n; i++) { * double acc = MM[i, j]; * for(int k = 0; k < j; k++) { * acc -= Lo[i, k] * Lo[j, k]; * } * * Lo[i, j] = (1 / (Lo[j, j] * sig)) * acc; * } * } * * int info = 0; * unsafe { * fixed(double* B_entries = Lo.Storage) { * * int UPLO = 'L', DIAG = 'N'; * LAPACK.F77_LAPACK.DTRTRI_(ref UPLO, ref DIAG, ref n, B_entries, ref n, out info); * } * } * * MultidimensionalArray Up = MultidimensionalArray.Create(n, n); * Lo.TransposeTo(Up); * Test.Clear(); * Test.Multiply(-1.0, Lo, Mbefore, R, 1.0, "ij", "ik", "kl", "lj"); * * * for(int i = 0; i < n; i++) { * //Debug.Assert((Test[i, i].Abs() - 1.0).Abs() < 1.0e-8); * Test[i, i] -= Math.Sign(Test[i, i]); * } * * double TestNorm1 = Test.InfNorm(); * //double scale = Math.Max(Mbefore.InfNorm(), R.InfNorm()); * Console.WriteLine(TestNorm1); * * } */ #endif }