11#include <camp/time_derivative.h>
16 unsigned int num_spec) {
17 if (num_spec <= 0)
return 0;
19 time_deriv->production_rates =
20 (
long double *)malloc(num_spec *
sizeof(
long double));
21 if (time_deriv->production_rates == NULL)
return 0;
23 time_deriv->loss_rates =
24 (
long double *)malloc(num_spec *
sizeof(
long double));
25 if (time_deriv->loss_rates == NULL) {
26 free(time_deriv->production_rates);
30 time_deriv->num_spec = num_spec;
33 time_deriv->last_max_loss_precision = 0.0;
40 for (
unsigned int i_spec = 0; i_spec < time_deriv.num_spec; ++i_spec) {
41 time_deriv.production_rates[i_spec] = 0.0;
42 time_deriv.loss_rates[i_spec] = 0.0;
47 double *deriv_est,
unsigned int output_precision) {
48 long double *r_p = time_deriv.production_rates;
49 long double *r_l = time_deriv.loss_rates;
52 time_deriv.last_max_loss_precision = 1.0;
55 for (
unsigned int i_spec = 0; i_spec < time_deriv.num_spec; ++i_spec) {
56 double prec_loss = 1.0;
57 if (*r_p + *r_l != 0.0) {
59 long double scale_fact;
62 (1.0 / (*r_p + *r_l) + MAX_PRECISION_LOSS / fabsl(*r_p - *r_l));
64 scale_fact * (*r_p - *r_l) + (1.0 - scale_fact) * (*deriv_est);
66 *dest_array = *r_p - *r_l;
69 if (*r_p != 0.0 && *r_l != 0.0) {
70 prec_loss = *r_p > *r_l ? 1.0 - *r_l / *r_p : 1.0 - *r_p / *r_l;
71 if (prec_loss < time_deriv.last_max_loss_precision)
72 time_deriv.last_max_loss_precision = prec_loss;
81 if (deriv_est) ++deriv_est;
83 if (output_precision == 1) {
84 printf(
"\nspec %d prec_loss %le", i_spec, -log(prec_loss) / log(2.0));
91 long double rate_contribution) {
92 if (rate_contribution > 0.0) {
93 time_deriv.production_rates[spec_id] += rate_contribution;
95 time_deriv.loss_rates[spec_id] += -rate_contribution;
100double time_derivative_max_loss_precision(TimeDerivative time_deriv) {
101 return -log(time_deriv.last_max_loss_precision) / log(2.0);
106 free(time_deriv.production_rates);
107 free(time_deriv.loss_rates);
void time_derivative_free(TimeDerivative time_deriv)
int time_derivative_initialize(TimeDerivative *time_deriv, unsigned int num_spec)
void time_derivative_reset(TimeDerivative time_deriv)
void time_derivative_output(TimeDerivative time_deriv, double *dest_array, double *deriv_est, unsigned int output_precision)
void time_derivative_add_value(TimeDerivative time_deriv, unsigned int spec_id, long double rate_contribution)