示例#1
0
        public static bool ComplexSolveBiCGSTABWithPivoting(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B, int fillinLevel,
            double convRatioTolerance)
        {
            int t;

            t = System.Environment.TickCount;
            ComplexSparseMatrix LU;

            int[] pivot;
            ComplexCalcILUWithPivoting(out LU, out pivot, A, fillinLevel);
            ComplexSparseMatrix pivotingA = new ComplexSparseMatrix(A.RowLength, A.ColumnLength);

            for (int i = 0; i < pivotingA.RowLength; i++)
            {
                pivotingA.RowColIndexValues[i] = A.RowColIndexValues[pivot[i]];
            }
            System.Numerics.Complex[] pivotingB = new System.Numerics.Complex[B.Length];
            for (int i = 0; i < B.Length; i++)
            {
                pivotingB[i] = B[pivot[i]];
            }
            A = null;
            B = null;
            System.Diagnostics.Debug.WriteLine("ComplexSolveBiCGStab 1: t= " + (System.Environment.TickCount - t));
            t = System.Environment.TickCount;
            bool success = IvyFEM.Linear.Functions.ComplexSolvePreconditionedBiCGSTAB(out X, pivotingA, pivotingB, LU,
                                                                                      convRatioTolerance);

            System.Diagnostics.Debug.WriteLine("ComplexSolveBiCGSTAB 2: t= " + (System.Environment.TickCount - t));
            return(success);
        }
        private bool ComplexSolveBiCGSTABWithPivoting(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            int t;

            X = null;

            //t = System.Environment.TickCount;
            //bool success = IvyFEM.Linear.Functions.ComplexSolveBiCGSTABWithPivoting(out X, A, B, ILUFillinLevel,
            //    ConvRatioTolerance);
            //System.Diagnostics.Debug.Assert(success);
            //System.Diagnostics.Debug.WriteLine("  ComplexSolveCGWithPivoting t = " + (System.Environment.TickCount - t));

            // Nativeを使う
            bool success = false;

            {
                System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
                int   n = A.RowLength;
                int[] APtrs;
                int[] AIndexs;
                System.Numerics.Complex[] AValues;
                t = System.Environment.TickCount;
                A.GetCSR(out APtrs, out AIndexs, out AValues);
                System.Diagnostics.Debug.WriteLine("  GetCSR t = " + (System.Environment.TickCount - t));
                t       = System.Environment.TickCount;
                success = IvyFEM.Native.Functions.ComplexSolveBiCGSTABWithPivoting(
                    out X, n, APtrs, AIndexs, AValues, B, ILUFillinLevel,
                    ConvRatioTolerance);
                System.Diagnostics.Debug.Assert(success);
                System.Diagnostics.Debug.WriteLine("  ComplexSolveCGWithPivoting t = " + (System.Environment.TickCount - t));
            }

            return(success);
        }
示例#3
0
        public bool ComplexSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            bool success = false;

            using (IvyFEM.Lis.LisInitializer LisInitializer = new IvyFEM.Lis.LisInitializer())
                using (IvyFEM.Lis.LisMatrix lisA = (IvyFEM.Lis.LisMatrix)A)
                    using (IvyFEM.Lis.LisVector lisB = (IvyFEM.Lis.LisVector)B)
                        using (IvyFEM.Lis.LisVector lisX = new IvyFEM.Lis.LisVector())
                            using (IvyFEM.Lis.LisSolver lisSolver = new IvyFEM.Lis.LisSolver())
                            {
                                int ret;
                                int n = B.Length;
                                lisX.SetSize(0, n);
                                A   = null;
                                ret = lisSolver.SetOption(GetOption());
                                System.Diagnostics.Debug.Assert(ret == 0);
                                ret = lisSolver.SetOptionC();
                                System.Diagnostics.Debug.Assert(ret == 0);
                                ret = lisSolver.Solve(lisA, lisB, lisX);
                                System.Diagnostics.Debug.Assert(ret == 0);
                                success = (ret == 0);
                                int iter;
                                ret = lisSolver.GetIter(out iter);
                                System.Diagnostics.Debug.Assert(ret == 0);
                                System.Diagnostics.Debug.WriteLine("Lis Solve iter = " + iter);
                                X   = new System.Numerics.Complex[n];
                                ret = lisX.GetValues(0, n, X);
                                System.Diagnostics.Debug.Assert(ret == 0);
                            }
            return(success);
        }
