view gsl.c @ 12:24da5bf5b263 default tip

Updated to lastest version of MonetDB which uses NaN for floating point NULL.
author Sjoerd Mullender <sjoerd@acm.org>
date Fri, 25 May 2018 15:19:01 +0200 (2018-05-25)
parents 14b8c4bacde5
children
line wrap: on
line source
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0.  If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright 1997 - July 2008 CWI, August 2008 - 2018 MonetDB B.V.
 */

/*
 *  A. de Rijke, B. Scheers
 * The gsl module
 * The gsl module contains wrappers for functions in
 * gsl.
 */

#include "monetdb_config.h"
#include "mal.h"
#include "mal_exception.h"
#include <gsl/gsl_cdf.h>

#ifdef WIN32
#define gsl_export extern __declspec(dllexport)
#else
#define gsl_export extern
#endif

gsl_export str GSLchisqProb(dbl *retval, dbl *chi2, dbl *datapoints);
gsl_export str GSLbat_chisqProb_cst(bat *retval, bat *chi2, dbl *datapoints);
gsl_export str GSLcst_chisqProb_bat(bat *retval, dbl *chi2, bat *datapoints);
gsl_export str GSLbat_chisqProb_bat(bat *retval, bat *chi2, bat *datapoints);

static str
gsl_chisqprob(dbl *retval, dbl chi2, dbl datapoints)
{
	*retval = dbl_nil;
	if (is_dbl_nil(chi2) || chi2 < 0)
		throw(MAL, "gsl.chi2prob", "Wrong value for chi2");
	if (is_dbl_nil(datapoints) || datapoints < 0)
		throw(MAL, "gsl.chi2prob", "Wrong value for datapoints");
	*retval = gsl_cdf_chisq_Q(chi2, datapoints);
	return MAL_SUCCEED;
}

static str
gsl_bat_chisqprob_cst(bat *retval, bat chi2, dbl datapoints)
{
	BAT *b, *bn;
	BATiter bi;
	BUN p, q;
	dbl r;

	if (is_dbl_nil(datapoints))
		throw(MAL, "GSLbat_chisqprob_cst", "Parameter datapoints should not be nil");
	if (datapoints < 0)
		throw(MAL, "gsl.chi2prob", "Wrong value for datapoints");

	if ((b = BATdescriptor(chi2)) == NULL) {
		throw(MAL, "chisqprob", RUNTIME_OBJECT_MISSING);
	}
	bi = bat_iterator(b);
	bn = COLnew(b->hseqbase, TYPE_dbl, BATcount(b), TRANSIENT);
	if (bn == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "gsl.chisqprob", MAL_MALLOC_FAIL);
	}
	BATloop(b, p, q) {
		dbl d = *(dbl *) BUNtail(bi, p);
		if (is_dbl_nil(d) || d < 0) {
			BBPunfix(b->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", "Wrong value for chi2");
		}
		r = gsl_cdf_chisq_Q(d, datapoints);
		if (BUNappend(bn, &r, FALSE) != GDK_SUCCEED) {
			BBPunfix(b->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", GDK_EXCEPTION);
		}
	}
	*retval = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}

static str
gsl_cst_chisqprob_bat(bat *retval, dbl chi2, bat datapoints)
{
	BAT *b, *bn;
	BATiter bi;
	BUN p, q;
	dbl r;

	if (is_dbl_nil(chi2))
		throw(MAL, "GSLbat_chisqprob_cst", "Parameter chi2 should not be nil");
	if (chi2 < 0)
		throw(MAL, "gsl.chi2prob", "Wrong value for chi2");
	if ((b = BATdescriptor(datapoints)) == NULL) {
		throw(MAL, "chisqprob", RUNTIME_OBJECT_MISSING);
	}
	bi = bat_iterator(b);
	bn = COLnew(b->hseqbase, TYPE_dbl, BATcount(b), TRANSIENT);
	if (bn == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "gsl.chisqprob", MAL_MALLOC_FAIL);
	}
	BATloop(b, p, q) {
		dbl datapoints = *(dbl *) BUNtail(bi, p);

		if (is_dbl_nil(datapoints) || datapoints < 0) {
			BBPunfix(b->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", "Wrong value for datapoints");
		}
		r = gsl_cdf_chisq_Q(chi2, datapoints);
		if (BUNappend(bn, &r, FALSE) != GDK_SUCCEED) {
			BBPunfix(b->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", GDK_EXCEPTION);
		}
	}
	BBPkeepref(*retval = bn->batCacheid);
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}

static str
gsl_bat_chisqprob_bat(bat *retval, bat chi2, bat datapoints)
{
	BAT *b, *c, *bn;
	dbl r, *chi2p, *datapointsp;
	size_t cnt = 0, i;

	if ((b = BATdescriptor(chi2)) == NULL) {
		throw(MAL, "chisqprob", RUNTIME_OBJECT_MISSING);
	}
	if ((c = BATdescriptor(datapoints)) == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "chisqprob", RUNTIME_OBJECT_MISSING);
	}
	bn = COLnew(b->hseqbase, TYPE_dbl, cnt = BATcount(b), TRANSIENT);
	if (bn == NULL) {
		BBPunfix(b->batCacheid);
		BBPunfix(c->batCacheid);
		throw(MAL, "gsl.chisqprob", MAL_MALLOC_FAIL);
	}
	chi2p = (dbl *) Tloc(b, 0);
	datapointsp = (dbl *) Tloc(c, 0);
	for (i = 0; i < cnt; i++) {
		if (is_dbl_nil(chi2p[i]) || chi2p[i] < 0) {
			BBPunfix(b->batCacheid);
			BBPunfix(c->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", "Wrong value for chi2");
		}
		if (is_dbl_nil(datapointsp[i]) || datapointsp[i] < 0) {
			BBPunfix(b->batCacheid);
			BBPunfix(c->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", "Wrong value for datapoints");
		}
		r = gsl_cdf_chisq_Q(chi2p[i], datapointsp[i]);
		if (BUNappend(bn, &r, FALSE) != GDK_SUCCEED) {
			BBPunfix(b->batCacheid);
			BBPunfix(c->batCacheid);
			BBPreclaim(bn);
			throw(MAL, "gsl.chi2prob", GDK_EXCEPTION);
		}
	}
	BBPkeepref(*retval = bn->batCacheid);
	BBPunfix(b->batCacheid);
	BBPunfix(c->batCacheid);
	return MAL_SUCCEED;
}

str
GSLchisqProb(dbl *retval, dbl *chi2, dbl *datapoints)
{
	return gsl_chisqprob(retval, *chi2, *datapoints);
}

str
GSLbat_chisqProb_cst(bat *retval, bat *chi2, dbl *datapoints)
{
	return gsl_bat_chisqprob_cst(retval, *chi2, *datapoints);
}

str
GSLcst_chisqProb_bat(bat *retval, dbl *chi2, bat *datapoints)
{
	return gsl_cst_chisqprob_bat(retval, *chi2, *datapoints);
}

str
GSLbat_chisqProb_bat(bat *retval, bat *chi2, bat *datapoints)
{
	return gsl_bat_chisqprob_bat(retval, *chi2, *datapoints);
}