public BlockMatrix(string PATH, int SIZE_BLOCK)
        {
            //PATH + "Sizebin" - путь файла для чтения
            //FileMode - для открытия
            using (var Reader = new System.IO.BinaryReader(File.Open(PATH + "Size.bin", FileMode.Open)))
            {
                M = Reader.ReadInt32();
                N = M;
            }

            if (M % SIZE_BLOCK != 0)
            {
                throw new Exception("Block_Matrix: cant be separated on blocks");
            }

            M         /= SIZE_BLOCK;
            N         /= SIZE_BLOCK;
            Size_Block = SIZE_BLOCK;
            Block      = new Matrix[M][];

            using (var Reader = new System.IO.BinaryReader(File.Open(PATH + "Matrix.bin", FileMode.Open)))
            {
                var LU_Decomposition = new LU_Decomposition();

                for (int i = 0; i < N; i++)
                {
                    Block[i] = new Matrix[N];

                    //определение блоков в блочной матрице
                    for (int j = 0; j < M; j++)
                    {
                        Block[i][j] = new Matrix(Size_Block, Size_Block);
                    }

                    for (int ii = 0; ii < Size_Block; ii++)
                    {
                        for (int j = 0; j < M; j++)
                        {
                            for (int k = 0; k < Size_Block; k++)
                            {
                                Block[i][j].Elem[ii][k] = Reader.ReadDouble();
                            }
                        }
                    }

                    LU_Decomposition.CreateLU(Block[i][i]);

                    //копируем элементы из LU в блочную матрицу
                    for (int Row = 0; Row < Size_Block; Row++)
                    {
                        for (int Column = 0; Column < Size_Block; Column++)
                        {
                            Block[i][i].Elem[Row][Column] = LU_Decomposition.LU.Elem[Row][Column];
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        //Вычисление числа обусловленности
        public double Cond_Square_Matrix_Parallel()
        {
            if (M != N)
            {
                throw new Exception("Cond_Square_Matrix: matrix doesn't square");
            }

            //решатель СЛАУ
            var LU_Solver = new LU_Decomposition();

            LU_Solver.CreateLU(this.Transpose_Matrix());

            //число допустимых виртуальных ядер
            int Number_Threads = Environment.ProcessorCount;

            //семафор для потоков(используется список)
            var Semaphors = new List <bool>();

            //норма строк (разделяется по потокам)
            var Norma_Row_A  = new double[Number_Threads];
            var Norma_Row_A1 = new double[Number_Threads];

            //вход в параллельную секцию
            //объявление объекта типа делегат
            //для создания объекта в параметрах конструктора передаётся анонимный метод
            var Thread_Solver = new Threads_Solving(Number =>
                                                    //лямбда-выражение
            {
                //строк для отображения матрицы
                //в каждом потоке хранится своя строка матрицы
                var A1 = new Vector(M);
                double S1, S2;

                //индексы указывающие на первую и последнюю строку для потока
                int Begin = N / Number_Threads * Number;
                int End   = Begin + N / Number_Threads;

                //если деление было нецелочисленное, записываем в конец остаток
                if (Number + 1 == Number_Threads)
                {
                    End += N % Number_Threads;
                }

                //решение СЛАУ для End-Begin строк
                for (int i = Begin; i < End; i++)
                {
                    A1.Elem[i] = 1.0;
                    A1         = LU_Solver.Start_Solver(LU_Solver.LU, A1);

                    //нормы S1, S2
                    S1 = 0;
                    S2 = 0;

                    for (int j = 0; j < M; j++)
                    {
                        S1        += Math.Abs(Elem[i][j]);
                        S2        += Math.Abs(A1.Elem[j]);
                        A1.Elem[j] = 0.0;
                    }

                    //определение наибольшей из норм
                    if (Norma_Row_A[Number] < S1)
                    {
                        Norma_Row_A[Number] = S1;
                    }

                    if (Norma_Row_A1[Number] < S2)
                    {
                        Norma_Row_A1[Number] = S2;
                    }
                }

                //сигнал о завершении потока
                Semaphors[Number] = true;
            });

            //отцовский поток вызывает дочерние
            for (int I = 0; I < Number_Threads; I++)
            {
                int Number = I;
                Semaphors.Add(false);

                //пул(очередь) потоков
                ThreadPool.QueueUserWorkItem(Param => Thread_Solver(Number));
            }

            //просмотр списка семафора на наличие незавершённых потоков
            while (Semaphors.Contains(false))
            {
                ;
            }

            for (int i = 1; i < Number_Threads; i++)
            {
                if (Norma_Row_A[0] < Norma_Row_A[i])
                {
                    Norma_Row_A[0] = Norma_Row_A[i];
                }

                if (Norma_Row_A1[0] < Norma_Row_A1[i])
                {
                    Norma_Row_A1[0] = Norma_Row_A1[i];
                }
            }

            return(Norma_Row_A[0] * Norma_Row_A1[0]);
        }