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]; } } } } }
//Вычисление числа обусловленности 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]); }