
/*****************************************************************************
*
* MODULE:       Grass PDE Numerical Library
* AUTHOR(S):    Soeren Gebbert, Berlin (GER) Dec 2006
* 		soerengebbert <at> gmx <dot> de
*               
* PURPOSE:      Unit tests of math tools 
*
* COPYRIGHT:    (C) 2000 by the GRASS Development Team
*
*               This program is free software under the GNU General Public
*               License (>=v2). Read the file COPYING that comes with GRASS
*               for details.
*
*****************************************************************************/

#include <grass/gis.h>
#include <grass/glocale.h>
#include <grass/N_pde.h>
#include "test_gpde_lib.h"


/* prototypes */
static int test_mean_calc(void);

/* *************************************************************** */
/* Perfrome the math tool tests ********************************** */
/* *************************************************************** */
int unit_test_tools(void)
{
    int sum = 0;

    G_message(_("\n++ Running math tool unit tests ++"));

    sum += test_mean_calc();

    if (sum > 0)
	G_warning(_("\n-- math tool unit tests failure --"));
    else
	G_message(_("\n-- math tool unit tests finished successfully --"));

    return sum;
}

/* *************************************************************** */
/* Test the mean calculation functions *************************** */
/* *************************************************************** */
int test_mean_calc(void)
{
    double a, b, mean_n, mean, vector, distance, D, weight;
    double v[2];
    double array[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    int i;
    int sum = 0;
    char buff1[10];

    for (i = 0; i < 10; i++)
	array[i] += i;

    a = 1.0 / 3.0;
    b = 3.0;
    v[0] = a;
    v[1] = b;

    /*arith mean */
    mean = N_calc_arith_mean(a, b);
    G_message("N_calc_arith_mean: calc a %g and b %g = %12.18lf", a, b, mean);
    mean_n = N_calc_arith_mean_n(v, 2);
    G_message("N_calc_arith_mean_n: calc a %g and b %g = %12.18lf", v[0],
	      v[1], mean_n);
    if (mean != mean_n)
	sum++;

    /*geom mean */
    mean = N_calc_geom_mean(a, b);
    G_message("N_calc_geom_mean: calc a %g and b %g = %12.18lf", a, b, mean);
    mean_n = N_calc_geom_mean_n(v, 2);
    G_message("N_calc_geom_mean_n: calc a %g and b %g = %12.18lf", v[0], v[1],
	      mean_n);
    if (mean != mean_n)
	sum++;

    /*harmonic mean */
    mean = N_calc_harmonic_mean(a, b);
    G_message("N_calc_harmonic_mean: calc a %g and b %g = %12.18lf", a, b,
	      mean);
    mean_n = N_calc_harmonic_mean_n(v, 2);
    G_message("N_calc_harmonic_mean_n: calc a %g and b %g = %12.18lf", v[0],
	      v[1], mean_n);
    if (mean != mean_n)
	sum++;
    /*null test */
    a = 2;
    b = 0;
    v[0] = a;
    v[1] = b;
    mean = N_calc_harmonic_mean(a, b);
    G_message("N_calc_harmonic_mean: calc a %g and b %g = %12.18lf", a, b,
	      mean);
    mean_n = N_calc_harmonic_mean_n(v, 2);
    G_message("N_calc_harmonic_mean_n: calc a %g and b %g = %12.18lf", v[0],
	      v[1], mean_n);
    if (mean != mean_n)
	sum++;

    /*quadratic mean */
    a = 1.0 / 3.0;
    b = 3.0;
    v[0] = a;
    v[1] = b;

    mean = N_calc_quad_mean(a, b);
    G_message("N_calc_quad_mean: calc a %g and b %g = %12.18lf", a, b, mean);
    mean_n = N_calc_quad_mean_n(v, 2);
    G_message("N_calc_quad_mean_n: calc a %g and b %g = %12.18lf", v[0], v[1],
	      mean_n);
    if (mean != mean_n)
	sum++;

    /*Test the full upwind stabailization */
    vector = -0.000001;
    distance = 20;
    D = 0.000001;

    weight = N_full_upwinding(vector, distance, D);
    G_message("N_full_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);

    if (weight != 0) {
	G_warning("Error detected in N_full_upwinding");
	sum++;
    }

    vector = 0.000001;

    weight = N_full_upwinding(vector, distance, D);
    G_message("N_full_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);
    if (weight != 1) {
	G_warning("Error detected in N_full_upwinding");
	sum++;
    }

    D = 0.0;

    weight = N_full_upwinding(vector, distance, D);
    G_message("N_full_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);
    if (weight != 0.5) {
	G_warning("Error detected in N_full_upwinding");
	sum++;
    }


    /*Test the exponential upwind stabailization */
    vector = -0.000001;
    distance = 20;
    D = 0.000001;

    weight = N_exp_upwinding(vector, distance, D);
    G_message("N_exp_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);
    sprintf(buff1, "%1.2lf", weight);
    sscanf(buff1, "%lf", &weight);

    if (weight != 0.05) {
	G_warning("Error detected in N_exp_upwinding");
	sum++;
    }

    vector = 0.000001;

    weight = N_exp_upwinding(vector, distance, D);
    G_message("N_exp_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);
    sprintf(buff1, "%1.2lf", weight);
    sscanf(buff1, "%lf", &weight);

    if (weight != 0.95) {
	G_warning("Error detected in N_exp_upwinding");
	sum++;
    }

    D = 0.0;

    weight = N_exp_upwinding(vector, distance, D);
    G_message("N_exp_upwinding: vector %g distance %g D %g weight %g\n",
	      vector, distance, D, weight);
    if (weight != 0.5) {
	G_warning("Error detected in N_exp_upwinding");
	sum++;
    }

    return sum;
}
