Exemple #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>
        public override void CreateFillin(SparseMatrix <T> matrix, MatrixElement <T> fillin)
        {
            matrix.ThrowIfNull(nameof(matrix));
            fillin.ThrowIfNull(nameof(fillin));

            // 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--;
            }
        }
Exemple #2
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="eliminationStep">The elimination step.</param>
        public override void Update(SparseMatrix <T> matrix, MatrixElement <T> pivot, int eliminationStep)
        {
            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 = 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 = 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++;
                }
            }
        }
Exemple #3
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>
        /// <returns>
        /// True if the pivot can be used.
        /// </returns>
        public override bool IsValidPivot(MatrixElement <T> pivot)
        {
            pivot.ThrowIfNull(nameof(pivot));

            // 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)
            {
                largest = Math.Max(largest, Magnitude(element.Value));
                element = element.Below;
            }

            // Check the validity
            if (largest * RelativePivotThreshold < magnitude)
            {
                return(true);
            }
            return(false);
        }
Exemple #4
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>
        public override void MovePivot(SparseMatrix <T> matrix, SparseVector <T> rhs, MatrixElement <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 column = pivot.Column;

            // If the pivot is a singleton, then we just consumed it
            if (_markowitzProduct[pivot.Row] == 0 || _markowitzProduct[pivot.Column] == 0)
            {
                Singletons--;
            }

            // Exchange rows
            if (pivot.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 (column != eliminationStep)
            {
                // Swap column Markowitz numbers
                var tmp = _markowitzColumn[column];
                _markowitzColumn[column]          = _markowitzColumn[eliminationStep];
                _markowitzColumn[eliminationStep] = tmp;

                // Update the Markowitz product
                oldProduct = _markowitzProduct[column];
                _markowitzProduct[column] = _markowitzRow[column] * _markowitzColumn[column];
                if (oldProduct == 0)
                {
                    if (_markowitzProduct[column] != 0)
                    {
                        Singletons--;
                    }
                }
                else
                {
                    if (_markowitzProduct[column] == 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++;
                }
            }
        }