示例#4
0
        public bool ComplexSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            bool success = false;

            X = null;

            switch (Method)
            {
            case LapackEquationSolverMethod.Dense:
                success = ComplexDenseSolve(out X, A, B);
                break;

            case LapackEquationSolverMethod.Default:
            case LapackEquationSolverMethod.Band:
                success = ComplexBandSolve(out X, A, B);
                break;

            case LapackEquationSolverMethod.PositiveDefiniteBand:
                success = ComplexPositiveDefiniteBandSolve(out X, A, B);
                break;

            default:
                throw new NotImplementedException();
                //break;
            }

            return(success);
        }
示例#5
0
        private bool ComplexPositiveDefiniteBandSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            X = null;
            bool isHermitian = A.IsHermitian();

            System.Diagnostics.Debug.Assert(isHermitian);
            if (!isHermitian)
            {
                return(false);
            }

            bool success = false;

            IvyFEM.Lapack.ComplexHermitianBandMatrix pbA = (IvyFEM.Lapack.ComplexHermitianBandMatrix)A;
            A = null;
            int xRow;
            int xCol;
            int ret = IvyFEM.Lapack.Functions.zpbsv(out X, out xRow, out xCol,
                                                    pbA.Buffer, pbA.RowLength, pbA.ColumnLength,
                                                    pbA.SuperdiaLength,
                                                    B, B.Length, 1);

            System.Diagnostics.Debug.Assert(ret == 0);
            success = (ret == 0);
            return(success);
        }
        /////////////////////////////////////////////////////////////////////////////////
        // complex

        // LU : Lii = 1 Lij (i=1...n -1 j=0...i-1) Uij (i=0...n-1 j=i...n-1)
        // Note: M = L * U
        public static ComplexSparseMatrix ComplexCalcILU(ComplexSparseMatrix A, int fillinLevel)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            ComplexSparseMatrix LU = new ComplexSparseMatrix(A);

            int[,] level = new int[n, n];
            for (int row = 0; row < n; row++)
            {
                for (int col = 0; col < n; col++)
                {
                    level[row, col] = (A[row, col].Magnitude >= IvyFEM.Constants.PrecisionLowerLimit) ?
                                      0 : (fillinLevel + 1);
                }
            }

            for (int i = 1; i < n; i++)
            {
                for (int k = 0; k <= (i - 1); k++)
                {
                    //if (!LU.RowColIndexValues[i].ContainsKey(k))
                    //{
                    //    continue;
                    //}
                    if (level[i, k] > fillinLevel)
                    {
                        continue;
                    }
                    LU[i, k] /= LU[k, k];
                    System.Numerics.Complex LUik = LU[i, k];
                    foreach (var pair in LU.RowColIndexValues[k])
                    {
                        int j = pair.Key;
                        System.Numerics.Complex LUkj = pair.Value;
                        if (j >= k + 1 && j < n)
                        {
                            //
                        }
                        else
                        {
                            continue;
                        }

                        level[i, j] = Math.Min(level[i, j], level[i, k] + level[k, j] + 1);
                        if (level[i, j] <= fillinLevel)
                        {
                            LU[i, j] -= LUik * LUkj;
                        }
                    }
                }
            }
            return(LU);
        }
