TPCCLIB
Loading...
Searching...
No Matches
simdispersion.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpccm.h"
14/*****************************************************************************/
15
16/*****************************************************************************/
28 double *x,
30 double *y,
32 const int n,
34 const double tau1,
36 const double tau2,
39 double *tmp
40) {
41 /* Check input */
42 if(x==NULL || y==NULL || n<2) return 1;
43 if(tau1<0.0 || tau2<0.0) return 2;
44
45 /* Allocate memory if not allocated by user */
46 double *buf;
47 if(tmp!=NULL) buf=tmp; else buf=(double*)malloc(n*sizeof(double));
48 if(buf==NULL) return 3;
49
50 /* First dispersion */
51 if(tau1>0.0) {
52 double k=1.0/tau1;
53 int ret=simC1(x, y, n, k, k, buf);
54 if(ret!=0) {
55 if(tmp==NULL) free(buf);
56 return 100+ret;
57 }
58 for(int i=0; i<n; i++) y[i]=buf[i];
59 }
60
61 /* Second dispersion */
62 if(tau2>0.0) {
63 double k=1.0/tau2;
64 int ret=simC1(x, y, n, k, k, buf);
65 if(ret!=0) {
66 if(tmp==NULL) free(buf);
67 return 200+ret;
68 }
69 for(int i=0; i<n; i++) y[i]=buf[i];
70 }
71
72 if(tmp==NULL) free(buf);
73 return 0;
74}
75/*****************************************************************************/
76
77/*****************************************************************************/
90 double *x,
92 double *y,
94 const int n,
96 const double tau,
99 double *tmp
100) {
101 /* Check input */
102 if(x==NULL || y==NULL || n<2) return 1;
103 if(tau<0.0) return 2;
104 if(x[0]<0.0) return 3;
105
106 /* Allocate memory if not allocated by user */
107 double *buf;
108 if(tmp!=NULL) buf=tmp; else buf=(double*)malloc(n*sizeof(double));
109 if(buf==NULL) return 3;
110
111 /* Integrate measured data */
112 buf[0]=0.5*y[0]*x[0];
113 for(int i=1; i<n; i++) buf[i]=buf[i-1]+0.5*(y[i]+y[i-1])*(x[i]-x[i-1]);
114
115 /* Calculate the integral of dispersion corrected data */
116 for(int i=0; i<n; i++) buf[i]+=tau*y[i];
117
118 /* Calculate dispersion corrected curve from its integral */
119 {
120 int i=0;
121 double dt=x[i];
122 if(dt>0.0) y[i]=2.0*buf[i]/dt; else y[i]=0.0;
123 for(i=1; i<n-1; i++) {
124 dt=x[i+1]-x[i-1]; if(dt>0.0) y[i]=(buf[i+1]-buf[i-1])/dt; else y[i]=y[i-1];
125 }
126 dt=x[i]-x[i-1]; if(dt>0.0) y[i]=(buf[i]-buf[i-1])/dt; else y[i]=y[i-1];
127 }
128
129 if(tmp==NULL) free(buf);
130 return 0;
131}
132/*****************************************************************************/
133
134/*****************************************************************************/
146 double *t,
148 double *c0,
150 const int n,
152 const double k,
154 const int cn,
156 double *cout
157) {
158 /* Check for data */
159 if(n<2 || cn<1) return(1);
160 if(t==NULL || c0==NULL || cout==NULL) return(2);
161 /* Check the rate constant */
162 if(!(k>=0.0)) return(3);
163
164 double c[cn+1], ci[cn+1]; // Compartmental concentrations for current sample
165 double c_last[cn+1], ci_last[cn+1]; // Compartmental concentrations for previous sample
166 for(int j=0; j<=cn; j++) c[j]=c_last[j]=ci[j]=ci_last[j]=0.0;
167
168 /* Calculate curves */
169#if(0)
170 printf("\nTime\tC0\tiC0");
171 for(int j=1; j<=cn; j++) printf("\tC%d", j);
172 printf("\n");
173#endif
174 double t_last=0.0; if(t[0]<t_last) t_last=t[0];
175 double c0_last=0.0, c0i=0.0;
176 for(int i=0; i<n; i++) { // loop through sample times
177 /* delta time / 2 */
178 double dt2=0.5*(t[i]-t_last); if(!(dt2>=0.0)) return(5);
179 /* input integral */
180 c0i+=(c0[i]+c0_last)*dt2;
181 /* k/(1+k*(dt/2)) */
182 double kdt=k/(1.0+dt2*k);
183 /* calculate compartmental concentrations */
184 ci[0]=c0i;
185 if(dt2>0.0) {
186 for(int j=1; j<=cn; j++) {
187 c[j] = kdt * (ci[j-1] - ci_last[j] - dt2*c_last[j]);
188 ci[j] = ci_last[j] + dt2*(c_last[j]+c[j]);
189 }
190 } else { // sample time same as previously, thus concentration do not change either
191 for(int j=0; j<=cn; j++) {
192 c[j]=c_last[j];
193 ci[j]=ci_last[j];
194 }
195 }
196#if(0)
197 printf("%g\t%g\t%g", t[i], c0[i], ci[0]);
198 for(int j=1; j<=cn; j++) printf("\t%g", c[j]);
199 printf("\n");
200#endif
201 cout[i]=c[cn];
202 /* prepare to the next loop */
203 t_last=t[i]; c0_last=c0[i];
204 for(int j=0; j<=cn; j++) {
205 c_last[j]=c[j];
206 ci_last[j]=ci[j];
207 }
208 }
209
210 return(0);
211}
212/*****************************************************************************/
213
214/*****************************************************************************/
229 double *t,
231 double *c0i,
233 const int n,
235 const double k,
237 const int cn,
239 double *cout
240) {
241 /* Check for data */
242 if(n<2 || cn<1) return(1);
243 if(t==NULL || c0i==NULL || cout==NULL) return(2);
244 /* Check the rate constant */
245 if(!(k>=0.0)) return(3);
246
247 double c[cn+1], ci[cn+1]; // Compartmental concentrations for current sample
248 double c_last[cn+1], ci_last[cn+1]; // Compartmental concentrations for previous sample
249 for(int j=0; j<=cn; j++) c[j]=c_last[j]=ci[j]=ci_last[j]=0.0;
250
251 /* Calculate curves */
252#if(0)
253 printf("\nTime\tiC0");
254 for(int j=1; j<=cn; j++) printf("\tC%d", j);
255 printf("\n");
256#endif
257 double t_last=0.0; if(t[0]<t_last) t_last=t[0];
258 for(int i=0; i<n; i++) { // loop through sample times
259 /* delta time / 2 */
260 double dt2=0.5*(t[i]-t_last); if(!(dt2>=0.0)) return(5);
261 /* k/(1+k*(dt/2)) */
262 double kdt=k/(1.0+dt2*k);
263 /* calculate compartmental concentrations */
264 ci[0]=c0i[i];
265 if(dt2>0.0) {
266 for(int j=1; j<=cn; j++) {
267 c[j] = kdt * (ci[j-1] - ci_last[j] - dt2*c_last[j]);
268 ci[j] = ci_last[j] + dt2*(c_last[j]+c[j]);
269 }
270 } else { // sample time same as previously, thus concentration do not change either
271 for(int j=0; j<=cn; j++) {
272 c[j]=c_last[j];
273 ci[j]=ci_last[j];
274 }
275 }
276#if(0)
277 printf("%g\t%g", t[i], ci[0]);
278 for(int j=1; j<=cn; j++) printf("\t%g", c[j]);
279 printf("\n");
280#endif
281 cout[i]=c[cn];
282 /* prepare to the next loop */
283 t_last=t[i];
284 for(int j=0; j<=cn; j++) {
285 c_last[j]=c[j];
286 ci_last[j]=ci[j];
287 }
288 }
289
290 return(0);
291}
292/*****************************************************************************/
293
294/*****************************************************************************/
int simC1(double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
Definition sim1cm.c:93
int simTTM_i(double *t, double *c0i, const int n, const double k, const int cn, double *cout)
int simDispersion(double *x, double *y, const int n, const double tau1, const double tau2, double *tmp)
int simTTM(double *t, double *c0, const int n, const double k, const int cn, double *cout)
int corDispersion(double *x, double *y, const int n, const double tau, double *tmp)
Header file for libtpccm.