/// <summary> /// Adds two matrixes /// </summary> /// <param name="mtx1">first matrix</param> /// <param name="mtx2">second matrix</param> /// <returns>result of summing this matrixes</returns> public static KnuthSparseMatrix operator +(KnuthSparseMatrix mtx1, KnuthSparseMatrix mtx2) { if (mtx1.storage.Rows.Count != mtx2.storage.Rows.Count || mtx1.storage.Cols.Count != mtx2.storage.Cols.Count) throw new Exception("Wrong size of matrix to summ"); KnuthSparseMatrix Res = new KnuthSparseMatrix(mtx1.storage.Rows.Count, mtx1.storage.Cols.Count); KnuthNode<double> Iter1, Iter2; for (int i = 0; i < mtx1.storage.Rows.Count; ++i) { Iter1 = mtx1.storage.Rows[i].Left; Iter2 = mtx2.storage.Rows[i].Left; while (Iter1 != mtx1.storage.Rows[i] || Iter2 != mtx2.storage.Rows[i]) { if (Iter1 == mtx1.storage.Rows[i]) { Res.At(Iter2.Row, Iter2.Col, Iter2.Val); Iter2 = Iter2.Left; } else if (Iter2 == mtx2.storage.Rows[i]) { Res.At(Iter1.Row, Iter1.Col, Iter1.Val); Iter1 = Iter1.Left; } else if (Iter1.Col == Iter2.Col) { Res.At(Iter1.Row, Iter1.Col, Iter1.Val + Iter2.Val); Iter1 = Iter1.Left; Iter2 = Iter2.Left; } else if (Iter1.Col < Iter2.Col) { Res.At(Iter2.Row, Iter2.Col, Iter2.Val); Iter2 = Iter2.Left; } else //(Iter2.Col < Iter1.Col) { Res.At(Iter1.Row, Iter1.Col, Iter1.Val); Iter1 = Iter1.Left; } } } return Res; }
/// <summary> /// Multiply two sparse matrix /// </summary> /// <param name="mtx1">first matrix</param> /// <param name="mtx2">second matrix</param> /// <returns>result of multiplying this matrix</returns> public static KnuthSparseMatrix operator *(KnuthSparseMatrix mtx1, KnuthSparseMatrix mtx2) { if (mtx1.storage.Cols.Count != mtx2.storage.Rows.Count) throw new Exception("Wrong size of matrix to multiple"); KnuthSparseMatrix Res = new KnuthSparseMatrix(mtx1.storage.Rows.Count, mtx2.storage.Cols.Count); double tmp; KnuthNode<double> Iter1, Iter2; for (int i = 0; i < mtx1.storage.Rows.Count; ++i) { for (int j = 0; j < mtx2.storage.Cols.Count; ++j) { tmp = 0; //initalize mult of i-th row and j-th column Iter1 = mtx1.storage.Rows[i].Left; Iter2 = mtx2.storage.Cols[j].Up; while (Iter1 != mtx1.storage.Rows[i] && Iter2 != mtx2.storage.Cols[j]) { if (Iter1.Col == Iter2.Row) { tmp += Iter1.Val * Iter2.Val; Iter1 = Iter1.Left; Iter2 = Iter2.Up; } else if (Iter1.Col < Iter2.Row) { Iter2 = Iter2.Up; } else //(Iter2.Col < Iter1.Col) { Iter1 = Iter1.Left; } } if (tmp != 0) // paste not 0 element { Res.At(i, j, tmp); } } } return Res; }