/// <summary> /// Setup the pivot strategy. /// </summary> /// <param name="matrix">The matrix.</param> /// <param name="rhs">The right-hand side vector.</param> /// <param name="eliminationStep">The current elimination step.</param> /// <param name="max">The maximum row/column index.</param> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="matrix"/> or <paramref name="rhs"/> is <c>null</c>. /// </exception> public void Setup(ISparseMatrix <T> matrix, ISparseVector <T> rhs, int eliminationStep, int max) { matrix.ThrowIfNull(nameof(matrix)); rhs.ThrowIfNull(nameof(rhs)); // Initialize Markowitz row, column and product vectors if necessary if (_markowitzRow == null || _markowitzRow.Length != matrix.Size + 1) { Initialize(matrix); } Count(matrix, rhs, eliminationStep, max); Products(eliminationStep, max); }
/// <summary> /// Move the pivot to the diagonal for this elimination step. /// </summary> /// <param name="matrix">The matrix.</param> /// <param name="rhs">The right-hand side vector.</param> /// <param name="pivot">The pivot element.</param> /// <param name="eliminationStep">The elimination step.</param> /// <remarks> /// This is done by swapping the rows and columns of the diagonal and that of the pivot. /// </remarks> /// <exception cref="ArgumentNullException"> /// Thrown if <paramref name="matrix"/>, <paramref name="rhs"/> or <paramref name="pivot"/> is <c>null</c>. /// </exception> public void MovePivot(ISparseMatrix <T> matrix, ISparseVector <T> rhs, ISparseMatrixElement <T> pivot, int eliminationStep) { matrix.ThrowIfNull(nameof(matrix)); rhs.ThrowIfNull(nameof(rhs)); pivot.ThrowIfNull(nameof(pivot)); // If we haven't setup, just skip if (_markowitzProduct == null) { return; } int oldProduct; var row = pivot.Row; var col = pivot.Column; // If the pivot is a singleton, then we just consumed it if (_markowitzProduct[row] == 0 || _markowitzProduct[col] == 0) { Singletons--; } // Exchange rows if (row != eliminationStep) { // Swap row Markowitz numbers var tmp = _markowitzRow[row]; _markowitzRow[row] = _markowitzRow[eliminationStep]; _markowitzRow[eliminationStep] = tmp; // Update the Markowitz product oldProduct = _markowitzProduct[row]; _markowitzProduct[row] = _markowitzRow[row] * _markowitzColumn[row]; if (oldProduct == 0) { if (_markowitzProduct[row] != 0) { Singletons--; } } else { if (_markowitzProduct[row] == 0) { Singletons++; } } } // Exchange columns if (col != eliminationStep) { // Swap column Markowitz numbers var tmp = _markowitzColumn[col]; _markowitzColumn[col] = _markowitzColumn[eliminationStep]; _markowitzColumn[eliminationStep] = tmp; // Update the Markowitz product oldProduct = _markowitzProduct[col]; _markowitzProduct[col] = _markowitzRow[col] * _markowitzColumn[col]; if (oldProduct == 0) { if (_markowitzProduct[col] != 0) { Singletons--; } } else { if (_markowitzProduct[col] == 0) { Singletons++; } } } // Also update the moved pivot oldProduct = _markowitzProduct[eliminationStep]; _markowitzProduct[eliminationStep] = _markowitzRow[eliminationStep] * _markowitzColumn[eliminationStep]; if (oldProduct == 0) { if (_markowitzProduct[eliminationStep] != 0) { Singletons--; } } else { if (_markowitzProduct[eliminationStep] == 0) { Singletons++; } } }