示例#7
0
 public void Copy(ComplexSparseMatrix src)
 {
     Resize(src.RowLength, src.ColumnLength);
     for (int row = 0; row < src.RowLength; row++)
     {
         var srcColIndexValues = src.RowColIndexValues[row];
         foreach (var pair in srcColIndexValues)
         {
             int col = pair.Key;
             System.Numerics.Complex value = pair.Value;
             RowColIndexValues[row].Add(col, value);
         }
     }
 }
        public bool ComplexSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            bool success = false;

            X = null;

            switch (Method)
            {
            case IvyFEMEquationSolverMethod.CG:
                // エルミート行列の場合はCG
                // 必要なケースがでてくれば実装する
                throw new NotImplementedException();
            //break;

            case IvyFEMEquationSolverMethod.Default:
            case IvyFEMEquationSolverMethod.NoPreconCOCG:
                success = ComplexSolveNoPreconCOCG(out X, A, B);
                break;

            case IvyFEMEquationSolverMethod.COCG:
                // 複素対称行列の場合はCOCG
                success = ComplexSolveCOCG(out X, A, B);
                break;

            case IvyFEMEquationSolverMethod.ICCOCG:
                success = ComplexSolveICCOCG(out X, A, B);
                break;

            case IvyFEMEquationSolverMethod.NoPreconBiCGSTAB:
                success = ComplexSolveNoPreconBiCGSTAB(out X, A, B);
                break;

            case IvyFEMEquationSolverMethod.BiCGSTAB:
                success = ComplexSolveBiCGSTAB(out X, A, B);
                break;

            case IvyFEMEquationSolverMethod.BiCGSTABWithPivoting:
                success = ComplexSolveBiCGSTABWithPivoting(out X, A, B);
                break;

            default:
                throw new NotImplementedException();
                //break;
            }

            return(success);
        }
示例#9
0
        private static bool[,] GetComplexMatrixNonzeroPattern(ComplexSparseMatrix A)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            bool[,] nonzeroPattern = new bool[n, n];
            for (int row = 0; row < n; row++)
            {
                foreach (var pair in A.RowColIndexValues[row])
                {
                    int col = pair.Key;
                    nonzeroPattern[row, col] = true;
                }
            }
            return(nonzeroPattern);
        }
示例#10
0
        public static bool ComplexSolveICCOCG(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B,
            double convRatioTolerance)
        {
            int t;

            t = System.Environment.TickCount;
            ComplexSparseMatrix LU = IvyFEM.Linear.Functions.ComplexCalcIC(A);

            System.Diagnostics.Debug.WriteLine("ComplexSolveICCOCG 1: t= " + (System.Environment.TickCount - t));
            t = System.Environment.TickCount;
            bool success = IvyFEM.Linear.Functions.ComplexSolvePreconditionedCOCG(out X, A, B, LU,
                                                                                  convRatioTolerance);

            System.Diagnostics.Debug.WriteLine("ComplexSolveICCG 2: t= " + (System.Environment.TickCount - t));
            return(success);
        }
示例#11
0
        private bool ComplexDenseSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            bool success = false;

            IvyFEM.Lapack.ComplexMatrix denseA = (IvyFEM.Lapack.ComplexMatrix)A;
            int xRow;
            int xCol;
            int ret = IvyFEM.Lapack.Functions.zgesv(out X, out xRow, out xCol,
                                                    denseA.Buffer, denseA.RowLength, denseA.ColumnLength,
                                                    B, B.Length, 1);

            System.Diagnostics.Debug.Assert(ret == 0);
            success = (ret == 0);

            return(success);
        }
示例#12
0
        public static bool ComplexSolveBiCGSTAB(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B, int fillinLevel,
            double convRatioTolerance)
        {
            int t;

            t = System.Environment.TickCount;
            ComplexSparseMatrix LU = IvyFEM.Linear.Functions.ComplexCalcILU(A, fillinLevel);

            System.Diagnostics.Debug.WriteLine("ComplexSolveBiCGSTAB 1: t= " + (System.Environment.TickCount - t));
            t = System.Environment.TickCount;
            bool success = IvyFEM.Linear.Functions.ComplexSolvePreconditionedBiCGSTAB(out X, A, B, LU,
                                                                                      convRatioTolerance);

            System.Diagnostics.Debug.WriteLine("ComplexSolveBiCGSTAB 2: t= " + (System.Environment.TickCount - t));
            return(success);
        }
