/*
    Theseus - maximum likelihood superpositioning of macromolecular structures

    Copyright (C) 2004-2015 Douglas L. Theobald

    This program 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.

    This program 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 this program; if not, write to the:

    Free Software Foundation, Inc.,
    59 Temple Place, Suite 330,
    Boston, MA  02111-1307  USA

    -/_|:|_|_\-
*/

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include "VecUtils.h"

void
VecPrint(double *vec, const int size)
{
    int             i;

    for (i = 0; i < size; ++i)
        printf(" %4d [ % 14.8e ]\n", i, vec[i]);

    printf("\n");

    fflush(NULL);
}


void
RotVec(double *newvec, double *vec, double **rotmat)
{
    int             j, k;

    for (j = 0; j < 3; ++j)
    {
        newvec[j] = 0.0;
        for (k = 0; k < 3; ++k)
            newvec[j] += (vec[k] * rotmat[k][j]);
    }
}


void
InvRotVec(double *newvec, double *vec, double **rotmat)
{
    int             j, k;

    for (j = 0; j < 3; ++j)
    {
        newvec[j] = 0.0;
        for (k = 0; k < 3; ++k)
            newvec[j] += (vec[k] * rotmat[j][k]);
    }
}


void
RotVecAdd(double *newvec, double *vec, double **rotmat)
{
    int             j, k;

    for (j = 0; j < 3; ++j)
        for (k = 0; k < 3; ++k)
            newvec[j] += (vec[k] * rotmat[k][j]);
}


void
InvRotVecAdd(double *newvec, double *vec, double **rotmat)
{
    int             j, k;

    for (j = 0; j < 3; ++j)
        for (k = 0; k < 3; ++k)
            newvec[j] += (vec[k] * rotmat[j][k]);
}


int
VecEq(const double *vec1, const double *vec2, const int len, const double tol)
{
    int             i;
    double          sum, diff;

    sum = 0.0;
    for (i = 0; i < len; ++i)
    {
        diff = (vec1[i] - vec2[i]);
        if (vec1[i] + vec2[i] == 0.0)
            sum += 0.0;
        else
            sum += diff * diff / (vec1[i] + vec2[i]);
    }

    /* printf("\n %e", sqrt(0.5 * sum/len)); */

    if (sqrt(0.5 * sum / len) > tol)
        return(0);
    else
        return(1);
}


void
RevVecIp(double *vec, const int len)
{
    int             i;
    double          tmp;

    for (i = 0; i < (len - 1) / 2; ++i)
    {
        tmp = vec[i];
        vec[i] = vec[len-i-1];
        vec[len-i-1] = tmp;
    }
}


double
VecSmallest(double *vec, const int len)
{
    int             i;
    double          smallest = DBL_MAX;

    for (i = 0; i < len; ++i)
        if (smallest > vec[i])
            smallest = vec[i];

    return(smallest);
}


double
VecBiggest(double *vec, const int len)
{
    int             i;
    double          biggest = -DBL_MAX;

    for (i = 0; i < len; ++i)
        if (biggest < vec[i])
            biggest = vec[i];

    return(biggest);
}

