Пример #1
0
            /// <summary>
            /// Create or get an element in the row.
            /// </summary>
            /// <param name="row">The row index used for creating a new element</param>
            /// <param name="column">The column index.</param>
            /// <param name="result">The found or created element.</param>
            /// <returns>True if the element was found, false if it was created.</returns>
            public bool CreateGetElement(int row, int column, out SparseMatrixElement result)
            {
                result = null;
                SparseMatrixElement element = FirstInRow, lastElement = null;

                while (element != null)
                {
                    if (element.Column > column)
                    {
                        break;
                    }
                    if (element.Column == column)
                    {
                        // Found the element
                        result = element;
                        return(true);
                    }

                    lastElement = element;
                    element     = element.NextInRow;
                }

                // Create a new element
                result = new SparseMatrixElement(row, column);

                // Update links for last element
                if (lastElement == null)
                {
                    FirstInRow = result;
                }
                else
                {
                    lastElement.NextInRow = result;
                }
                result.PreviousInRow = lastElement;

                // Update links for next element
                if (element == null)
                {
                    LastInRow = result;
                }
                else
                {
                    element.PreviousInRow = result;
                }
                result.NextInRow = element;

                // Could not find existing element
                return(false);
            }
Пример #2
0
            /// <summary>
            /// Create or get an element in the column.
            /// </summary>
            /// <param name="row">The row index used for creating a new element</param>
            /// <param name="column">The column index.</param>
            /// <param name="result">The found or created element.</param>
            /// <returns>True if the element was found, false if it was created.</returns>
            public bool CreateGetElement(int row, int column, out SparseMatrixElement result)
            {
                SparseMatrixElement element = FirstInColumn, lastElement = null;

                while (element != null)
                {
                    if (element.Row > row)
                    {
                        break;
                    }
                    if (element.Row == row)
                    {
                        result = element;
                        return(true);
                    }

                    lastElement = element;
                    element     = element.NextInColumn;
                }

                // Create a new element
                result = new SparseMatrixElement(row, column);

                // Update links for last element
                if (lastElement == null)
                {
                    FirstInColumn = result;
                }
                else
                {
                    lastElement.NextInColumn = result;
                }
                result.PreviousInColumn = lastElement;

                // Update links for next element
                if (element == null)
                {
                    LastInColumn = result;
                }
                else
                {
                    element.PreviousInColumn = result;
                }
                result.NextInColumn = element;

                // Did not find element
                return(false);
            }
Пример #3
0
 /// <summary>
 /// Remove an element from the row.
 /// </summary>
 /// <param name="element">The element to be removed.</param>
 public void Remove(SparseMatrixElement element)
 {
     if (element.PreviousInRow == null)
     {
         FirstInRow = element.NextInRow;
     }
     else
     {
         element.PreviousInRow.NextInRow = element.NextInRow;
     }
     if (element.NextInRow == null)
     {
         LastInRow = element.PreviousInRow;
     }
     else
     {
         element.NextInRow.PreviousInRow = element.PreviousInRow;
     }
 }
Пример #4
0
 /// <summary>
 /// Remove an element from the column.
 /// </summary>
 /// <param name="element">The element to be removed.</param>
 public void Remove(SparseMatrixElement element)
 {
     if (element.PreviousInColumn == null)
     {
         FirstInColumn = element.NextInColumn;
     }
     else
     {
         element.PreviousInColumn.NextInColumn = element.NextInColumn;
     }
     if (element.NextInColumn == null)
     {
         LastInColumn = element.PreviousInColumn;
     }
     else
     {
         element.NextInColumn.PreviousInColumn = element.PreviousInColumn;
     }
 }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SparseMatrix{T}"/> class.
        /// </summary>
        /// <param name="size">The matrix size.</param>
        public SparseMatrix(int size)
            : base(size)
        {
            _allocatedSize = Math.Max(InitialSize, size);

            // Allocate rows
            _rows = new Row[_allocatedSize + 1];
            for (var i = 1; i <= _allocatedSize; i++)
            {
                _rows[i] = new Row();
            }

            // Allocate columns
            _columns = new Column[_allocatedSize + 1];
            for (var i = 1; i <= _allocatedSize; i++)
            {
                _columns[i] = new Column();
            }

            // Other
            _diagonal = new SparseMatrixElement[_allocatedSize + 1];
            _trashCan = new SparseMatrixElement(0, 0);
        }
Пример #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SparseMatrix{T}"/> class.
        /// </summary>
        public SparseMatrix()
            : base(1)
        {
            _allocatedSize = InitialSize;

            // Allocate rows
            _rows = new Row[InitialSize + 1];
            for (var i = 1; i <= InitialSize; i++)
            {
                _rows[i] = new Row();
            }

            // Allocate columns
            _columns = new Column[InitialSize + 1];
            for (var i = 1; i <= InitialSize; i++)
            {
                _columns[i] = new Column();
            }

            // Other
            _diagonal = new SparseMatrixElement[InitialSize + 1];
            _trashCan = new SparseMatrixElement(0, 0);
        }
