Пример #1
0
        /// <summary>
        /// Notifies the strategy that a fill-in has been created
        /// </summary>
        /// <param name="matrix">The matrix.</param>
        /// <param name="fillin">The fill-in.</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if <paramref name="matrix"/> or <paramref name="fillin"/> is <c>null</c>.
        /// </exception>
        public void CreateFillin(ISparseMatrix <T> matrix, ISparseMatrixElement <T> fillin)
        {
            matrix.ThrowIfNull(nameof(matrix));
            fillin.ThrowIfNull(nameof(fillin));

            if (_markowitzProduct == null)
            {
                return;
            }

            // Update the markowitz row count
            int index = fillin.Row;

            _markowitzRow[index]++;
            _markowitzProduct[index] =
                Math.Min(_markowitzRow[index] * _markowitzColumn[index], _maxMarkowitzCount);
            if (_markowitzRow[index] == 1 && _markowitzColumn[index] != 0)
            {
                Singletons--;
            }

            // Update the markowitz column count
            index = fillin.Column;
            _markowitzColumn[index]++;
            _markowitzProduct[index] =
                Math.Min(_markowitzRow[index] * _markowitzColumn[index], _maxMarkowitzCount);
            if (_markowitzRow[index] != 0 && _markowitzColumn[index] == 1)
            {
                Singletons--;
            }
        }
Пример #2
0
        /// <summary>
        /// This method will check whether or not a pivot element is valid or not.
        /// It checks for the submatrix right/below of the pivot.
        /// </summary>
        /// <param name="pivot">The pivot candidate.</param>
        /// <param name="max">The maximum index that a pivot can have.</param>
        /// <returns>
        /// True if the pivot can be used.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="pivot"/> is <c>null</c>.</exception>
        public bool IsValidPivot(ISparseMatrixElement <T> pivot, int max)
        {
            pivot.ThrowIfNull(nameof(pivot));
            if (pivot.Row > max || pivot.Column > max)
            {
                return(false);
            }

            // Get the magnitude of the current pivot
            var magnitude = Magnitude(pivot.Value);

            // Search for the largest element below the pivot
            var element = pivot.Below;
            var largest = 0.0;

            while (element != null && element.Row <= max)
            {
                largest = Math.Max(largest, Magnitude(element.Value));
                element = element.Below;
            }

            // Check the validity
            if (largest * RelativePivotThreshold < magnitude)
            {
                return(true);
            }
            return(false);
        }
Пример #3
0
        /// <summary>
        /// Moves a chosen pivot to the diagonal.
        /// </summary>
        /// <param name="pivot">The pivot element.</param>
        /// <param name="step">The current step of factoring.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="pivot"/> is <c>null</c>.</exception>
        protected void MovePivot(ISparseMatrixElement <T> pivot, int step)
        {
            pivot.ThrowIfNull(nameof(pivot));
            Parameters.MovePivot(Matrix, Vector, pivot, step);

            // Move the pivot in the matrix
            SwapRows(pivot.Row, step);
            SwapColumns(pivot.Column, step);

            // Update the pivoting strategy
            Parameters.Update(Matrix, pivot, Size - PivotSearchReduction);
        }
Пример #4
0
        /// <summary>
        /// Update the strategy after the pivot was moved.
        /// </summary>
        /// <param name="matrix">The matrix.</param>
        /// <param name="pivot">The pivot element.</param>
        /// <param name="limit">The maximum row/column for pivots.</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if <paramref name="matrix"/> or <paramref name="pivot"/> is <c>null</c>.
        /// </exception>
        public void Update(ISparseMatrix <T> matrix, ISparseMatrixElement <T> pivot, int limit)
        {
            matrix.ThrowIfNull(nameof(matrix));
            pivot.ThrowIfNull(nameof(pivot));

            // If we haven't setup, just skip
            if (_markowitzProduct == null)
            {
                return;
            }

            // Go through all elements below the pivot. If they exist, then we can subtract 1 from the Markowitz row vector!
            for (var column = pivot.Below; column != null && column.Row <= limit; column = column.Below)
            {
                var row = column.Row;

                // Update the Markowitz product
                _markowitzProduct[row] -= _markowitzColumn[row];
                --_markowitzRow[row];

                // If we reached 0, then the row just turned to a singleton row
                if (_markowitzRow[row] == 0)
                {
                    Singletons++;
                }
            }

            // go through all elements right of the pivot. For every element, we can subtract 1 from the Markowitz column vector!
            for (var row = pivot.Right; row != null && row.Column <= limit; row = row.Right)
            {
                var column = row.Column;

                // Update the Markowitz product
                _markowitzProduct[column] -= _markowitzRow[column];
                --_markowitzColumn[column];

                // If we reached 0, then the column just turned to a singleton column
                // This only adds a singleton if the row wasn't detected as a singleton row first
                if (_markowitzColumn[column] == 0 && _markowitzRow[column] != 0)
                {
                    Singletons++;
                }
            }
        }
Пример #5
0
        /// <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++;
                }
            }
        }