示例#13
0
        private bool __ComplexBandSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            bool success = false;

            IvyFEM.Lapack.ComplexBandMatrix bandA = (IvyFEM.Lapack.ComplexBandMatrix)A;
            A = null;
            int xRow;
            int xCol;
            int ret = IvyFEM.Lapack.Functions.zgbsv(out X, out xRow, out xCol,
                                                    bandA.Buffer, bandA.RowLength, bandA.ColumnLength,
                                                    bandA.SubdiaLength, bandA.SuperdiaLength,
                                                    B, B.Length, 1);

            System.Diagnostics.Debug.Assert(ret == 0);
            success = (ret == 0);
            return(success);
        }
        //////////////////////////////////////////////////////////////////////////////////////
        // complex

        private bool ComplexSolveNoPreconCOCG(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            int t;

            X = null;
            //t = System.Environment.TickCount;
            //bool isSymmetric = A.IsSymmetric();
            //System.Diagnostics.Debug.Assert(isSymmetric);
            //System.Diagnostics.Debug.WriteLine("  IsSymmetric t = " + (System.Environment.TickCount - t));
            //if (!isSymmetric)
            //{
            //    return false;
            //}

            //t = System.Environment.TickCount;
            //bool success = IvyFEM.Linear.Functions.ComplexSolveNoPreconCOCG(out X, A, B,
            //    ConvRatioTolerance);
            //System.Diagnostics.Debug.Assert(success);
            //System.Diagnostics.Debug.WriteLine("  ComplexSolveNoPreconCOCG t = " + (System.Environment.TickCount - t));

            // Nativeを使う
            bool success = false;

            {
                System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
                int   n = A.RowLength;
                int[] APtrs;
                int[] AIndexs;
                System.Numerics.Complex[] AValues;
                t = System.Environment.TickCount;
                A.GetCSR(out APtrs, out AIndexs, out AValues);
                System.Diagnostics.Debug.WriteLine("  GetCSR t = " + (System.Environment.TickCount - t));
                t       = System.Environment.TickCount;
                success = IvyFEM.Native.Functions.ComplexSolveNoPreconCOCG(
                    out X, n, APtrs, AIndexs, AValues, B,
                    ConvRatioTolerance);
                System.Diagnostics.Debug.Assert(success);
                System.Diagnostics.Debug.WriteLine("  ComplexSolveNoPreconCOCG t = " + (System.Environment.TickCount - t));
            }

            return(success);
        }
示例#15
0
        private bool ComplexBandSolve(
            out System.Numerics.Complex[] X, ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            X = null;
            ComplexSparseMatrix AToSolve;

            System.Numerics.Complex[] BToSolve;
            int[] indexs;
            if (IsOrderingToBandMatrix)
            {
                bool successOrder = IvyFEM.Linear.Utils.OrderToComplexBandMatrix(
                    out AToSolve, out BToSolve, out indexs, A, B);
                System.Diagnostics.Debug.Assert(successOrder);
                if (!successOrder)
                {
                    return(false);
                }
            }
            else
            {
                AToSolve = A;
                BToSolve = B;
                indexs   = null;
            }

            System.Numerics.Complex[] XToSolve;
            bool success = __ComplexBandSolve(out XToSolve, AToSolve, BToSolve);

            if (IsOrderingToBandMatrix)
            {
                X = new System.Numerics.Complex[XToSolve.Length];
                for (int row = 0; row < XToSolve.Length; row++)
                {
                    X[indexs[row]] = XToSolve[row];
                }
            }
            else
            {
                X = XToSolve;
            }
            return(success);
        }
        public static void ComplexSolveLU(
            out System.Numerics.Complex[] X, ComplexSparseMatrix LU, System.Numerics.Complex[] B)
        {
            System.Diagnostics.Debug.Assert(LU.RowLength == LU.ColumnLength);
            int n = LU.RowLength;

            X = new System.Numerics.Complex[n];
            B.CopyTo(X, 0);

            // Ly = b
            for (int row = 1; row < n; row++)
            {
                foreach (var pair in LU.RowColIndexValues[row])
                {
                    int col = pair.Key;
                    System.Numerics.Complex value = pair.Value;
                    if (col >= 0 && col < row)
                    {
                        X[row] -= value * X[col]; // LU[row, col]
                    }
                }
            }

            // Ux = y
            for (int row = n - 2; row >= 0; row--)
            {
                foreach (var pair in LU.RowColIndexValues[row])
                {
                    int col = pair.Key;
                    System.Numerics.Complex value = pair.Value;
                    if (col >= row + 1 && col < n)
                    {
                        X[row] -= value * X[col]; // LU[row, col]
                    }
                }
                X[row] /= LU[row, row];
            }
        }
