/// <summary> /// 检测两个矩阵的矩阵乘法后得到的新矩阵在row和col /// 列的算式。 /// </summary> /// <param name="matrix1"></param> /// <param name="matrix2"></param> /// <param name="row"></param> /// <param name="col"></param> /// <returns></returns> public static string TestMatrixMultiMatrix(SparseMatrix matrix1, SparseMatrix matrix2, int row, int col) { decimal sumVal = 0; SparseMatrixCell rowHead = matrix1._rowHead[row]; SparseMatrixCell colHead = matrix2._colHead[col]; StringBuilder sb = new StringBuilder(); string connChar = ""; while (rowHead != null && colHead != null) { if (rowHead.ColIndex == colHead.RowIndex) { sb.Append(connChar).Append(rowHead.Val).Append("*").Append(colHead.Val); connChar = "+"; sumVal += rowHead.Val * colHead.Val; colHead = colHead.Down; rowHead = rowHead.Right; } else if (rowHead.ColIndex > colHead.RowIndex) { colHead = colHead.Down; } else if (rowHead.ColIndex < colHead.RowIndex) { rowHead = rowHead.Right; } } sb.Append("=").Append(sumVal); return(sb.ToString()); }
/// <summary> /// 把数据追加到结尾 /// </summary> /// <param name="rowIndex"></param> /// <param name="colIndex"></param> /// <param name="val"></param> void AppendToTail(int rowIndex, int colIndex, decimal val) { SparseMatrixCell cell = new SparseMatrixCell { ColIndex = colIndex, RowIndex = rowIndex, Val = val }; SparseMatrixCell tempColTail = _colTail[colIndex]; if (tempColTail == null) { _colHead[colIndex] = cell; } else { (cell.Up = tempColTail).Down = cell; } _colTail[colIndex] = cell; SparseMatrixCell tempRowTail = _rowTail[rowIndex]; if (tempRowTail == null) { _rowHead[rowIndex] = cell; } else { (cell.Left = tempRowTail).Right = cell; } _rowTail[rowIndex] = cell; }
/// <summary> /// 矩阵向量化 /// </summary> public SparseMatrix Vec() { if (ColCount == 1) { return((SparseMatrix)Clone()); } SparseMatrix newMatrix = new SparseMatrix(ColCount * RowCount, 1); //find=true(寻找头部)、find=false(寻找尾部) SparseMatrixCell newHead = null; SparseMatrixCell tempTail = null; IEnumerator ie = _colHead.GetEnumerator(); for (; ie.MoveNext();) { newHead = (SparseMatrixCell)ie.Current; if (newHead != null) { tempTail = _colTail[newHead.ColIndex]; break; } } if (newHead != null) { SparseMatrixCell tempHead = null; for (; ie.MoveNext();) { tempHead = (SparseMatrixCell)ie.Current; if (tempHead != null) { tempTail.Down = tempHead; tempHead.Up = tempTail; tempTail = _colTail[tempHead.ColIndex]; } } } newMatrix._colHead[0] = newHead; SparseMatrixCell newTail = newHead; while (true) { newTail.RowIndex = RowCount * newTail.ColIndex + newTail.RowIndex; newTail.ColIndex = 0; newTail.Right = newTail.Left = null; newMatrix._rowTail.AppendToTail(newTail, newTail.RowIndex); newMatrix._rowHead.AppendToTail(newTail, newTail.RowIndex); if (newTail.Down == null) { break; } else { newTail = newTail.Down; } } newMatrix._colTail[0] = newTail; return(newMatrix); }
/// <summary> /// 矩阵对角化 /// </summary> public SparseMatrix Diag() { if (ColCount != 1) { throw new Exception("只有向量才能对角化!"); } SparseMatrix newMatrix = new SparseMatrix(RowCount, RowCount); SparseMatrixCell current = _colHead[0], temp; for (int i; current != null;) { i = current.RowIndex; newMatrix._colTail.AppendToTail(current, i); newMatrix._rowTail.AppendToTail(current, i); newMatrix._colHead.AppendToTail(current, i); newMatrix._rowHead.AppendToTail(current, i); current.ColIndex = i; temp = current; current = current.Down; temp.Down = temp.Up = temp.Left = temp.Right = null; } return(newMatrix); }
/// <summary> /// 读取/写入稀疏矩阵指定行列的元素 /// </summary> /// <param name="rowIndex"></param> /// <param name="colIndex"></param> /// <returns></returns> public decimal this[int rowIndex, int colIndex] { set { if (value == 0) { return; } if (colIndex < -1 || rowIndex < -1 || colIndex >= ColCount || rowIndex >= RowCount) { throw new Exception($"索引错误,矩阵的大小是:{RowCount}x{ColCount}"); } SparseMatrixCell setVal = new SparseMatrixCell { Val = value, ColIndex = colIndex, RowIndex = rowIndex }; SparseMatrixCell tempHead = _colHead[colIndex]; SparseMatrixCell tempTail; if (tempHead == null) { _colHead[colIndex] = setVal; _colTail[colIndex] = setVal; } else { tempTail = _colTail[colIndex]; } while (tempHead != null) { if (tempHead.RowIndex == rowIndex) { tempHead.Val = value; return; } else if (tempHead.RowIndex < rowIndex) { if (tempHead.Down == null) { tempHead.Down = setVal; setVal.Up = tempHead; _colTail[colIndex] = setVal; break; } else { tempHead = tempHead.Down; } } else if (tempHead.RowIndex > rowIndex) { if (tempHead.Up == null) { tempHead.Up = setVal; setVal.Down = tempHead; _colHead[colIndex] = setVal; } else { tempHead.Up.Down = setVal; setVal.Up = tempHead.Up; setVal.Down = tempHead; tempHead.Up = setVal; } break; } } tempHead = _rowHead[rowIndex]; if (tempHead == null) { _rowHead[rowIndex] = setVal; _rowTail[rowIndex] = setVal; return; } while (tempHead != null) { if (tempHead.ColIndex == colIndex) { tempHead.Val = value; return; } else if (tempHead.ColIndex < colIndex) { if (tempHead.Right == null) { tempHead.Right = setVal; setVal.Left = tempHead; _rowTail[rowIndex] = setVal; return; } else { tempHead = tempHead.Right; } } else if (tempHead.ColIndex > colIndex) { if (tempHead.Left == null) { tempHead.Left = setVal; setVal.Right = tempHead; _rowHead[rowIndex] = setVal; } else { tempHead.Left.Right = setVal; setVal.Left = tempHead.Left; setVal.Right = tempHead; tempHead.Left = setVal; } return; } } } get { if (colIndex < -1 || rowIndex < -1 || colIndex >= ColCount || rowIndex >= RowCount) { throw new Exception($"索引错误,矩阵的大小是:{RowCount}x{ColCount}"); } SparseMatrixCell lastHead; SparseMatrixCell lastTail; if (rowIndex > colIndex) { lastHead = _rowHead[rowIndex]; if (lastHead == null) { return(0); } lastTail = _rowTail[rowIndex]; bool nearHead = (colIndex << 1) < lastTail.ColIndex + lastHead.ColIndex; if (nearHead) { while (true) { if (lastHead.ColIndex == colIndex) { return(lastHead.Val); } else if (lastHead.ColIndex < colIndex) { if (lastHead.Right == null) { return(0); } else { lastHead = lastHead.Right; } } else if (lastHead.ColIndex > colIndex) { return(0); } } } else { while (true) { if (lastTail.ColIndex == colIndex) { return(lastTail.Val); } else if (lastTail.ColIndex > colIndex) { if (lastTail.Left == null) { return(0); } else { lastTail = lastTail.Left; } } else if (lastTail.ColIndex < colIndex) { return(0); } } } } else { lastHead = _colHead[colIndex]; if (lastHead == null) { return(0); } lastTail = _colTail[colIndex]; bool nearHead = (rowIndex << 1) < lastHead.RowIndex + lastTail.RowIndex; if (nearHead) { while (true) { if (lastHead.RowIndex == rowIndex) { return(lastHead.Val); } else if (lastHead.RowIndex < rowIndex) { if (lastHead.Down == null) { return(0); } else { lastHead = lastHead.Down; } } else if (lastHead.RowIndex > rowIndex) { return(0); } } } else { while (true) { if (lastTail.RowIndex == rowIndex) { return(lastTail.Val); } else if (lastTail.RowIndex > rowIndex) { if (lastTail.Up == null) { return(0); } else { lastTail = lastTail.Up; } } else if (lastTail.RowIndex < rowIndex) { return(0); } } } } } }
/// <summary> /// 把值追加到指定位置上。 /// </summary> /// <param name="rowIndex"></param> /// <param name="colIndex"></param> /// <param name="val"></param> private void AddTo(int rowIndex, int colIndex, decimal val) { if (val == 0) { return; } if (colIndex < -1 || rowIndex < -1 || colIndex >= ColCount || rowIndex >= RowCount) { throw new Exception($"索引错误,矩阵的大小是:{RowCount}x{ColCount}"); } SparseMatrixCell setVal = new SparseMatrixCell { Val = val, ColIndex = colIndex, RowIndex = rowIndex }; SparseMatrixCell temp = _colHead[colIndex]; while (true) { if (temp == null) { _colHead[colIndex] = setVal; } else if (temp.RowIndex == rowIndex) { temp.Val += val; return; } else if (temp.RowIndex < rowIndex) { if (temp.Down == null) { temp.Down = setVal; setVal.Up = temp; } else { temp = temp.Down; continue; } } else if (temp.RowIndex < rowIndex && temp.Down.RowIndex > rowIndex) { temp.Down.Up = setVal; setVal.Down = temp.Down; temp.Down = setVal; setVal.Up = temp; } else { continue; } break; } temp = _rowHead[rowIndex]; while (true) { if (temp == null) { _rowHead[rowIndex] = setVal; } else if (temp.ColIndex == colIndex) { temp.Val += val; return; } else if (temp.ColIndex < colIndex) { if (temp.Right == null) { temp.Right = setVal; setVal.Left = temp; } else { temp = temp.Right; continue; } } else if (temp.ColIndex < colIndex && temp.Right.ColIndex > colIndex) { temp.Right.Left = setVal; setVal.Right = temp.Right; temp.Right = setVal; setVal.Left = temp; } else { continue; } break; } }