1
/* The Exponential distribution.
2
Copyright (c) 2005--2009 by Ben Klemens. Licensed under the modified GNU GPL v2; see COPYING and COPYING2.
4
\amodel apop_exponential The Exponential distribution.
6
\f$Z(\mu,k) = \sum_k 1/\mu e^{-k/\mu} \f$ <br>
7
\f$ln Z(\mu,k) = \sum_k -\ln(\mu) - k/\mu \f$ <br>
8
\f$dln Z(\mu,k)/d\mu = \sum_k -1/\mu + k/(\mu^2) \f$ <br>
10
Some write the function as:
11
\f$Z(C,k) dx = \ln C C^{-k}. \f$
12
If you prefer this form, just convert your parameter via \f$\mu = {1\over \ln C}\f$
13
(and convert back from the parameters this function gives you via \f$C=\exp(1/\mu)\f$).
16
Ignores the matrix structure of the input data, so send in a 1 x N, an N x 1, or an N x M.
17
\li See also \ref apop_data_rank_compress for means of dealing with one more input data format.
19
\adoc Parameter_format \f$\mu\f$ is in the zeroth element of the vector.
20
\adoc CDF Produces a single number.
21
\adoc settings None. */
23
#include "apop_internal.h"
25
static long double beta_greater_than_x_constraint(apop_data *data, apop_model *v){
26
//constraint is 0 < beta_1
27
return apop_linear_constraint(v->parameters->vector, .margin = 1e-3);
30
static long double exponential_log_likelihood(apop_data *d, apop_model *p){
31
Nullcheck_mpd(d, p, GSL_NAN);
32
Get_vmsizes(d) //tsize
33
double mu = gsl_vector_get(p->parameters->vector, 0);
34
double llikelihood = -((d->matrix ? apop_matrix_sum(d->matrix):0) + (d->vector ? apop_sum(d->vector) : 0))/ mu;
35
llikelihood -= tsize * log(mu);
39
static void exponential_dlog_likelihood(apop_data *d, gsl_vector *gradient, apop_model *p){
40
Nullcheck_mpd(d, p, );
41
Get_vmsizes(d) //tsize
42
double mu = gsl_vector_get(p->parameters->vector, 0);
43
double d_likelihood = (d->matrix ? apop_matrix_sum(d->matrix):0) + (d->vector ? apop_sum(d->vector) : 0);
44
d_likelihood /= gsl_pow_2(mu);
45
d_likelihood -= tsize /mu;
46
gsl_vector_set(gradient,0, d_likelihood);
49
/* \adoc estimated_info Reports <tt>log likelihood</tt>. */
50
static void exponential_estimate(apop_data * data, apop_model *est){
51
apop_score_vtable_add(exponential_dlog_likelihood, apop_exponential);
52
apop_name_add(est->parameters->names, "μ", 'r');
53
Get_vmsizes(data); //msize1, msize2, vsize, tsize
54
double mu = (vsize ? vsize * apop_vector_mean(data->vector):0
55
+ msize1 ? msize1*msize2 * apop_matrix_mean(data->matrix):0)/tsize;
56
gsl_vector_set(est->parameters->vector, 0, mu);
57
apop_data_add_named_elmt(est->info, "log likelihood", exponential_log_likelihood(data, est));
60
static long double expo_cdf(apop_data *d, apop_model *params){
61
Nullcheck_mpd(d, params, GSL_NAN);
62
Get_vmsizes(d) //vsize
63
double val = apop_data_get(d, 0, vsize ? -1 : 0);
64
double lambda = gsl_vector_get(params->parameters->vector, 0);
65
return gsl_cdf_exponential_P(val, lambda);
68
/* \adoc RNG Just a wrapper for \c gsl_ran_exponential. */
69
static int exponential_rng(double *out, gsl_rng* r, apop_model *p){
70
*out = gsl_ran_exponential(r, p->parameters->vector->data[0]);
74
static void exponential_prep(apop_data *data, apop_model *params){
75
apop_score_vtable_add(exponential_dlog_likelihood, apop_exponential);
76
apop_model_clear(data, params);
79
apop_model *apop_exponential = &(apop_model){"Exponential distribution", 1,0,0,.dsize=1,
80
.estimate = exponential_estimate, .log_likelihood = exponential_log_likelihood,
81
.prep = exponential_prep, .constraint = beta_greater_than_x_constraint,
82
.draw = exponential_rng, .cdf = expo_cdf};