示例#17
0
        /*
         * public void Transpose()
         * {
         *  throw new NotImplementedException();
         * }
         */

        public static ComplexSparseMatrix operator *(ComplexSparseMatrix A, ComplexSparseMatrix B)
        {
            int aRow = A.RowLength;
            int aCol = A.ColumnLength;
            int bRow = B.RowLength;
            int bCol = B.ColumnLength;

            if (aCol != bRow)
            {
                throw new ArgumentException("Mismatched size: aCol != bRow(" + aCol + " != " + bRow + ")");
            }

            int cRow = aRow;
            int cCol = bCol;
            ComplexSparseMatrix C = new ComplexSparseMatrix(cRow, cCol);

            for (int i = 0; i < aRow; i++)
            {
                var colIndexValues1 = A.RowColIndexValues[i];
                for (int j = 0; j < bCol; j++)
                {
                    foreach (var pair1 in colIndexValues1)
                    {
                        int k = pair1.Key;
                        System.Numerics.Complex value1 = pair1.Value; // Aik

                        if (B.RowColIndexValues[k].ContainsKey(j))
                        {
                            System.Numerics.Complex value2 = B.RowColIndexValues[k][j]; // Bkj
                            C[i, j] += value1 * value2;
                        }
                    }
                }
            }
            return(C);
        }
        // Incomplete Cholesky Factorization
        public static ComplexSparseMatrix ComplexCalcIC(ComplexSparseMatrix A)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            ComplexSparseMatrix LU = new ComplexSparseMatrix(n, n);

            System.Numerics.Complex[] D = new System.Numerics.Complex[n];

            D[0]     = A[0, 0];
            LU[0, 0] = 1.0;

            // L
            for (int i = 1; i < n; i++)
            {
                for (int j = 0; j <= (i - 1); j++)
                {
                    if (!A.RowColIndexValues[i].ContainsKey(j))
                    {
                        continue;
                    }
                    System.Numerics.Complex tmp = A[i, j];
                    foreach (var pair in LU.RowColIndexValues[i])
                    {
                        int k = pair.Key;
                        System.Numerics.Complex LUik = pair.Value;
                        if (k >= 0 && k <= (j - 1))
                        {
                            //
                        }
                        else
                        {
                            continue;
                        }
                        tmp -= LUik * LU[j, k] * D[k];  // LU[i, k]
                    }
                    LU[i, j] = (1.0 / D[j]) * tmp;
                }

                // i == jのとき
                {
                    System.Numerics.Complex tmp = A[i, i];
                    foreach (var pair in LU.RowColIndexValues[i])
                    {
                        int k = pair.Key;
                        System.Numerics.Complex LUik = pair.Value;
                        if (k >= 0 && k <= (i - 1))
                        {
                            //
                        }
                        else
                        {
                            continue;
                        }
                        tmp -= LUik * LUik * D[k];  // LU[i, k]
                    }
                    D[i]     = tmp;
                    LU[i, i] = 1.0;
                }
            }

            // DL^T
            for (int i = 0; i < n; i++)
            {
                foreach (var pair in LU.RowColIndexValues[i])
                {
                    int j = pair.Key;
                    System.Numerics.Complex LUij = pair.Value;
                    if (j >= 0 && j <= (i - 1))
                    {
                        //
                    }
                    else
                    {
                        continue;
                    }
                    LU[j, i] = D[j] * LUij; // LU[i, j]
                }
                LU[i, i] = D[i];
            }
            return(LU);
        }
