Beispiel #1
0
        /// <summary>
        /// Links vector elements.
        /// </summary>
        /// <param name="vector">The vector.</param>
        /// <param name="row">The row variable.</param>
        private void LinkElement(ISparseVector <T> vector, Bridge <int> row)
        {
            var loc = Solver.ExternalToInternal(new MatrixLocation(row.Local, row.Local));

            // Do we need to create an element?
            var local_elt = vector.FindElement(loc.Row);

            if (local_elt == null)
            {
                // Check if solving will result in an element
                var first = vector.GetFirstInVector();
                if (first == null || first.Index > Solver.Size - Solver.Degeneracy)
                {
                    return;
                }
                local_elt = vector.GetElement(loc.Row);
            }
            if (local_elt == null)
            {
                return;
            }
            var parent_elt = Parent.Solver.GetElement(row.Global);

            _elements.Add(new Bridge <Element <T> >(local_elt, parent_elt));
        }
Beispiel #2
0
        private void Count(ISparseMatrix <T> matrix, ISparseVector <T> rhs, int step, int max)
        {
            ISparseMatrixElement <T> element;

            // Get the first element in the vector
            var rhsElement = rhs.GetFirstInVector();

            // Generate Markowitz row count
            for (var i = max; i >= step; i--)
            {
                // Set count to -1 initially to remove count due to pivot element
                var count = -1;
                element = matrix.GetFirstInRow(i);
                while (element != null && element.Column < step)
                {
                    element = element.Right;
                }
                while (element != null) // We want to count the elements outside the limit as well
                {
                    count++;
                    element = element.Right;
                }

                // Include elements on the Rhs vector
                while (rhsElement != null && rhsElement.Index < step)
                {
                    rhsElement = rhsElement.Below;
                }
                if (rhsElement != null && rhsElement.Index == i)
                {
                    count++;
                }

                _markowitzRow[i] = Math.Min(count, _maxMarkowitzCount);
            }

            // Generate Markowitz column count
            for (var i = step; i <= max; i++)
            {
                // Set count to -1 initially to remove count due to pivot element
                var count = -1;
                element = matrix.GetFirstInColumn(i);
                while (element != null && element.Row < step)
                {
                    element = element.Below;
                }
                while (element != null)
                {
                    count++;
                    element = element.Below;
                }
                _markowitzColumn[i] = Math.Min(count, _maxMarkowitzCount);
            }
        }
