예제 #1
0
파일: Row.cs 프로젝트: slicol/SpiceSharp
        /// <summary>
        /// Create or get an element in the row
        /// </summary>
        /// <param name="row">Row (used for creating a new element)</param>
        /// <param name="column">Column</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 <T> result)
        {
            result = null;
            SparseMatrixElement <T> 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 <T>(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
파일: Column.cs 프로젝트: slicol/SpiceSharp
        /// <summary>
        /// Create or get an element in the column
        /// </summary>
        /// <param name="row">Row</param>
        /// <param name="column">Column (used for creating a new element)</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 <T> result)
        {
            SparseMatrixElement <T> 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 <T>(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
파일: Row.cs 프로젝트: slicol/SpiceSharp
        /// <summary>
        /// Find an element in the row without creating it, returns null if it doesn't exist
        /// </summary>
        /// <param name="column">Column</param>
        public SparseMatrixElement <T> Find(int column)
        {
            SparseMatrixElement <T> element = FirstInRow;

            while (element != null)
            {
                if (element.Column == column)
                {
                    return(element);
                }
                if (element.Column > column)
                {
                    return(null);
                }
                element = element.NextInRow;
            }
            return(null);
        }
예제 #4
0
파일: Column.cs 프로젝트: slicol/SpiceSharp
        /// <summary>
        /// Find an element in the column without creating it, returns null if it doesn't exist
        /// </summary>
        /// <param name="row">Row</param>
        public SparseMatrixElement <T> Find(int row)
        {
            SparseMatrixElement <T> element = FirstInColumn;

            while (element != null)
            {
                if (element.Row == row)
                {
                    return(element);
                }
                if (element.Row > row)
                {
                    return(null);
                }
                element = element.NextInColumn;
            }
            return(null);
        }
예제 #5
0
파일: Row.cs 프로젝트: slicol/SpiceSharp
 /// <summary>
 /// Remove an element from the row
 /// </summary>
 /// <param name="element">Element</param>
 public void Remove(SparseMatrixElement <T> 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;
     }
 }
예제 #6
0
파일: Column.cs 프로젝트: slicol/SpiceSharp
 /// <summary>
 /// Remove an element from the row
 /// </summary>
 /// <param name="element">Element</param>
 public void Remove(SparseMatrixElement <T> 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;
     }
 }
예제 #7
0
파일: Row.cs 프로젝트: slicol/SpiceSharp
        /// <summary>
        /// Insert an element in the row
        /// This method assumes an element does not exist at its indices!
        /// </summary>
        /// <param name="newElement">New element</param>
        public void Insert(SparseMatrixElement <T> newElement)
        {
            int column = newElement.Column;
            SparseMatrixElement <T> 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
파일: Row.cs 프로젝트: slicol/SpiceSharp
        /// <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">First matrix element</param>
        /// <param name="second">Second matrix element</param>
        /// <param name="columnFirst">First column</param>
        /// <param name="columnSecond">Second column</param>
        public void Swap(SparseMatrixElement <T> first, SparseMatrixElement <T> 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
                SparseMatrixElement <T> 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
                SparseMatrixElement <T> 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
                    SparseMatrixElement <T> 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;
                }
            }
        }