/*!\file PowerVariogram.c
 * \brief: implementation of the PowerVariogram object
 */

#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include <stdio.h>
#include <string.h>
#include "../objects/objects.h"
#include "../../EnumDefinitions/EnumDefinitions.h"
#include "../../shared/shared.h"
#include "../../include/include.h"

/*PowerVariogram constructors and destructor*/
/*FUNCTION PowerVariogram::PowerVariogram(){{{*/
PowerVariogram::PowerVariogram(){
	this->nugget = 0.2;
	this->slope  = 1.;
	this->power  = 1.;
	return;
}
/*}}}*/
/*FUNCTION PowerVariogram::PowerVariogram(Options* options){{{*/
PowerVariogram::PowerVariogram(Options* options){

	/*Defaults*/
	this->nugget = 0.2;
	this->slope  = 1.;
	this->power  = 1.;

	/*Overwrite from options*/
	if(options->GetOption("nugget")) options->Get(&this->nugget,"nugget");
	if(options->GetOption("slope"))  options->Get(&this->slope,"slope");
	if(options->GetOption("power"))  options->Get(&this->power,"power");

	/*Checks*/
	if(power<=0 || power>=2) _error_("power must be betwwen 0 and 2 (0 < power < 2)");
	if(slope<=0) _error_("slope must be positive");
}
/*}}}*/
/*FUNCTION PowerVariogram::~PowerVariogram(){{{*/
PowerVariogram::~PowerVariogram(){
	return;
}
/*}}}*/

/*Object virtual functions definitions:*/
/*FUNCTION PowerVariogram::Echo {{{*/
void PowerVariogram::Echo(void){
	_printLine_("PowerVariogram");
	_printLine_("   nugget: " << this->nugget);
	_printLine_("   slope : " << this->slope);
	_printLine_("   power : " << this->power);
}
/*}}}*/

/*Variogram function*/
/*FUNCTION PowerVariogram::Covariance{{{*/
double PowerVariogram::Covariance(double deltax,double deltay){
	/*The covariance can be deduced from the variogram from the following
	 * relationship:
	 *    2 gamma = C(x,x) + C(y,y) -2 C(x,y)
	 * so
	 *    C(h) = sill - gamma                                            */
	double h,cova;

	/*Calculate length square*/
	h=sqrt(pow(deltax,2.)+pow(deltay,2.));

	/*return covariance*/
	cova = 9999. - this->slope*pow(h,this->power);

	return cova;
}
/*}}}*/
/*FUNCTION PowerVariogram::SemiVariogram{{{*/
double PowerVariogram::SemiVariogram(double deltax,double deltay){
	/*http://en.wikipedia.org/wiki/Variogram*/
	double h,gamma;

	/*Calculate length square*/
	h=sqrt(pow(deltax,2.)+pow(deltay,2.));

	/*return semi-variogram*/
	gamma = this->nugget + this->slope*pow(h,this->power);

	//if(h>1000) _printLine_("gamma = " << gamma << " h=" << h);
	return gamma;
}
/*}}}*/
