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; }
/// <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]; }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
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; }
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); }
/// <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; }
internal void AddDoubletTerm(SparseCell L_jk, SparseCell D_k) { terms.Add(L_jk); terms.Add(D_k); termCount += 2; }
internal CholeskyDCell(int rowIndex, int colIndex, SparseCell ACell) : base(rowIndex, colIndex) { this.ACell = ACell; }
internal CholeskyLCell(int rowIndex, int colIndex, SparseCell aCell, SparseCell diagDenominatorCell) : base(rowIndex, colIndex) { ACell = aCell; DiagDenominatorCell = diagDenominatorCell; }