-
Notifications
You must be signed in to change notification settings - Fork 0
/
twolayer6.c
120 lines (101 loc) · 2.4 KB
/
twolayer6.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "twolayer6.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#define H 6.6260755e-27
#define K 1.380658e-16
#define TBG 2.73
#define NSIG 2.0
static double *velocity_array;
static double *temperature_array;
static double *twolayer_array;
static double frequency;
static int nchan;
static double vrange[2];
static double jfunc(double t, double nu) {
double to;
if(nu<1.0e-6) return t;
to = H*nu/K;
return to/(exp(to/t)-1.0);
}
void twolayer6_init(int channels, double *varray, double *tarray, double nu, double vmin, double vmax) {
twolayer_array = malloc(channels*sizeof(double));
if(twolayer_array==NULL) {
fprintf(stderr, "twolayer6_init: Out of memory.\n");
exit(1);
}
velocity_array=varray;
temperature_array=tarray;
nchan = channels;
frequency = nu;
vrange[0]=vmin;
vrange[1]=vmax;
}
void twolayer6_free() {
free(twolayer_array);
}
double *twolayer6_getfit() {
return twolayer_array;
}
static double twolayer6_model(double tau, double v_lsr, double v_in, double sigma, double tr, double tf) {
double tauf;
double taur;
int i;
double vr;
double vf;
double resrms;
double resid;
vf = v_lsr+v_in;
vr = v_lsr-v_in;
resrms=0.0;
for(i=0;i<nchan;i++) {
tauf = tau*exp(-pow((velocity_array[i]-vf)/sigma,2.0)/2.0);
taur = tau*exp(-pow((velocity_array[i]-vr)/sigma,2.0)/2.0);
twolayer_array[i]=jfunc(tf,frequency)*(1.0-exp(-tauf))+jfunc(tr,frequency)*(1.0-exp(-taur))*exp(-tauf)-jfunc(TBG,frequency)*(1.0-exp(-taur-tauf));
resid=temperature_array[i]-twolayer_array[i];
if(velocity_array[i]>vrange[0] && velocity_array[i]<vrange[1]) {
resrms+=resid*resid;
}
}
return resrms;
}
/* Solvable 6 parameter two layer model, calculates fit and returns rms
residual.
parameters:
0: tau_0
1: v_lsr
2: v_in
3: sigma
4: Tr
5: Tf
*/
double twolayer6_evaluate(double *params) {
double tau = params[0];
double v_lsr = params[1];
double v_in = params[2];
double sigma = params[3];
double tr = params[4];
double tf = params[5];
double resrms;
if(sigma<0.0) {
return DBL_MAX;
}
if(v_in<0.0) {
return DBL_MAX;
}
if(v_lsr<vrange[0] || v_lsr>vrange[1]) {
return DBL_MAX;
}
if(v_in>NSIG*sigma) {
return DBL_MAX;
}
if(tf<TBG) {
return DBL_MAX;
}
if(tr<tf) {
return DBL_MAX;
}
resrms = twolayer6_model(tau,v_lsr,v_in,sigma,tr,tf);
return resrms;
}