Пример #7
0
            /// <summary>
            /// Insert an element in the row. This method assumes an element does not exist at its indices!
            /// </summary>
            /// <param name="newElement">The new element to insert.</param>
            public void Insert(SparseMatrixElement newElement)
            {
                var column = newElement.Column;
                SparseMatrixElement element = FirstInRow, lastElement = null;

                while (element != null)
                {
                    if (element.Column > column)
                    {
                        break;
                    }
                    lastElement = element;
                    element     = element.NextInRow;
                }

                // Update links for last element
                if (lastElement == null)
                {
                    FirstInRow = newElement;
                }
                else
                {
                    lastElement.NextInRow = newElement;
                }
                newElement.PreviousInRow = lastElement;

                // Update links for next element
                if (element == null)
                {
                    LastInRow = newElement;
                }
                else
                {
                    element.PreviousInRow = newElement;
                }
                newElement.NextInRow = element;
            }
Пример #8
0
            /// <summary>
            /// Swap two elements in the row, <paramref name="first"/> and <paramref name="columnFirst"/>
            /// are supposed to come first in the row. Does not update column pointers!
            /// </summary>
            /// <param name="first">The first matrix element.</param>
            /// <param name="second">The second matrix element.</param>
            /// <param name="columnFirst">The first column.</param>
            /// <param name="columnSecond">The second column.</param>
            public void Swap(SparseMatrixElement first, SparseMatrixElement second, int columnFirst,
                             int columnSecond)
            {
                if (first == null && second == null)
                {
                    throw new ArgumentException("Both matrix elements cannot be null");
                }

                if (first == null)
                {
                    // Do we need to move the element?
                    if (second.PreviousInRow == null || second.PreviousInRow.Column < columnFirst)
                    {
                        second.Column = columnFirst;
                        return;
                    }

                    // Move the element back
                    var element = second.PreviousInRow;
                    Remove(second);
                    while (element.PreviousInRow != null && element.PreviousInRow.Column > columnFirst)
                    {
                        element = element.PreviousInRow;
                    }

                    // We now have the first element below the insertion point
                    if (element.PreviousInRow == null)
                    {
                        FirstInRow = second;
                    }
                    else
                    {
                        element.PreviousInRow.NextInRow = second;
                    }
                    second.PreviousInRow  = element.PreviousInRow;
                    element.PreviousInRow = second;
                    second.NextInRow      = element;
                    second.Column         = columnFirst;
                }
                else if (second == null)
                {
                    // Do we need to move the element?
                    if (first.NextInRow == null || first.NextInRow.Column > columnSecond)
                    {
                        first.Column = columnSecond;
                        return;
                    }

                    // Move the element forward
                    var element = first.NextInRow;
                    Remove(first);
                    while (element.NextInRow != null && element.NextInRow.Column < columnSecond)
                    {
                        element = element.NextInRow;
                    }

                    // We now have the first element above the insertion point
                    if (element.NextInRow == null)
                    {
                        LastInRow = first;
                    }
                    else
                    {
                        element.NextInRow.PreviousInRow = first;
                    }
                    first.NextInRow     = element.NextInRow;
                    element.NextInRow   = first;
                    first.PreviousInRow = element;
                    first.Column        = columnSecond;
                }
                else
                {
                    // Are they adjacent or not?
                    if (first.NextInRow == second)
                    {
                        // Correct surrounding links
                        if (first.PreviousInRow == null)
                        {
                            FirstInRow = second;
                        }
                        else
                        {
                            first.PreviousInRow.NextInRow = second;
                        }
                        if (second.NextInRow == null)
                        {
                            LastInRow = first;
                        }
                        else
                        {
                            second.NextInRow.PreviousInRow = first;
                        }

                        // Correct element links
                        first.NextInRow      = second.NextInRow;
                        second.PreviousInRow = first.PreviousInRow;
                        first.PreviousInRow  = second;
                        second.NextInRow     = first;
                        first.Column         = columnSecond;
                        second.Column        = columnFirst;
                    }
                    else
                    {
                        // Swap surrounding links
                        if (first.PreviousInRow == null)
                        {
                            FirstInRow = second;
                        }
                        else
                        {
                            first.PreviousInRow.NextInRow = second;
                        }
                        first.NextInRow.PreviousInRow = second;
                        if (second.NextInRow == null)
                        {
                            LastInRow = first;
                        }
                        else
                        {
                            second.NextInRow.PreviousInRow = first;
                        }
                        second.PreviousInRow.NextInRow = first;

                        // Swap element links
                        var element = first.PreviousInRow;
                        first.PreviousInRow  = second.PreviousInRow;
                        second.PreviousInRow = element;

                        element          = first.NextInRow;
                        first.NextInRow  = second.NextInRow;
                        second.NextInRow = element;
                        first.Column     = columnSecond;
                        second.Column    = columnFirst;
                    }
                }
            }