/*=============================================================================

    This file is part of FLINT.

    FLINT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    FLINT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with FLINT; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

=============================================================================*/
/******************************************************************************

    Copyright (C) 2010 William Hart
    Copyright (C) 2014 Abhinav Baid

******************************************************************************/

*******************************************************************************

    Memory management

*******************************************************************************

double * _d_vec_init(slong len)

    Returns an initialised vector of \code{double}'s of given length. The
    entries are not zeroed.

void _d_vec_clear(double * vec)

    Frees the space allocated for \code{vec}.

*******************************************************************************

    Randomisation

*******************************************************************************

void _d_vec_randtest(double * f, flint_rand_t state, 
                        slong len, slong minexp, slong maxexp)

    Sets the entries of a vector of the given length to random signed numbers
    with exponents between \code{minexp} and \code{maxexp} or zero.

*******************************************************************************

    Assignment and basic manipulation

*******************************************************************************

void _d_vec_set(double * vec1, const double * vec2, slong len2)

    Makes a copy of \code{(vec2, len2)} into \code{vec1}.

void _d_vec_zero(double * vec, slong len)

    Zeros the entries of \code{(vec, len)}.

*******************************************************************************

    Comparison

*******************************************************************************

int _d_vec_equal(const double * vec1, const double * vec2, slong len)

    Compares two vectors of the given length and returns $1$ if they are 
    equal, otherwise returns $0$.

int _d_vec_is_zero(const double * vec, slong len)

    Returns $1$ if \code{(vec, len)} is zero, and $0$ otherwise.
    
int _d_vec_is_approx_zero(const double * vec, slong len, double eps)

    Returns $1$ if the entries of \code{(vec, len)} are zero to within
    \code{eps}, and $0$ otherwise.

int _d_vec_approx_equal(const double * vec1, const double * vec2, slong len, 
                            double eps)

    Compares two vectors of the given length and returns $1$ if their entries 
    are within \code{eps} of each other, otherwise returns $0$.

*******************************************************************************

    Addition and subtraction

*******************************************************************************

void _d_vec_add(double * res, const double * vec1, 
                    const double * vec2, slong len2)

    Sets \code{(res, len2)} to the sum of \code{(vec1, len2)} 
    and \code{(vec2, len2)}.

void _d_vec_sub(double * res, const double * vec1, 
                    const double * vec2, slong len2)

    Sets \code{(res, len2)} to \code{(vec1, len2)} minus \code{(vec2, len2)}.

*******************************************************************************

    Dot product and norm

*******************************************************************************

double _d_vec_dot(const double * vec1, const double * vec2, 
                                slong len2)

    Returns the dot product of \code{(vec1, len2)} 
    and \code{(vec2, len2)}.
    
double _d_vec_norm(const double * vec, slong len)

    Returns the square of the Euclidean norm of \code{(vec, len)}.
    
double _d_vec_dot_heuristic(const double * vec1, const double * vec2,
                                slong len2, double * err)

    Returns the dot product of \code{(vec1, len2)}
    and \code{(vec2, len2)} by adding up the positive and negative products,
    and doing a single subtraction of the two sums at the end. \code{err} is a
    pointer to a double in which an error bound for the operation will be
    stored.

double _d_vec_dot_thrice(const double * vec1, const double * vec2,
                                slong len2, double * err)

    Returns the dot product of \code{(vec1, len2)}
    and \code{(vec2, len2)} using error-free floating point sums and products
    to compute the dot product with three times (thrice) the working precision.
    \code{err} is a pointer to a double in which an error bound for the
    operation will be stored.

    This implements the algorithm of Ogita-Rump-Oishi. See
    \url{http://www.ti3.tuhh.de/paper/rump/OgRuOi05.pdf}.