示例#19
0
        public static bool OrderToComplexBandMatrix(
            out ComplexSparseMatrix orderedA, out System.Numerics.Complex[] orderedB, out int[] indexs,
            ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            orderedA = null;
            orderedB = null;
            indexs   = null;

            // バンド幅を縮小する
            // 非0要素のパターンを取得
            bool[,] matPattern = GetComplexMatrixNonzeroPattern(A);
            int n = matPattern.GetLength(0);
            // subdiagonal、superdiagonalのサイズを取得する
            int iniSubdiaLength   = 0;
            int iniSuperdiaLength = 0;
            {
                System.Diagnostics.Debug.WriteLine("/////initial Band Matrix info///////");
                int rowcolLength;
                int subdiaLength;
                int superdiaLength;
                GetBandMatrixSubDiaSuperDia(matPattern, out rowcolLength, out subdiaLength, out superdiaLength);
                iniSubdiaLength   = subdiaLength;
                iniSuperdiaLength = superdiaLength;
            }

            // 非0要素出現順に節点番号を格納
            IList <int> newIndexs = new List <int>();
            Queue <int> check     = new Queue <int>();

            int[] remain = new int[matPattern.GetLength(0)];
            for (int i = 0; i < matPattern.GetLength(0); i++)
            {
                remain[i] = i;
            }
            while (newIndexs.Count < n)
            {
                for (int iRemain = 0; iRemain < remain.Length; iRemain++)
                {
                    int i = remain[iRemain];
                    if (i == -1)
                    {
                        continue;
                    }
                    check.Enqueue(i);
                    remain[iRemain] = -1;
                    break;
                }
                while (check.Count > 0)
                {
                    int i = check.Dequeue();
                    newIndexs.Add(i);
                    for (int iRemain = 0; iRemain < remain.Length; iRemain++)
                    {
                        int j = remain[iRemain];
                        if (j == -1)
                        {
                            continue;
                        }
                        if (matPattern[i, j])
                        {
                            check.Enqueue(j);
                            remain[iRemain] = -1;
                        }
                    }
                }
            }
            System.Diagnostics.Debug.Assert(newIndexs.Count == n);
            ComplexSparseMatrix newA = new ComplexSparseMatrix(n, n);

            // 遅い
            //for (int row = 0; row < n; row++)
            //{
            //    for (int col = 0; col < n; col++)
            //    {
            //        newA[row, col] = A[newIndexs[row], newIndexs[col]];
            //    }
            //}
            int[] oldIndexs = new int[n];
            for (int i = 0; i < n; i++)
            {
                oldIndexs[newIndexs[i]] = i;
            }

            for (int row = 0; row < n; row++)
            {
                foreach (var pair in A.RowColIndexValues[row])
                {
                    int col = pair.Key;
                    System.Numerics.Complex value = pair.Value;
                    newA[oldIndexs[row], oldIndexs[col]] = value;
                }
            }

            // 改善できないこともあるのでチェックする
            bool improved = false;

            // 非0パターンを取得
            bool[,] newMatPattern = GetComplexMatrixNonzeroPattern(newA);
            // check
            {
                System.Diagnostics.Debug.WriteLine("///// orderd Band Matrix info ///////");
                int rowcolLength;
                int subdiaLength;
                int superdiaLength;
                GetBandMatrixSubDiaSuperDia(newMatPattern, out rowcolLength, out subdiaLength, out superdiaLength);
                if (subdiaLength <= iniSubdiaLength && superdiaLength <= iniSuperdiaLength)
                {
                    improved = true;
                }
            }
            if (improved)
            {
                // 置き換え
                orderedA = newA;
                indexs   = newIndexs.ToArray();

                orderedB = new System.Numerics.Complex[n];
                for (int row = 0; row < n; row++)
                {
                    orderedB[row] = B[newIndexs[row]];
                }
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("band with not optimized!");
            }
            return(improved);
        }
        public static void ComplexCalcILUWithPivoting(
            out ComplexSparseMatrix LU, out int[] pivot, ComplexSparseMatrix A, int fillinLevel)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            LU    = new ComplexSparseMatrix(A);
            pivot = new int[n];
            for (int row = 0; row < n; row++)
            {
                pivot[row] = row;
            }

            int[,] level = new int[n, n];
            for (int row = 0; row < n; row++)
            {
                for (int col = 0; col < n; col++)
                {
                    level[row, col] = (A[row, col].Magnitude >= IvyFEM.Constants.PrecisionLowerLimit) ?
                                      0 : (fillinLevel + 1);
                }
            }

            for (int k = 0; k < (n - 1); k++)
            {
                int p = k;
                {
                    double max = LU[k, k].Magnitude;
                    for (int i = k + 1; i < n; i++)
                    {
                        double abs = LU[i, k].Magnitude;
                        if (abs > max)
                        {
                            max = abs;
                            p   = i;
                        }
                    }
                }
                if (k != p)
                {
                    {
                        int tmp = pivot[k];
                        pivot[k] = pivot[p];
                        pivot[p] = tmp;
                    }
                    {
                        var tmp = LU.RowColIndexValues[k];
                        LU.RowColIndexValues[k] = LU.RowColIndexValues[p];
                        LU.RowColIndexValues[p] = tmp;
                    }
                    for (int j = 0; j < n; j++)
                    {
                        int tmp = level[k, j];
                        level[k, j] = level[p, j];
                        level[p, j] = tmp;
                    }
                }
                for (int i = k + 1; i < n; i++)
                {
                    if (level[i, k] > fillinLevel)
                    {
                        continue;
                    }
                    System.Diagnostics.Debug.Assert(LU.RowColIndexValues[k].ContainsKey(k));
                    LU[i, k] /= LU[k, k];
                    System.Numerics.Complex LUik = LU[i, k];
                    foreach (var pair in LU.RowColIndexValues[k])
                    {
                        int j = pair.Key;
                        System.Numerics.Complex LUkj = pair.Value;
                        if (j >= k + 1 && j < n)
                        {
                        }
                        else
                        {
                            continue;
                        }
                        level[i, j] = Math.Min(level[i, j], level[i, k] + level[k, j] + 1);
                        if (level[i, j] <= fillinLevel)
                        {
                            LU[i, j] -= LUik * LUkj; // LU[i, k] LU[k, j]
                        }
                    }
                }
            }
            for (int i = 0; i < n; i++)
            {
                System.Diagnostics.Debug.Assert(LU.RowColIndexValues[i].ContainsKey(i));
            }
        }