Beispiel #3
0
        /// <summary>
        /// MPI-parallel 2-norm
        /// </summary>
        static public double drnm2 <TX>(int N, TX x, int incx, MPI_Comm comm) where TX : IList <double>
        {
            double locRes = 0;

            double[] dx = x as double[];
            if (dx != null)
            {
                // double[] - implementation
                locRes = BLAS.dnrm2(N, dx, incx);
                locRes = locRes * locRes;
            }
            else
            {
                ISparseVector <double> spx = x as ISparseVector <double>;

                if (spx != null)
                {
                    // sparse implementation

                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % incx;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        double xi = entry.Value;
                        locRes += xi * xi;
                    }
                }
                else
                {
                    // default implementation
                    for (int n = 0; n < N; n++)
                    {
                        double xi = x[n * incx];
                        locRes += xi * xi;
                    }
                }
            }



            double globRes = double.NaN;

            unsafe {
                csMPI.Raw.Allreduce((IntPtr)(&locRes), (IntPtr)(&globRes), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, comm);
            }
            return(Math.Sqrt(globRes));
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <summary>
        /// blas dscal: <paramref name="X"/> = <paramref name="X"/>*<paramref name="alpha"/>;
        /// </summary>
        static public void dscal <T>(int N, double alpha, T X, int incx) where T : IList <double>
        {
            ISparseVector <double> spx = X as ISparseVector <double>;

            double[] arx = X as double[];


            if (arx != null)
            {
                // double - array -> use BLAS
                // ++++++++++++++++++++++++++
                BLAS.dscal(N, alpha, arx, incx);
                return;
            }

            if (spx != null)
            {
                // sparce vector -> compute only nonzero entries
                // +++++++++++++++++++++++++++++++++++++++++++++

                int[] idx = new int[spx.NonZeros];
                spx.SparseStruct.Keys.CopyTo(idx, 0);

                foreach (int i in idx)
                {
                    int m = i % incx;
                    if (m != 0)
                    {
                        // entry is skipped by x-increment
                        continue;
                    }

                    spx[i] *= alpha;
                }

                return;
            }


            {
                // reference version
                // +++++++++++++++++

                for (int i = 0; i < N; i += incx)
                {
                    X[i] *= alpha;
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// MPI - parallel scalar product
        /// </summary>
        static public double ddot <TX, TY>(int N, TX x, int incx, TY y, int incy, MPI.Wrappers.MPI_Comm comm)
            where TX : IList <double>
            where TY : IList <double>
        {
            if (incx * x.Count < N)
            {
                throw new ArgumentException("vector too short.", "x");
            }
            if (incy * y.Count < N)
            {
                throw new ArgumentException("vector too short.", "y");
            }

            double locRes = 0;

            double[] dx = x as double[];
            double[] dy = y as double[];
            if (dx != null && dy != null)
            {
                // use dnese BLAS
                locRes = BLAS.ddot(N, dx, incx, dy, incy);
            }
            else
            {
                ISparseVector <double> spx = x as ISparseVector <double>;
                ISparseVector <double> spy = y as ISparseVector <double>;
                IList <double>         _y  = y;
                if (spy != null)
                {
                    if (spx == null || spy.Sparsity < spx.Sparsity)
                    {
                        // y is sparser than x, use y !
                        spx = spy;
                        spy = null;
                        _y  = x;
                        x   = default(TX);
                        y   = default(TY);
                        int buffy = incx;
                        incx = incy;
                        incy = buffy;
                    }
                }

                if (spx != null)
                {
                    // sparse implementation

                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % incx;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        int n = entry.Key / incx;

                        locRes += entry.Value * _y[n * incy];
                    }
                }
                else
                {
                    // default IList<double> - implementation
                    for (int n = 0; n < N; n++)
                    {
                        locRes += x[n * incx] * y[n * incy];
                    }
                }
            }

            double globRes = double.NaN;

            unsafe {
                csMPI.Raw.Allreduce((IntPtr)(&locRes), (IntPtr)(&globRes), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.SUM, comm);
            }
            return(globRes);
        }
Beispiel #7
0
        /// <summary>
        /// blas daxpy: <paramref name="Y"/> = <paramref name="Y"/> + <paramref name="alpha"/>*<paramref name="X"/>;
        /// </summary>
        static public void daxpy <TX, TY>(int N,
                                          double alpha, TX X, int INCX,
                                          TY Y, int INCY)
            where TX : IList <double>
            where TY : IList <double>
        {
            if (object.ReferenceEquals(X, Y))
            {
                // while formally there is no problem that this should work, it seems much more likely
                // that it's a bug.
                throw new ArgumentException("Illegal use: reference-equality of input vectors -- this might be a mis-use instead of intention.");
            }

            {
                // sparse vector branch
                // ++++++++++++++++++++
                ISparseVector <double> spx = X as ISparseVector <double>;
                if (spx != null)
                {
                    foreach (var entry in spx.SparseStruct)
                    {
                        int m = entry.Key % INCX;
                        if (m != 0)
                        {
                            // entry is skipped by x-increment
                            continue;
                        }

                        int n = entry.Key / INCX;

                        double xi = entry.Value;
                        Y[n * INCY] += xi * alpha;
                    }

                    return;
                }
            }


            {
                // both arrays-branch -> use BLAS
                // ++++++++++++++++++++++++++++++


                double[] _XasDouble = X as double[];
                double[] _YasDouble = Y as double[];
                if (_XasDouble != null && _YasDouble != null)
                {
                    BLAS.daxpy(N, alpha, _XasDouble, INCX, _YasDouble, INCY);
                    return;
                }
            }
            {
                // default branch
                // ++++++++++++++

                for (int n = 0; n < N; n++)
                {
                    Y[n * INCY] += X[n * INCX] * alpha;
                }

                return;
            }
        }
Beispiel #8
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++;
                }
            }
        }