예제 #1
0
 internal void AddTripletTerm(SparseCell L_ik, SparseCell L_jk, SparseCell D_k)
 {
     terms.Add(L_ik);
     terms.Add(L_jk);
     terms.Add(D_k);
     termCount += 3;
 }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SparseMatrix"/> class.
 /// </summary>
 /// <param name="numRows">The number rows.</param>
 /// <param name="numCols">The number cols.</param>
 public SparseMatrix(int numRows, int numCols)
 {
     cellsRowbyRow = new List <SparseCell>();
     NumRows       = numRows;
     NumCols       = numCols;
     Diagonals     = new SparseCell[numRows];
     RowFirsts     = new SparseCell[numRows];
     RowLasts      = new SparseCell[numRows];
     ColFirsts     = new SparseCell[numCols];
     ColLasts      = new SparseCell[numCols];
 }
예제 #3
0
 /// <summary>
 /// Searches down to.
 /// </summary>
 /// <param name="rowIndex">Index of the row.</param>
 /// <param name="startCell">The start cell.</param>
 /// <returns>SparseCell.</returns>
 /// <exception cref="ArithmeticException">No non-zero sparse matrix cell found at the location.</exception>
 private SparseCell SearchDownToCell(int rowIndex, SparseCell startCell)
 {
     do
     {
         if (startCell == null || startCell.RowIndex > rowIndex)
         {
             return(null);
         }
         if (startCell.RowIndex == rowIndex)
         {
             return(startCell);
         }
         startCell = startCell.Down;
     } while (true);
 }
예제 #4
0
 /// <summary>
 /// Searches the left to.
 /// </summary>
 /// <param name="colIndex">Index of the col.</param>
 /// <param name="startCell">The start cell.</param>
 /// <returns>SparseCell.</returns>
 private SparseCell SearchRightToCell(int colIndex, SparseCell startCell)
 {
     do
     {
         if (startCell == null || startCell.ColIndex > colIndex)
         {
             return(null);
         }
         if (startCell.ColIndex == colIndex)
         {
             return(startCell);
         }
         startCell = startCell.Right;
     } while (true);
 }
예제 #5
0
 /// <summary>
 /// Searches the left to.
 /// </summary>
 /// <param name="colIndex">Index of the col.</param>
 /// <param name="startCell">The start cell.</param>
 /// <returns>SparseCell.</returns>
 private Boolean TrySearchRightToCell(int colIndex, ref SparseCell startCell)
 {
     do
     {
         if (startCell == null || startCell.ColIndex > colIndex)
         {
             return(false);
         }
         if (startCell.ColIndex == colIndex)
         {
             return(true);
         }
         startCell = startCell.Right;
     } while (true);
 }
예제 #6
0
        /// <summary>
        /// Removes the columns.
        /// </summary>
        /// <param name="colIndicesToRemove">The col indices to remove.</param>
        public void RemoveColumns(IList <int> colIndicesToRemove)
        {
            TopologyChanged = true;
            var numToRemove   = colIndicesToRemove.Count;
            var removeIndices = colIndicesToRemove.OrderBy(i => i).ToArray();

            for (int i = 0; i < numToRemove; i++)
            {
                var cell = ColFirsts[removeIndices[i]];
                while (cell != null)
                {
                    var nextCell = cell.Down;
                    RemoveCell(cell);
                    if (cell.ColIndex == cell.RowIndex)
                    {
                        Diagonals[cell.RowIndex] = null;
                    }
                    cell = nextCell;
                }
            }
            NumCols -= numToRemove;
            var newColFirsts = new SparseCell[NumCols];
            var newColLasts  = new SparseCell[NumCols];
            var offset       = 0;

            for (int i = 0; i < NumCols; i++)
            {
                while (offset < numToRemove && (i + offset) == removeIndices[offset])
                {
                    offset++;
                }
                newColFirsts[i] = ColFirsts[i + offset];
                newColLasts[i]  = ColLasts[i + offset];
                var cell = ColFirsts[i + offset];
                while (cell != null)
                {
                    cell.ColIndex = i;
                    if (cell.RowIndex == i)
                    {
                        Diagonals[i] = cell;
                    }
                    cell = cell.Down;
                }
            }
            ColFirsts = newColFirsts;
            ColLasts  = newColLasts;
        }
예제 #7
0
        /// <summary>
        /// Removes the column.
        /// </summary>
        /// <param name="colIndexToRemove">The col index to remove.</param>
        public void RemoveColumn(int colIndexToRemove)
        {
            TopologyChanged = true;
            var thisCell = ColFirsts[colIndexToRemove];

            while (thisCell != null)
            {
                var nextCell = thisCell.Down;
                RemoveCell(thisCell);
                if (thisCell.RowIndex == colIndexToRemove)
                {
                    Diagonals[colIndexToRemove] = null;
                }
                thisCell = nextCell;
            }

            NumCols--;
            var newColFirsts = new SparseCell[NumCols];
            var newColLasts  = new SparseCell[NumCols];

            for (int i = 0; i < colIndexToRemove; i++)
            {
                newColFirsts[i] = ColFirsts[i];
                newColLasts[i]  = ColLasts[i];
            }
            for (int i = colIndexToRemove; i < NumCols; i++)
            {
                newColFirsts[i] = ColFirsts[i + 1];
                newColLasts[i]  = ColLasts[i + 1];
                var cell = ColFirsts[i + 1];
                while (cell != null)
                {
                    cell.ColIndex = i;
                    if (cell.RowIndex == i)
                    {
                        Diagonals[i] = cell;
                    }
                    cell = cell.Down;
                }
            }
            ColFirsts = newColFirsts;
            ColLasts  = newColLasts;
        }