示例#21
0
        public static bool ComplexSolvePreconditionedBiCGSTAB(
            out System.Numerics.Complex[] X,
            ComplexSparseMatrix A, System.Numerics.Complex[] B, ComplexSparseMatrix LU,
            double convRatioTolerance)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            System.Diagnostics.Debug.Assert(B.Length == n);
            double    convRatio = convRatioTolerance;
            double    tolerance = convRatio;
            const int maxIter   = IvyFEM.Linear.Constants.MaxIter;

            System.Numerics.Complex[] r  = new System.Numerics.Complex[n];
            System.Numerics.Complex[] r0 = new System.Numerics.Complex[n];
            System.Numerics.Complex[] x  = new System.Numerics.Complex[n];
            System.Numerics.Complex[] p  = new System.Numerics.Complex[n];
            System.Numerics.Complex[] s  = new System.Numerics.Complex[n];
            System.Numerics.Complex[] Mp = new System.Numerics.Complex[n];
            System.Numerics.Complex[] Ms = new System.Numerics.Complex[n];
            int iter = 0;

            B.CopyTo(r, 0);
            double sqInvNorm0;

            {
                double sqNorm0 = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                if (sqNorm0 < IvyFEM.Constants.PrecisionLowerLimit)
                {
                    convRatio = 0;
                    X         = x;
                    System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                    return(true);
                }
                sqInvNorm0 = 1.0 / sqNorm0;
            }

            r.CopyTo(r0, 0);
            r.CopyTo(p, 0);

            for (iter = 0; iter < maxIter; iter++)
            {
                ComplexSolveLU(out Mp, LU, p);
                System.Numerics.Complex r0r = IvyFEM.Lapack.Functions.zdotc(r0, r);

                System.Numerics.Complex[] AMp = A * Mp;
                System.Numerics.Complex   alpha;
                {
                    System.Numerics.Complex denominator = IvyFEM.Lapack.Functions.zdotc(r0, AMp);
                    alpha = r0r / denominator;
                }
                s = IvyFEM.Lapack.Functions.zaxpy(-alpha, AMp, r);

                ComplexSolveLU(out Ms, LU, s);

                System.Numerics.Complex[] AMs = A * Ms;
                System.Numerics.Complex   omega;
                {
                    System.Numerics.Complex denominator = IvyFEM.Lapack.Functions.zdotc(AMs, AMs);
                    System.Numerics.Complex numerator   = IvyFEM.Lapack.Functions.zdotc(s, AMs);
                    omega = numerator / denominator;
                }

                x = IvyFEM.Lapack.Functions.zaxpy(alpha, Mp, x);
                x = IvyFEM.Lapack.Functions.zaxpy(omega, Ms, x);
                r = IvyFEM.Lapack.Functions.zaxpy(-omega, AMs, s);

                {
                    double sqNorm = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                    if (sqNorm * sqInvNorm0 < tolerance * tolerance)
                    {
                        convRatio = Math.Sqrt(sqNorm * sqInvNorm0);
                        X         = x;
                        System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                        return(true);
                    }
                }

                System.Numerics.Complex beta;
                {
                    System.Numerics.Complex r0rPrev = r0r;
                    r0r  = IvyFEM.Lapack.Functions.zdotc(r0, r);
                    beta = (r0r * alpha) / (r0rPrev * omega);
                }
                p = IvyFEM.Lapack.Functions.zaxpy(beta, p, r);
                p = IvyFEM.Lapack.Functions.zaxpy(-beta * omega, AMp, p);
            }

            {
                double sqNormRes = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                convRatio = Math.Sqrt(sqNormRes * sqInvNorm0);
                System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                X = x;
            }
            System.Diagnostics.Debug.WriteLine("Not converged");
            return(false);
        }
