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
        }