예제 #8
0
        /// <summary>
        /// Finds the index of the insertion within the cellsRowbyRow. Of course, there are built-in functions to do this,
        /// but the idea with writing our own is that we can make a faster search given information that is known about
        /// this .
        /// </summary>
        /// <param name="cell">The cell.</param>
        /// <returns>System.Int32.</returns>
        //private int FindInsertionIndex(SparseCell cell)
        //{
        //int i= cellsRowbyRow.IndexOf(cell);
        // if (i >= 0) return i;
        //var averageCellPerRow = NumNonZero / NumRows;
        //var index = Math.Min(averageCellPerRow * cell.RowIndex + cell.ColIndex, NumNonZero - 1);
        //int step = averageCellPerRow;
        //do
        //{
        //    if (cell.RowIndex < cellsRowbyRow[index].RowIndex
        //        || (cell.RowIndex == cellsRowbyRow[index].RowIndex
        //        && cell.ColIndex < cellsRowbyRow[index].ColIndex))
        //    {
        //        if (index == 0 || step == 1) step = 0;
        //        else if (step > 0) step = -step / 2;
        //    }
        //    else if (cell.RowIndex > cellsRowbyRow[index].RowIndex
        //        || (cell.RowIndex == cellsRowbyRow[index].RowIndex
        //        && cell.ColIndex > cellsRowbyRow[index].ColIndex))
        //    {
        //        if (index == NumNonZero - 1 || step == -1) step = 0;
        //        else if (step < 0) step = -step / 2;
        //    }
        //    else step = 0;
        //    index += step;
        //    if (index < 0)
        //    {
        //        step -= index;
        //        index = 0;
        //    }
        //    else if (index >= NumNonZero)
        //    {
        //        step = index - (NumNonZero - 1);
        //        index = NumNonZero - 1;
        //    }
        //} while (step != 0);
        //return index;
        //}


        /// <summary>
        /// Removes the row.
        /// </summary>
        /// <param name="rowIndexToRemove">The row index to remove.</param>
        public void RemoveRow(int rowIndexToRemove)
        {
            TopologyChanged = true;
            var thisCell = RowFirsts[rowIndexToRemove];

            while (thisCell != null)
            {
                var nextCell = thisCell.Right;
                RemoveCell(thisCell);
                if (thisCell.ColIndex == rowIndexToRemove)
                {
                    Diagonals[rowIndexToRemove] = null;
                }
                thisCell = nextCell;
            }

            NumRows--;
            var newRowFirsts = new SparseCell[NumRows];
            var newRowLasts  = new SparseCell[NumRows];

            for (int i = 0; i < rowIndexToRemove; i++)
            {
                newRowFirsts[i] = RowFirsts[i];
                newRowLasts[i]  = RowLasts[i];
            }
            for (int i = rowIndexToRemove; i < NumRows; i++)
            {
                newRowFirsts[i] = RowFirsts[i + 1];
                newRowLasts[i]  = RowLasts[i + 1];
                var cell = RowFirsts[i + 1];
                while (cell != null)
                {
                    cell.RowIndex = i;
                    if (cell.ColIndex == i)
                    {
                        Diagonals[i] = cell;
                    }
                    cell = cell.Right;
                }
            }
            RowFirsts = newRowFirsts;
            RowLasts  = newRowLasts;
        }
예제 #9
0
        private void RemoveCell(SparseCell cell)
        {
            if (cell.Left == null)
            {
                RowFirsts[cell.RowIndex] = cell.Right;
            }
            else
            {
                cell.Left.Right = cell.Right;
            }
            if (cell.Right == null)
            {
                RowLasts[cell.RowIndex] = cell.Left;
            }
            else
            {
                cell.Right.Left = cell.Left;
            }

            if (cell.Up == null)
            {
                ColFirsts[cell.ColIndex] = cell.Down;
            }
            else
            {
                cell.Up.Down = cell.Down;
            }
            if (cell.Down == null)
            {
                ColLasts[cell.ColIndex] = cell.Up;
            }
            else
            {
                cell.Down.Up = cell.Up;
            }
            cellsRowbyRow.Remove(cell);
            NumNonZero--;
            TopologyChanged = true;
        }