示例#22
0
 public ComplexSparseMatrix(ComplexSparseMatrix src)
 {
     Copy(src);
 }
        public static bool ComplexSolveNoPreconCOCG(
            out System.Numerics.Complex[] X,
            ComplexSparseMatrix A, System.Numerics.Complex[] B,
            double convRatioTolerance)
        {
            System.Diagnostics.Debug.Assert(A.RowLength == A.ColumnLength);
            int n = A.RowLength;

            System.Diagnostics.Debug.Assert(B.Length == n);
            double    convRatio    = convRatioTolerance;
            double    convRatioTol = convRatio;
            const int maxIter      = IvyFEM.Linear.Constants.MaxIter;

            System.Numerics.Complex[] r = new System.Numerics.Complex[n];
            System.Numerics.Complex[] x = new System.Numerics.Complex[n];
            System.Numerics.Complex[] p = new System.Numerics.Complex[n];
            int iter = 0;

            B.CopyTo(r, 0);
            double sqInvNorm0;

            {
                double sqNorm0 = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                if (sqNorm0 < IvyFEM.Constants.PrecisionLowerLimit)
                {
                    convRatio = 0;
                    X         = x;
                    System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                    return(true);
                }
                sqInvNorm0 = 1.0 / sqNorm0;
            }

            r.CopyTo(p, 0);
            System.Numerics.Complex rr = IvyFEM.Lapack.Functions.zdotu(r, r);

            for (iter = 0; iter < maxIter; iter++)
            {
                System.Numerics.Complex[] Ap = A * p;
                System.Numerics.Complex   alpha;
                {
                    System.Numerics.Complex pAp = IvyFEM.Lapack.Functions.zdotu(p, Ap);
                    alpha = rr / pAp;
                }
                r = IvyFEM.Lapack.Functions.zaxpy(-alpha, Ap, r);
                x = IvyFEM.Lapack.Functions.zaxpy(alpha, p, x);

                {
                    double sqNorm = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                    if (sqNorm * sqInvNorm0 < convRatioTol * convRatioTol)
                    {
                        convRatio = Math.Sqrt(sqNorm * sqInvNorm0);
                        X         = x;
                        System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                        return(true);
                    }
                }

                System.Numerics.Complex rrPrev = rr;
                rr = IvyFEM.Lapack.Functions.zdotu(r, r);
                System.Numerics.Complex beta = rr / rrPrev;

                p = IvyFEM.Lapack.Functions.zaxpy(beta, p, r);
            }

            {
                double sqNormRes = IvyFEM.Lapack.Functions.zdotc(r, r).Real;
                convRatio = Math.Sqrt(sqNormRes * sqInvNorm0);
                System.Diagnostics.Debug.WriteLine("iter = " + iter + " norm: " + convRatio);
                X = x;
            }
            System.Diagnostics.Debug.WriteLine("Not converged");
            return(false);
        }