S
S
sanches28052014-06-17 17:41:40
C++ / C#
sanches2805, 2014-06-17 17:41:40

How to implement parallel calculation of SLAE by Gauss method (C#)?

Please help me to parallelize the Gauss algorithm in C#.
If there is ready, I will be very grateful

class GausMethod
  {
    public uint RowCount;
    public uint ColumCount;
    public double[][] Matrix { get; set; }
    public double[] RightPart { get; set; }
    public double[] Answer { get; set; }
 
    public GausMethod(uint Row, uint Colum)
    {
      RightPart = new double[Row];
      Answer = new double[Row];
      Matrix = new double[Row][];
      for (int i = 0; i < Row; i++)
        Matrix[i] = new double[Colum];
      RowCount = Row;
      ColumCount = Colum;
 
      //обнулим массив
      for (int i = 0; i < Row; i++)
      {
        Answer[i] = 0;
        RightPart[i] = 0;
        for (int j = 0; j < Colum; j++)
          Matrix[i][j] = 0;
      }
    }
 
    private void SortRows(int SortIndex)
    {
 
      double MaxElement = Matrix[SortIndex][SortIndex];
      int MaxElementIndex = SortIndex;
      for (int i = SortIndex + 1; i < RowCount; i++)
      {
        if (Matrix[i][SortIndex] > MaxElement)
        {
          MaxElement = Matrix[i][SortIndex];
          MaxElementIndex = i;
        }
      }
 
      //теперь найден максимальный элемент ставим его на верхнее место
      if (MaxElementIndex > SortIndex)//если это не первый элемент
      {
        double Temp;
 
        Temp = RightPart[MaxElementIndex];
        RightPart[MaxElementIndex] = RightPart[SortIndex];
        RightPart[SortIndex] = Temp;
 
        for (int i = 0; i < ColumCount; i++)
        {
          Temp = Matrix[MaxElementIndex][i];
          Matrix[MaxElementIndex][i] = Matrix[SortIndex][i];
          Matrix[SortIndex][i] = Temp;
        }
      }
    }
 
    public int SolveMatrix()
    {
      if (RowCount != ColumCount)
        return 1; //нет решения
 
      for (int i = 0; i < RowCount - 1; i++)
      {
        SortRows(i);
        for (int j = i + 1; j < RowCount; j++)
        {
          if (Matrix[i][i] != 0) //если главный элемент не 0, то производим вычисления
          {
            double MultElement = Matrix[j][i] / Matrix[i][i];
            for (int k = i; k < ColumCount; k++)
              Matrix[j][k] -= Matrix[i][k] * MultElement;
            RightPart[j] -= RightPart[i] * MultElement;
          }
          //для нулевого главного элемента просто пропускаем данный шаг
        }
      }
 
      //ищем решение
      for (int i = (int)(RowCount - 1); i >= 0; i--)
      {
        Answer[i] = RightPart[i];
 
        for (int j = (int)(RowCount - 1); j > i; j--)
          Answer[i] -= Matrix[i][j] * Answer[j];
 
        if (Matrix[i][i] == 0)
          if (RightPart[i] == 0)
            return 2; //множество решений
          else
            return 1; //нет решения
 
        Answer[i] /= Matrix[i][i];
 
      }
      return 0;
    }
 
 
 
    public override String ToString()
    {
      String S = "";
      for (int i = 0; i < RowCount; i++)
      {
        S += "\r\n";
        for (int j = 0; j < ColumCount; j++)
        {
          S += Matrix[i][j].ToString("F04") + "\t";
        }
 
        S += "\t" + Answer[i].ToString("F08");
        S += "\t" + RightPart[i].ToString("F04");
      }
      return S;
    }
  }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
aush, 2014-06-17
@aush

Without going into the quality of the code in general, the way to parallelize is to replace:

for (int i = 0; i < RowCount - 1; i++)
{
  SortRows(i);
  for (int j = i + 1; j < RowCount; j++)
  {
    if (Matrix[i][i] != 0) //если главный элемент не 0, то производим вычисления
    {
      double MultElement = Matrix[j][i] / Matrix[i][i];
      for (int k = i; k < ColumCount; k++)
        Matrix[j][k] -= Matrix[i][k] * MultElement;
      RightPart[j] -= RightPart[i] * MultElement;
    }
    //для нулевого главного элемента просто пропускаем данный шаг
  }
}

on the
Parallel.For(0, (int)RowCount, i =>
{
  SortRows(i);
  for (int j = i + 1; j < RowCount; j++)
  {
    if (Matrix[i][i] != 0) //если главный элемент не 0, то производим вычисления
    {
      double MultElement = Matrix[j][i] / Matrix[i][i];
      for (int k = i; k < ColumCount; k++)
        Matrix[j][k] -= Matrix[i][k] * MultElement;
      RightPart[j] -= RightPart[i] * MultElement;
    }
    //для нулевого главного элемента просто пропускаем данный шаг
  }
});

The same is true for the second cycle. My CPU usage rises from ~24% to ~67% in both cases.
In such tasks, you need to pick up a profiler, look for bottlenecks and optimize them. Statement "and let's parallelize and everything will be fine" in the general case only makes things worse.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question