예제 #10
0
        private SparseCell AddCell(int rowI, int colI, double value = Double.NaN)
        {
            var cell = new SparseCell(rowI, colI, value);

            // stitch it into the rows
            if (RowFirsts[rowI] == null && RowLasts[rowI] == null)
            {
                RowFirsts[rowI] = RowLasts[rowI] = cell;
            }
            else if (RowFirsts[rowI] == null || RowFirsts[rowI].ColIndex > colI)
            {
                cell.Right           = RowFirsts[rowI];
                RowFirsts[rowI].Left = cell;
                RowFirsts[rowI]      = cell;
            }
            else if (RowLasts[rowI].ColIndex < colI)
            {
                cell.Left            = RowLasts[rowI];
                RowLasts[rowI].Right = cell;
                RowLasts[rowI]       = cell;
            }
            else
            {
                var startCell = RowFirsts[rowI];
                while (startCell.ColIndex < colI)
                {
                    startCell = startCell.Right;
                }
                cell.Right      = startCell;
                cell.Left       = startCell.Left;
                cell.Left.Right = cell;
                startCell.Left  = cell;
            }
            // stitch it into the colums
            if (ColFirsts[colI] == null && ColLasts[colI] == null)
            {
                ColFirsts[colI] = ColLasts[colI] = cell;
            }
            else if (ColFirsts[colI].RowIndex > rowI)
            {
                cell.Down          = ColFirsts[colI];
                ColFirsts[colI].Up = cell;
                ColFirsts[colI]    = cell;
            }
            else if (ColLasts[colI].RowIndex < rowI)
            {
                cell.Up             = ColLasts[colI];
                ColLasts[colI].Down = cell;
                ColLasts[colI]      = cell;
            }
            else
            {
                var startCell = ColFirsts[colI];
                while (startCell.RowIndex < rowI)
                {
                    startCell = startCell.Down;
                }
                cell.Down    = startCell;
                cell.Up      = startCell.Up;
                cell.Up.Down = cell;
                startCell.Up = cell;
            }
            if (rowI == colI)
            {
                Diagonals[rowI] = cell;
            }
            cellsRowbyRow.Add(cell);
            NumNonZero++;
            TopologyChanged = true;

            return(cell);
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SparseMatrix"/> class.
        /// </summary>
        /// <param name="indices">The row by row indices.</param>
        /// <param name="values">The values.</param>
        /// <param name="numRows">The number rows.</param>
        /// <param name="numCols">The number cols.</param>
        /// <param name="InRowOrder">The in row order.</param>
        public SparseMatrix(IList <int> indices, IList <double> values, int numRows, int numCols,
                            bool InRowOrder = true) : this(numRows, numCols)
        {
            if (InRowOrder)
            {
                #region Fill-in In Order

                /* this is an elaborate method to speed up the stitching together of new cells */
                var rowI          = 0;
                var rowLowerLimit = 0;
                var rowUpperLimit = NumCols;
                var newRow        = true;
                for (var i = 0; i < values.Count; i++)
                {
                    var index = indices[i];
                    var value = values[i];
                    while (i < values.Count - 1 && indices[i] == indices[i + 1])
                    {
                        i++;
                        value += values[i];
                    }
                    while (index >= rowUpperLimit)
                    {
                        newRow = true;
                        rowI++;
                        rowLowerLimit += NumCols;
                        rowUpperLimit += NumCols;
                    }
                    var colI = index - rowLowerLimit;
                    var cell = new SparseCell(rowI, colI, value);
                    if (rowI == colI)
                    {
                        Diagonals[rowI] = cell;
                    }
                    cellsRowbyRow.Add(cell);
                    if (newRow)
                    {
                        RowFirsts[rowI] = cell;
                        RowLasts[rowI]  = cell;
                        newRow          = false;
                    }
                    else
                    {
                        cell.Left            = RowLasts[rowI];
                        RowLasts[rowI].Right = cell;
                        RowLasts[rowI]       = cell;
                    }
                    if (ColFirsts[colI] == null)
                    {
                        ColFirsts[colI] = cell;
                        ColLasts[colI]  = cell;
                    }
                    else
                    {
                        cell.Up             = ColLasts[colI];
                        ColLasts[colI].Down = cell;
                        ColLasts[colI]      = cell;
                    }
                }

                #endregion
            }
            else
            {
                var count = values.Count;
                for (int i = 0; i < count; i++)
                {
                    var index = indices[i];
                    var rowI  = index / NumCols;
                    var colI  = index % NumCols;
                    this[rowI, colI] += values[i];
                }
            }
            NumNonZero = cellsRowbyRow.Count;
        }
예제 #12
0
 internal void AddDoubletTerm(SparseCell L_jk, SparseCell D_k)
 {
     terms.Add(L_jk);
     terms.Add(D_k);
     termCount += 2;
 }
예제 #13
0
 internal CholeskyDCell(int rowIndex, int colIndex, SparseCell ACell) : base(rowIndex, colIndex)
 {
     this.ACell = ACell;
 }
예제 #14
0
 internal CholeskyLCell(int rowIndex, int colIndex, SparseCell aCell, SparseCell diagDenominatorCell) : base(rowIndex, colIndex)
 {
     ACell = aCell;
     DiagDenominatorCell = diagDenominatorCell;
 }