Умножение матриц - C# (179996)
Формулировка задачи:
Доброго времени суток.
Реализовывал операции с матрицами (сложение, умножение на число, обратная матрица и т.д.), дошёл до умножения.
Составил алгоритм, написал код, но результат получается неверный. Сверялся с Excel и другими онлайн сервисами.
Поискал на просторах интернета решение. Оно сходится с моим, но видимо я всё же запутался и где-то допустил ошибку.
Полагаю, что проблема в условии циклов при умножении. Но бьюсь уже два дня и всё безрезультатно.
Поможете разобраться?
void Mul()
{
float [,]A=new float[First_matrix_column_now,First_matrix_line_now];//1 матрица
float [,]B=new float[Second_matrix_column_now,Second_matrix_line_now];//2 матрица
float [,]C=new float[First_matrix_column_now,Second_matrix_line_now];//результат
for(int i=0; i<First_matrix_column_now; i++)
for (int j=0; j<First_matrix_line_now; j++)
try
{
A[i,j] = Convert.ToInt16(First_matrix[i,j].Text);//берёт значения из TextBox'ов
}
catch
{
MessageBox.Show("Ошибка!A");
goto exit;
}
for(int i=0; i<Second_matrix_column_now; i++)
for (int j=0; j<Second_matrix_line_now; j++)
try
{
B[i,j] = Convert.ToInt16(Second_matrix[i,j].Text);//берёт значения из TextBox'ов
}
catch
{
MessageBox.Show("Ошибка!B");
goto exit;
}
for (int i = 0; i < First_matrix_column_now; i++)
for (int j = 0; j < Second_matrix_line_now; j++)
for (int k = 0; k < Second_matrix_column_now; k++)
{
try
{
C[i,j] += A[i,k] * B[k,j];//само умножение
}
catch
{
MessageBox.Show("Ошибка!C"+" "+i+"; "+j);
goto exit;
}
}
Result_matrix_column_change(First_matrix_column_now);//изменение количества TextBox'ов в соответствии с размером матрицы C (столбцы)
Result_matrix_line_change(Second_matrix_line_now);//изменение количества TextBox'ов в соответствии с размером матрицы C (строки)
for(int i=0; i<C.GetLength(0); i++)
for (int j=0; j<C.GetLength(1); j++)
Result_matrix[i,j].Text=C[i,j].ToString();
exit:{}
}Решение задачи: «Умножение матриц»
textual
Листинг программы
// Транспонирование матрицы
public static double[,] TransposeMatrixD(double[,] matrix)
{
int m = matrix.GetLength(0);
int n = matrix.GetLength(1);
double[,] matrixT = new double[n, m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrixT[i, j] = matrix[j, i];
}
}
return matrixT;
}
// Умножение матриц
public static double[,] MultiplicationMatrixD(double[,] a, double[,] b)
{
if (a.GetLength(1) != b.GetLength(0)) { throw new Exception("Матрицы нельзя перемножить"); }
int ma = a.GetLength(0);
int mb = b.GetLength(0);
int nb = b.GetLength(1);
double[,] r = new double[ma, nb];
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < nb; j++)
{
for (int k = 0; k < mb; k++)
{
r[i, j] += a[i, k] * b[k, j];
}
}
}
return r;
}
// Обратная матрица
public static double[,] InvertMatrixD(double[,] matrix)
{
int m = matrix.GetLength(0);
int n = matrix.GetLength(1);
double[,] res = new double[m, n];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < m; j++)
{
res[i, j] = matrix[i, j];
}
}
if (n != m)
{
throw new Exception("Обратной матрицы не существует");
}
int[] row = new int[n];
int[] col = new int[n];
double[] temp = new double[n];
int hold;
int I_pivot;
int J_pivot;
double pivot;
double abs_pivot;
// установиим row и column как вектор изменений.
for (int k = 0; k < n; k++)
{
row[k] = k;
col[k] = k;
}
// начало главного цикла
for (int k = 0; k < n; k++)
{
// найдем наибольший элемент для основы
pivot = res[row[k], col[k]];
I_pivot = k;
J_pivot = k;
for (int i = k; i < n; i++)
{
for (int j = k; j < n; j++)
{
abs_pivot = Math.Abs(pivot);
if (Math.Abs(res[row[i], col[j]]) > abs_pivot)
{
I_pivot = i;
J_pivot = j;
pivot = res[row[i], col[j]];
}
}
}
if (Math.Abs(pivot) < 1.0E-10)
{
//System.out.println("Matrix is singular !");
throw new Exception("!");
}
// Перестановка к-ой строки и к-ого столбца с стобцом и строкой, содержащий основной элемент(pivot основу)
hold = row[k];
row[k] = row[I_pivot];
row[I_pivot] = hold;
hold = col[k];
col[k] = col[J_pivot];
col[J_pivot] = hold;
// k-ую строку с учетом перестановок делим на основной элемент
res[row[k], col[k]] = 1.0 / pivot;
for (int j = 0; j < n; j++)
{
if (j != k)
{
res[row[k], col[j]] = res[row[k], col[j]] * res[row[k], col[k]];
}
}
// Внутренний цикл
for (int i = 0; i < n; i++)
{
if (k != i)
{
for (int j = 0; j < n; j++)
{
if (k != j)
{
res[row[i], col[j]] = res[row[i], col[j]] - res[row[i], col[k]] * res[row[k], col[j]];
}
}
res[row[i], col[k]] = -res[row[i], col[k]] * res[row[k], col[k]];
}
}
}
// Переставляем назад rows
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
temp[col[i]] = res[row[i], j];
}
for (int i = 0; i < n; i++)
{
res[i, j] = temp[i];
}
}
// Переставляем назад columns
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
temp[row[j]] = res[i, col[j]];
}
for (int j = 0; j < n; j++)
{
res[i, j] = temp[j];
}
}
return res;
}