コード例 #1
0
        /// <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());
        }
コード例 #2
0
        /// <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;
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
 /// <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);
                     }
                 }
             }
         }
     }
 }
コード例 #6
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;
            }
        }