annotate rDiff/src/locfit/Source/libmut.c @ 0:0f80a5141704

version 0.3 uploaded
author vipints
date Thu, 14 Feb 2013 23:38:36 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
4
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
5 #include "mex.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
6 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
7 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
8 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
9 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
10 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
11
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
12 /* stirlerr(n) = log(n!) - log( sqrt(2*pi*n)*(n/e)^n ) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
13
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
14 #define S0 0.083333333333333333333 /* 1/12 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
15 #define S1 0.00277777777777777777778 /* 1/360 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
16 #define S2 0.00079365079365079365079365 /* 1/1260 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
17 #define S3 0.000595238095238095238095238 /* 1/1680 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
18 #define S4 0.0008417508417508417508417508 /* 1/1188 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
19
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
20 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
21 error for 0, 0.5, 1.0, 1.5, ..., 14.5, 15.0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
22 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
23 static double sferr_halves[31] = {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
24 0.0, /* n=0 - wrong, place holder only */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
25 0.1534264097200273452913848, /* 0.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
26 0.0810614667953272582196702, /* 1.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
27 0.0548141210519176538961390, /* 1.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
28 0.0413406959554092940938221, /* 2.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
29 0.03316287351993628748511048, /* 2.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
30 0.02767792568499833914878929, /* 3.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
31 0.02374616365629749597132920, /* 3.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
32 0.02079067210376509311152277, /* 4.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
33 0.01848845053267318523077934, /* 4.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
34 0.01664469118982119216319487, /* 5.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
35 0.01513497322191737887351255, /* 5.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
36 0.01387612882307074799874573, /* 6.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
37 0.01281046524292022692424986, /* 6.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
38 0.01189670994589177009505572, /* 7.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
39 0.01110455975820691732662991, /* 7.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
40 0.010411265261972096497478567, /* 8.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
41 0.009799416126158803298389475, /* 8.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
42 0.009255462182712732917728637, /* 9.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
43 0.008768700134139385462952823, /* 9.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
44 0.008330563433362871256469318, /* 10.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
45 0.007934114564314020547248100, /* 10.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
46 0.007573675487951840794972024, /* 11.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
47 0.007244554301320383179543912, /* 11.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
48 0.006942840107209529865664152, /* 12.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
49 0.006665247032707682442354394, /* 12.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
50 0.006408994188004207068439631, /* 13.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
51 0.006171712263039457647532867, /* 13.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
52 0.005951370112758847735624416, /* 14.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
53 0.005746216513010115682023589, /* 14.5 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
54 0.005554733551962801371038690 /* 15.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
55 };
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
56
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
57 double stirlerr(n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
58 double n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
59 { double nn;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
60
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
61 if (n<15.0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
62 { nn = 2.0*n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
63 if (nn==(int)nn) return(sferr_halves[(int)nn]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
64 return(mut_lgamma(n+1.0) - (n+0.5)*log((double)n)+n - HF_LG_PIx2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
65 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
66
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
67 nn = (double)n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
68 nn = nn*nn;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
69 if (n>500) return((S0-S1/nn)/n);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
70 if (n>80) return((S0-(S1-S2/nn)/nn)/n);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
71 if (n>35) return((S0-(S1-(S2-S3/nn)/nn)/nn)/n);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
72 return((S0-(S1-(S2-(S3-S4/nn)/nn)/nn)/nn)/n);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
73 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
74
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
75 double bd0(x,np)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
76 double x, np;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
77 { double ej, s, s1, v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
78 int j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
79 if (fabs(x-np)<0.1*(x+np))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
80 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
81 s = (x-np)*(x-np)/(x+np);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
82 v = (x-np)/(x+np);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
83 ej = 2*x*v; v = v*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
84 for (j=1; ;++j)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
85 { ej *= v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
86 s1 = s+ej/((j<<1)+1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
87 if (s1==s) return(s1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
88 s = s1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
89 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
90 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
91 return(x*log(x/np)+np-x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
92 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
93
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
94 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
95 Raw binomial probability calculation.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
96 (1) This has both p and q arguments, when one may be represented
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
97 more accurately than the other (in particular, in df()).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
98 (2) This should NOT check that inputs x and n are integers. This
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
99 should be done in the calling function, where necessary.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
100 (3) Does not check for 0<=p<=1 and 0<=q<=1 or NaN's. Do this in
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
101 the calling function.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
102 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
103 double dbinom_raw(x,n,p,q,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
104 double x, n, p, q;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
105 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
106 { double f, lc;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
107
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
108 if (p==0.0) return((x==0) ? D_1 : D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
109 if (q==0.0) return((x==n) ? D_1 : D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
110
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
111 if (x==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
112 { lc = (p<0.1) ? -bd0(n,n*q) - n*p : n*log(q);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
113 return( DEXP(lc) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
114 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
115
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
116 if (x==n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
117 { lc = (q<0.1) ? -bd0(n,n*p) - n*q : n*log(p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
118 return( DEXP(lc) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
119 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
120
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
121 if ((x<0) | (x>n)) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
122
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
123 lc = stirlerr(n) - stirlerr(x) - stirlerr(n-x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
124 - bd0(x,n*p) - bd0(n-x,n*q);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
125 f = (PIx2*x*(n-x))/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
126
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
127 return( FEXP(f,lc) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
128 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
129
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
130 double dbinom(x,n,p,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
131 int x, n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
132 double p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
133 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
134 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
135 if ((p<0) | (p>1) | (n<0)) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
136 if (x<0) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
137
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
138 return( dbinom_raw((double)x,(double)n,p,1-p,give_log) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
139 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
140
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
141 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
142 Poisson probability lb^x exp(-lb) / x!.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
143 I don't check that x is an integer, since other functions
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
144 that call dpois_raw() (i.e. dgamma) may use a fractional
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
145 x argument.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
146 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
147 double dpois_raw(x,lambda,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
148 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
149 double x, lambda;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
150 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
151 if (lambda==0) return( (x==0) ? D_1 : D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
152 if (x==0) return( DEXP(-lambda) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
153 if (x<0) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
154
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
155 return(FEXP( PIx2*x, -stirlerr(x)-bd0(x,lambda) ));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
156 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
157
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
158 double dpois(x,lambda,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
159 int x, give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
160 double lambda;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
161 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
162 if (lambda<0) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
163 if (x<0) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
164
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
165 return( dpois_raw((double)x,lambda,give_log) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
166 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
167
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
168 double dbeta(x,a,b,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
169 double x, a, b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
170 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
171 { double f, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
172
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
173 if ((a<=0) | (b<=0)) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
174 if ((x<=0) | (x>=1)) return(D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
175
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
176 if (a<1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
177 { if (b<1) /* a<1, b<1 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
178 { f = a*b/((a+b)*x*(1-x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
179 p = dbinom_raw(a,a+b,x,1-x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
180 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
181 else /* a<1, b>=1 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
182 { f = a/x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
183 p = dbinom_raw(a,a+b-1,x,1-x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
184 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
185 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
186 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
187 { if (b<1) /* a>=1, b<1 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
188 { f = b/(1-x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
189 p = dbinom_raw(a-1,a+b-1,x,1-x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
190 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
191 else /* a>=1, b>=1 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
192 { f = a+b-1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
193 p = dbinom_raw(a-1,(a-1)+(b-1),x,1-x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
194 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
195 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
196
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
197 return( (give_log) ? p + log(f) : p*f );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
198 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
199
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
200 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
201 * To evaluate the F density, write it as a Binomial probability
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
202 * with p = x*m/(n+x*m). For m>=2, use the simplest conversion.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
203 * For m<2, (m-2)/2<0 so the conversion will not work, and we must use
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
204 * a second conversion. Note the division by p; this seems unavoidable
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
205 * for m < 2, since the F density has a singularity as x (or p) -> 0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
206 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
207 double df(x,m,n,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
208 double x, m, n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
209 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
210 { double p, q, f, dens;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
211
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
212 if ((m<=0) | (n<=0)) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
213 if (x <= 0.0) return(D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
214
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
215 f = 1.0/(n+x*m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
216 q = n*f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
217 p = x*m*f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
218
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
219 if (m>=2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
220 { f = m*q/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
221 dens = dbinom_raw((m-2)/2.0, (m+n-2)/2.0, p, q, give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
222 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
223 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
224 { f = m*m*q / (2*p*(m+n));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
225 dens = dbinom_raw(m/2.0, (m+n)/2.0, p, q, give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
226 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
227
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
228 return((give_log) ? log(f)+dens : f*dens);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
229 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
230
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
231 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
232 * Gamma density,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
233 * lb^r x^{r-1} exp(-lb*x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
234 * p(x;r,lb) = -----------------------
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
235 * (r-1)!
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
236 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
237 * If USE_SCALE is defined below, the lb argument will be interpreted
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
238 * as a scale parameter (i.e. replace lb by 1/lb above). Otherwise,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
239 * it is interpreted as a rate parameter, as above.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
240 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
241
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
242 /* #define USE_SCALE */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
243
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
244 double dgamma(x,r,lambda,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
245 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
246 double x, r, lambda;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
247 { double pr;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
248
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
249 if ((r<=0) | (lambda<0)) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
250 if (x<=0.0) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
251
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
252 #ifdef USE_SCALE
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
253 lambda = 1.0/lambda;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
254 #endif
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
255
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
256 if (r<1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
257 { pr = dpois_raw(r,lambda*x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
258 return( (give_log) ? pr + log(r/x) : pr*r/x );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
259 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
260
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
261 pr = dpois_raw(r-1.0,lambda*x,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
262 return( (give_log) ? pr + log(lambda) : lambda*pr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
263 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
264
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
265 double dchisq(x, df, give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
266 double x, df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
267 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
268 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
269 return(dgamma(x, df/2.0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
270 0.5
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
271 ,give_log));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
272 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
273 #ifdef USE_SCALE
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
274 2.0
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
275 #else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
276 0.5
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
277 #endif
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
278 ,give_log));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
279 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
280 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
281
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
282 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
283 * Given a sequence of r successes and b failures, we sample n (\le b+r)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
284 * items without replacement. The hypergeometric probability is the
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
285 * probability of x successes:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
286 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
287 * dbinom(x,r,p) * dbinom(n-x,b,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
288 * p(x;r,b,n) = ---------------------------------
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
289 * dbinom(n,r+b,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
290 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
291 * for any p. For numerical stability, we take p=n/(r+b); with this choice,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
292 * the denominator is not exponentially small.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
293 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
294 double dhyper(x,r,b,n,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
295 int x, r, b, n, give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
296 { double p, q, p1, p2, p3;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
297
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
298 if ((r<0) | (b<0) | (n<0) | (n>r+b))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
299 return( INVALID_PARAMS );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
300
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
301 if (x<0) return(D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
302
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
303 if (n==0) return((x==0) ? D_1 : D_0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
304
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
305 p = ((double)n)/((double)(r+b));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
306 q = ((double)(r+b-n))/((double)(r+b));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
307
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
308 p1 = dbinom_raw((double)x,(double)r,p,q,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
309 p2 = dbinom_raw((double)(n-x),(double)b,p,q,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
310 p3 = dbinom_raw((double)n,(double)(r+b),p,q,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
311
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
312 return( (give_log) ? p1 + p2 - p3 : p1*p2/p3 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
313 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
314
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
315 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
316 probability of x failures before the nth success.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
317 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
318 double dnbinom(x,n,p,give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
319 double n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
320 int x, give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
321 { double prob, f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
322
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
323 if ((p<0) | (p>1) | (n<=0)) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
324
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
325 if (x<0) return( D_0 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
326
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
327 prob = dbinom_raw(n,x+n,p,1-p,give_log);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
328 f = n/(n+x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
329
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
330 return((give_log) ? log(f) + prob : f*prob);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
331 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
332
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
333 double dt(x, df, give_log)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
334 double x, df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
335 int give_log;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
336 { double t, u, f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
337
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
338 if (df<=0.0) return(INVALID_PARAMS);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
339
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
340 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
341 exp(t) = Gamma((df+1)/2) /{ sqrt(df/2) * Gamma(df/2) }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
342 = sqrt(df/2) / ((df+1)/2) * Gamma((df+3)/2) / Gamma((df+2)/2).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
343 This form leads to a computation that should be stable for all
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
344 values of df, including df -> 0 and df -> infinity.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
345 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
346 t = -bd0(df/2.0,(df+1)/2.0) + stirlerr((df+1)/2.0) - stirlerr(df/2.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
347
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
348 if (x*x>df)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
349 u = log( 1+ x*x/df ) * df/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
350 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
351 u = -bd0(df/2.0,(df+x*x)/2.0) + x*x/2.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
352
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
353 f = PIx2*(1+x*x/df);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
354
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
355 return( FEXP(f,t-u) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
356 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
357 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
358 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
359 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
360 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
361 * Provides mut_erf() and mut_erfc() functions. Also mut_pnorm().
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
362 * Had too many problems with erf()'s built into math libraries
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
363 * (when they existed). Hence the need to write my own...
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
364 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
365 * Algorithm from Walter Kr\"{a}mer, Frithjof Blomquist.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
366 * "Algorithms with Guaranteed Error Bounds for the Error Function
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
367 * and Complementary Error Function"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
368 * Preprint 2000/2, Bergische Universt\"{a}t GH Wuppertal
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
369 * http://www.math.uni-wuppertal.de/wrswt/preprints/prep_00_2.pdf
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
370 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
371 * Coded by Catherine Loader, September 2006.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
372 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
373
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
374 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
375
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
376 double erf1(double x) /* erf; 0 < x < 0.65) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
377 { double p[5] = {1.12837916709551256e0, /* 2/sqrt(pi) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
378 1.35894887627277916e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
379 4.03259488531795274e-2,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
380 1.20339380863079457e-3,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
381 6.49254556481904354e-5};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
382 double q[5] = {1.00000000000000000e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
383 4.53767041780002545e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
384 8.69936222615385890e-2,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
385 8.49717371168693357e-3,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
386 3.64915280629351082e-4};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
387 double x2, p4, q4;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
388 x2 = x*x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
389 p4 = p[0] + p[1]*x2 + p[2]*x2*x2 + p[3]*x2*x2*x2 + p[4]*x2*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
390 q4 = q[0] + q[1]*x2 + q[2]*x2*x2 + q[3]*x2*x2*x2 + q[4]*x2*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
391 return(x*p4/q4);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
392 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
393
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
394 double erf2(double x) /* erfc; 0.65 <= x < 2.2 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
395 { double p[6] = {9.99999992049799098e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
396 1.33154163936765307e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
397 8.78115804155881782e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
398 3.31899559578213215e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
399 7.14193832506776067e-2,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
400 7.06940843763253131e-3};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
401 double q[7] = {1.00000000000000000e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
402 2.45992070144245533e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
403 2.65383972869775752e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
404 1.61876655543871376e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
405 5.94651311286481502e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
406 1.26579413030177940e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
407 1.25304936549413393e-2};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
408 double x2, p5, q6;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
409 x2 = x*x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
410 p5 = p[0] + p[1]*x + p[2]*x2 + p[3]*x2*x + p[4]*x2*x2 + p[5]*x2*x2*x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
411 q6 = q[0] + q[1]*x + q[2]*x2 + q[3]*x2*x + q[4]*x2*x2 + q[5]*x2*x2*x + q[6]*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
412 return( exp(-x2)*p5/q6 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
413 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
414
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
415 double erf3(double x) /* erfc; 2.2 < x <= 6 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
416 { double p[6] = {9.99921140009714409e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
417 1.62356584489366647e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
418 1.26739901455873222e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
419 5.81528574177741135e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
420 1.57289620742838702e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
421 2.25716982919217555e-2};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
422 double q[7] = {1.00000000000000000e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
423 2.75143870676376208e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
424 3.37367334657284535e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
425 2.38574194785344389e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
426 1.05074004614827206e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
427 2.78788439273628983e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
428 4.00072964526861362e-2};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
429 double x2, p5, q6;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
430 x2 = x*x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
431 p5 = p[0] + p[1]*x + p[2]*x2 + p[3]*x2*x + p[4]*x2*x2 + p[5]*x2*x2*x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
432 q6 = q[0] + q[1]*x + q[2]*x2 + q[3]*x2*x + q[4]*x2*x2 + q[5]*x2*x2*x + q[6]*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
433 return( exp(-x2)*p5/q6 );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
434 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
435
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
436 double erf4(double x) /* erfc; x > 6.0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
437 { double p[5] = {5.64189583547756078e-1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
438 8.80253746105525775e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
439 3.84683103716117320e1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
440 4.77209965874436377e1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
441 8.08040729052301677e0};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
442 double q[5] = {1.00000000000000000e0,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
443 1.61020914205869003e1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
444 7.54843505665954743e1,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
445 1.12123870801026015e2,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
446 3.73997570145040850e1};
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
447 double x2, p4, q4;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
448 if (x>26.5432) return(0.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
449 x2 = 1.0/(x*x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
450 p4 = p[0] + p[1]*x2 + p[2]*x2*x2 + p[3]*x2*x2*x2 + p[4]*x2*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
451 q4 = q[0] + q[1]*x2 + q[2]*x2*x2 + q[3]*x2*x2*x2 + q[4]*x2*x2*x2*x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
452 return(exp(-x*x)*p4/(x*q4));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
453 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
454
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
455 double mut_erfc(double x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
456 { if (x<0.0) return(2.0-mut_erfc(-x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
457 if (x==0.0) return(1.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
458 if (x<0.65) return(1.0-erf1(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
459 if (x<2.2) return(erf2(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
460 if (x<6.0) return(erf3(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
461 return(erf4(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
462 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
463
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
464 double mut_erf(double x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
465 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
466 if (x<0.0) return(-mut_erf(-x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
467 if (x==0.0) return(0.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
468 if (x<0.65) return(erf1(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
469 if (x<2.2) return(1.0-erf2(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
470 if (x<6.0) return(1.0-erf3(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
471 return(1.0-erf4(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
472 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
473
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
474 double mut_pnorm(double x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
475 { if (x<0.0) return(mut_erfc(-x/SQRT2)/2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
476 return((1.0+mut_erf(x/SQRT2))/2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
477 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
478 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
479 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
480 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
481 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
482
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
483 static double lookup_gamma[21] = {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
484 0.0, /* place filler */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
485 0.572364942924699971, /* log(G(0.5)) = log(sqrt(pi)) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
486 0.000000000000000000, /* log(G(1)) = log(0!) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
487 -0.120782237635245301, /* log(G(3/2)) = log(sqrt(pi)/2)) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
488 0.000000000000000000, /* log(G(2)) = log(1!) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
489 0.284682870472919181, /* log(G(5/2)) = log(3sqrt(pi)/4) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
490 0.693147180559945286, /* log(G(3)) = log(2!) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
491 1.200973602347074287, /* etc */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
492 1.791759469228054957,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
493 2.453736570842442344,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
494 3.178053830347945752,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
495 3.957813967618716511,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
496 4.787491742782045812,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
497 5.662562059857141783,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
498 6.579251212010101213,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
499 7.534364236758732680,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
500 8.525161361065414667,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
501 9.549267257300996903,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
502 10.604602902745250859,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
503 11.689333420797268559,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
504 12.801827480081469091 };
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
505
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
506 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
507 * coefs are B(2n)/(2n(2n-1)) 2n(2n-1) =
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
508 * 2n B(2n) 2n(2n-1) coef
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
509 * 2 1/6 2 1/12
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
510 * 4 -1/30 12 -1/360
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
511 * 6 1/42 30 1/1260
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
512 * 8 -1/30 56 -1/1680
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
513 * 10 5/66 90 1/1188
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
514 * 12 -691/2730 132 691/360360
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
515 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
516
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
517 double mut_lgamma(double x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
518 { double f, z, x2, se;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
519 int ix;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
520
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
521 /* lookup table for common values.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
522 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
523 ix = (int)(2*x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
524 if (((ix>=1) & (ix<=20)) && (ix==2*x)) return(lookup_gamma[ix]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
525
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
526 f = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
527 while (x <= 15)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
528 { f *= x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
529 x += 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
530 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
531
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
532 x2 = 1.0/(x*x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
533 z = (x-0.5)*log(x) - x + HF_LG_PIx2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
534 se = (13860 - x2*(462 - x2*(132 - x2*(99 - 140*x2))))/(166320*x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
535
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
536 return(z + se - log(f));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
537 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
538
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
539 double mut_lgammai(int i) /* log(Gamma(i/2)) for integer i */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
540 { if (i>20) return(mut_lgamma(i/2.0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
541 return(lookup_gamma[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
542 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
543 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
544 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
545 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
546 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
547 * A is a n*p matrix, find the cholesky decomposition
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
548 * of the first p rows. In most applications, will want n=p.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
549 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
550 * chol_dec(A,n,p) computes the decomoposition R'R=A.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
551 * (note that R is stored in the input A).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
552 * chol_solve(A,v,n,p) computes (R'R)^{-1}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
553 * chol_hsolve(A,v,n,p) computes (R')^{-1}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
554 * chol_isolve(A,v,n,p) computes (R)^{-1}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
555 * chol_qf(A,v,n,p) computes ||(R')^{-1}v||^2.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
556 * chol_mult(A,v,n,p) computes (R'R)v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
557 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
558 * The solve functions assume that A is already decomposed.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
559 * chol_solve(A,v,n,p) is equivalent to applying chol_hsolve()
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
560 * and chol_isolve() in sequence.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
561 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
562
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
563 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
564 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
565
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
566 void chol_dec(A,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
567 double *A;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
568 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
569 { int i, j, k;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
570
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
571 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
572 { k = n*j+j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
573 for (i=0; i<j; i++) A[k] -= A[n*j+i]*A[n*j+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
574 if (A[k]<=0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
575 { for (i=j; i<p; i++) A[n*i+j] = 0.0; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
576 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
577 { A[k] = sqrt(A[k]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
578 for (i=j+1; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
579 { for (k=0; k<j; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
580 A[n*i+j] -= A[n*i+k]*A[n*j+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
581 A[n*i+j] /= A[n*j+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
582 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
583 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
584 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
585 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
586 for (i=j+1; i<p; i++) A[n*j+i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
587 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
588
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
589 int chol_solve(A,v,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
590 double *A, *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
591 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
592 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
593
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
594 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
595 { for (j=0; j<i; j++) v[i] -= A[i*n+j]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
596 v[i] /= A[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
597 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
598 for (i=p-1; i>=0; i--)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
599 { for (j=i+1; j<p; j++) v[i] -= A[j*n+i]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
600 v[i] /= A[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
601 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
602 return(p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
603 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
604
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
605 int chol_hsolve(A,v,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
606 double *A, *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
607 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
608 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
609
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
610 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
611 { for (j=0; j<i; j++) v[i] -= A[i*n+j]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
612 v[i] /= A[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
613 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
614 return(p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
615 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
616
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
617 int chol_isolve(A,v,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
618 double *A, *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
619 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
620 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
621
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
622 for (i=p-1; i>=0; i--)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
623 { for (j=i+1; j<p; j++) v[i] -= A[j*n+i]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
624 v[i] /= A[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
625 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
626 return(p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
627 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
628
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
629 double chol_qf(A,v,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
630 double *A, *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
631 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
632 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
633 double sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
634
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
635 sum = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
636 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
637 { for (j=0; j<i; j++) v[i] -= A[i*n+j]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
638 v[i] /= A[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
639 sum += v[i]*v[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
640 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
641 return(sum);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
642 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
643
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
644 int chol_mult(A,v,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
645 double *A, *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
646 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
647 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
648 double sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
649 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
650 { sum = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
651 for (j=i; j<p; j++) sum += A[j*n+i]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
652 v[i] = sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
653 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
654 for (i=p-1; i>=0; i--)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
655 { sum = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
656 for (j=0; j<=i; j++) sum += A[i*n+j]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
657 v[i] = sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
658 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
659 return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
660 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
661 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
662 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
663 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
664 #include <stdio.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
665 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
666 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
667 #define E_MAXIT 20
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
668 #define E_TOL 1.0e-10
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
669 #define SQR(x) ((x)*(x))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
670
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
671 double e_tol(D,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
672 double *D;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
673 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
674 { double mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
675 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
676 if (E_TOL <= 0.0) return(0.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
677 mx = D[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
678 for (i=1; i<p; i++) if (D[i*(p+1)]>mx) mx = D[i*(p+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
679 return(E_TOL*mx);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
680 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
681
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
682 void eig_dec(X,P,d)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
683 double *X, *P;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
684 int d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
685 { int i, j, k, iter, ms;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
686 double c, s, r, u, v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
687
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
688 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
689 for (j=0; j<d; j++) P[i*d+j] = (i==j);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
690
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
691 for (iter=0; iter<E_MAXIT; iter++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
692 { ms = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
693 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
694 for (j=i+1; j<d; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
695 if (SQR(X[i*d+j]) > 1.0e-15*fabs(X[i*d+i]*X[j*d+j]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
696 { c = (X[j*d+j]-X[i*d+i])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
697 s = -X[i*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
698 r = sqrt(c*c+s*s);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
699 c /= r;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
700 s = sqrt((1-c)/2)*(2*(s>0)-1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
701 c = sqrt((1+c)/2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
702 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
703 { u = X[i*d+k]; v = X[j*d+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
704 X[i*d+k] = u*c+v*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
705 X[j*d+k] = v*c-u*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
706 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
707 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
708 { u = X[k*d+i]; v = X[k*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
709 X[k*d+i] = u*c+v*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
710 X[k*d+j] = v*c-u*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
711 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
712 X[i*d+j] = X[j*d+i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
713 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
714 { u = P[k*d+i]; v = P[k*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
715 P[k*d+i] = u*c+v*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
716 P[k*d+j] = v*c-u*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
717 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
718 ms = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
719 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
720 if (ms==0) return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
721 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
722 mut_printf("eig_dec not converged\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
723 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
724
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
725 int eig_solve(J,x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
726 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
727 double *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
728 { int d, i, j, rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
729 double *D, *P, *Q, *w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
730 double tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
731
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
732 D = J->Z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
733 P = Q = J->Q;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
734 d = J->p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
735 w = J->wk;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
736
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
737 tol = e_tol(D,d);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
738
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
739 rank = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
740 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
741 { w[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
742 for (j=0; j<d; j++) w[i] += P[j*d+i]*x[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
743 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
744 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
745 if (D[i*d+i]>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
746 { w[i] /= D[i*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
747 rank++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
748 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
749 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
750 { x[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
751 for (j=0; j<d; j++) x[i] += Q[i*d+j]*w[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
752 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
753 return(rank);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
754 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
755
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
756 int eig_hsolve(J,v)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
757 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
758 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
759 { int i, j, p, rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
760 double *D, *Q, *w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
761 double tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
762
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
763 D = J->Z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
764 Q = J->Q;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
765 p = J->p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
766 w = J->wk;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
767
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
768 tol = e_tol(D,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
769 rank = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
770
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
771 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
772 { w[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
773 for (j=0; j<p; j++) w[i] += Q[j*p+i]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
774 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
775 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
776 { if (D[i*p+i]>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
777 { v[i] = w[i]/sqrt(D[i*(p+1)]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
778 rank++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
779 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
780 else v[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
781 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
782 return(rank);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
783 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
784
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
785 int eig_isolve(J,v)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
786 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
787 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
788 { int i, j, p, rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
789 double *D, *Q, *w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
790 double tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
791
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
792 D = J->Z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
793 Q = J->Q;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
794 p = J->p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
795 w = J->wk;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
796
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
797 tol = e_tol(D,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
798 rank = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
799
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
800 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
801 { if (D[i*p+i]>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
802 { v[i] = w[i]/sqrt(D[i*(p+1)]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
803 rank++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
804 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
805 else v[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
806 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
807
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
808 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
809 { w[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
810 for (j=0; j<p; j++) w[i] += Q[i*p+j]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
811 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
812
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
813 return(rank);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
814 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
815
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
816 double eig_qf(J,v)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
817 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
818 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
819 { int i, j, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
820 double sum, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
821
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
822 p = J->p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
823 sum = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
824 tol = e_tol(J->Z,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
825
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
826 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
827 if (J->Z[i*p+i]>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
828 { J->wk[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
829 for (j=0; j<p; j++) J->wk[i] += J->Q[j*p+i]*v[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
830 sum += J->wk[i]*J->wk[i]/J->Z[i*p+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
831 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
832 return(sum);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
833 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
834 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
835 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
836 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
837 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
838 * Integrate a function f over a circle or disc.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
839 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
840
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
841 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
842
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
843 void setM(M,r,s,c,b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
844 double *M, r, s, c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
845 int b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
846 { M[0] =-r*s; M[1] = r*c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
847 M[2] = b*c; M[3] = b*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
848 M[4] =-r*c; M[5] = -s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
849 M[6] = -s; M[7] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
850 M[8] =-r*s; M[9] = c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
851 M[10]= c; M[11]= 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
852 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
853
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
854 void integ_circ(f,r,orig,res,mint,b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
855 int (*f)(), mint, b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
856 double r, *orig, *res;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
857 { double y, x[2], theta, tres[MXRESULT], M[12], c, s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
858 int i, j, nr;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
859
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
860 y = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
861 for (i=0; i<mint; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
862 { theta = 2*PI*(double)i/(double)mint;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
863 c = cos(theta); s = sin(theta);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
864 x[0] = orig[0]+r*c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
865 x[1] = orig[1]+r*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
866
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
867 if (b!=0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
868 { M[0] =-r*s; M[1] = r*c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
869 M[2] = b*c; M[3] = b*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
870 M[4] =-r*c; M[5] = -s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
871 M[6] = -s; M[7] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
872 M[8] =-r*s; M[9] = c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
873 M[10]= c; M[11]= 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
874 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
875
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
876 nr = f(x,2,tres,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
877 if (i==0) setzero(res,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
878 for (j=0; j<nr; j++) res[j] += tres[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
879 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
880 y = 2 * PI * ((b==0)?r:1.0) / mint;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
881 for (j=0; j<nr; j++) res[j] *= y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
882 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
883
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
884 void integ_disc(f,fb,fl,res,resb,mg)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
885 int (*f)(), (*fb)(), *mg;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
886 double *fl, *res, *resb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
887 { double x[2], y, r, tres[MXRESULT], *orig, rmin, rmax, theta, c, s, M[12];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
888 int ct, ctb, i, j, k, nr, nrb, w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
889
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
890 orig = &fl[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
891 rmax = fl[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
892 rmin = fl[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
893 y = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
894 ct = ctb = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
895
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
896 for (j=0; j<mg[1]; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
897 { theta = 2*PI*(double)j/(double)mg[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
898 c = cos(theta); s = sin(theta);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
899 for (i= (rmin>0) ? 0 : 1; i<=mg[0]; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
900 { r = rmin + (rmax-rmin)*i/mg[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
901 w = (2+2*(i&1)-(i==0)-(i==mg[0]));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
902 x[0] = orig[0] + r*c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
903 x[1] = orig[1] + r*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
904 nr = f(x,2,tres,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
905 if (ct==0) setzero(res,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
906 for (k=0; k<nr; k++) res[k] += w*r*tres[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
907 ct++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
908 if (((i==0) | (i==mg[0])) && (fb!=NULL))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
909 { setM(M,r,s,c,1-2*(i==0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
910 nrb = fb(x,2,tres,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
911 if (ctb==0) setzero(resb,nrb);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
912 ctb++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
913 for (k=0; k<nrb; k++) resb[k] += tres[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
914 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
915 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
916 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
917
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
918
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
919 /* for (i= (rmin>0) ? 0 : 1; i<=mg[0]; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
920 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
921 r = rmin + (rmax-rmin)*i/mg[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
922 w = (2+2*(i&1)-(i==0)-(i==mg[0]));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
923
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
924 for (j=0; j<mg[1]; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
925 { theta = 2*PI*(double)j/(double)mg[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
926 c = cos(theta); s = sin(theta);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
927 x[0] = orig[0] + r*c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
928 x[1] = orig[1] + r*s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
929 nr = f(x,2,tres,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
930 if (ct==0) setzero(res,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
931 ct++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
932 for (k=0; k<nr; k++) res[k] += w*r*tres[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
933
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
934 if (((i==0) | (i==mg[0])) && (fb!=NULL))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
935 { setM(M,r,s,c,1-2*(i==0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
936 nrb = fb(x,2,tres,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
937 if (ctb==0) setzero(resb,nrb);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
938 ctb++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
939 for (k=0; k<nrb; k++) resb[k] += tres[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
940 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
941 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
942 } */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
943 for (j=0; j<nr; j++) res[j] *= 2*PI*(rmax-rmin)/(3*mg[0]*mg[1]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
944 for (j=0; j<nrb; j++) resb[j] *= 2*PI/mg[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
945 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
946 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
947 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
948 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
949 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
950 * Multivariate integration of a vector-valued function
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
951 * using Monte-Carlo method.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
952 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
953 * uses drand48() random number generator. Does not seed.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
954 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
955
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
956 #include <stdlib.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
957 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
958 extern void setzero();
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
959
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
960 static double M[(1+MXIDIM)*MXIDIM*MXIDIM];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
961
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
962 void monte(f,ll,ur,d,res,n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
963 int (*f)(), d, n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
964 double *ll, *ur, *res;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
965 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
966 int i, j, nr;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
967 #ifdef WINDOWS
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
968 mut_printf("Sorry, Monte-Carlo Integration not enabled.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
969 for (i=0; i<n; i++) res[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
970 #else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
971 double z, x[MXIDIM], tres[MXRESULT];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
972
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
973 srand48(234L);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
974
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
975 for (i=0; i<n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
976 { for (j=0; j<d; j++) x[j] = ll[j] + (ur[j]-ll[j])*drand48();
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
977 nr = f(x,d,tres,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
978 if (i==0) setzero(res,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
979 for (j=0; j<nr; j++) res[j] += tres[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
980 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
981
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
982 z = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
983 for (i=0; i<d; i++) z *= (ur[i]-ll[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
984 for (i=0; i<nr; i++) res[i] *= z/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
985 #endif
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
986 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
987 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
988 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
989 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
990 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
991 * Multivariate integration of a vector-valued function
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
992 * using Simpson's rule.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
993 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
994
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
995 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
996 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
997 extern void setzero();
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
998
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
999 static double M[(1+MXIDIM)*MXIDIM*MXIDIM];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1000
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1001 /* third order corners */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1002 void simp3(fd,x,d,resd,delta,wt,i0,i1,mg,ct,res2,index)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1003 int (*fd)(), d, wt, i0, i1, *mg, ct, *index;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1004 double *x, *resd, *delta, *res2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1005 { int k, l, m, nrd;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1006 double zb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1007
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1008 for (k=i1+1; k<d; k++) if ((index[k]==0) | (index[k]==mg[k]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1009 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1010 setzero(M,d*d);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1011 m = 0; zb = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1012 for (l=0; l<d; l++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1013 if ((l!=i0) & (l!=i1) & (l!=k))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1014 { M[m*d+l] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1015 m++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1016 zb *= delta[l];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1017 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1018 M[(d-3)*d+i0] = (index[i0]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1019 M[(d-2)*d+i1] = (index[i1]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1020 M[(d-1)*d+k] = (index[k]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1021 nrd = fd(x,d,res2,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1022 if ((ct==0) & (i0==0) & (i1==1) & (k==2)) setzero(resd,nrd);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1023 for (l=0; l<nrd; l++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1024 resd[l] += wt*zb*res2[l];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1025 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1026 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1027
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1028 /* second order corners */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1029 void simp2(fc,fd,x,d,resc,resd,delta,wt,i0,mg,ct,res2,index)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1030 int (*fc)(), (*fd)(), d, wt, i0, *mg, ct, *index;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1031 double *x, *resc, *resd, *delta, *res2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1032 { int j, k, l, nrc;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1033 double zb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1034 for (j=i0+1; j<d; j++) if ((index[j]==0) | (index[j]==mg[j]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1035 { setzero(M,d*d);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1036 l = 0; zb = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1037 for (k=0; k<d; k++) if ((k!=i0) & (k!=j))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1038 { M[l*d+k] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1039 l++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1040 zb *= delta[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1041 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1042 M[(d-2)*d+i0] = (index[i0]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1043 M[(d-1)*d+j] = (index[j]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1044 nrc = fc(x,d,res2,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1045 if ((ct==0) & (i0==0) & (j==1)) setzero(resc,nrc);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1046 for (k=0; k<nrc; k++) resc[k] += wt*zb*res2[k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1047
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1048 if (fd!=NULL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1049 simp3(fd,x,d,resd,delta,wt,i0,j,mg,ct,res2,index);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1050 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1051 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1052
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1053 /* first order boundary */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1054 void simp1(fb,fc,fd,x,d,resb,resc,resd,delta,wt,mg,ct,res2,index)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1055 int (*fb)(), (*fc)(), (*fd)(), d, wt, *mg, ct, *index;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1056 double *x, *resb, *resc, *resd, *delta, *res2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1057 { int i, j, k, nrb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1058 double zb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1059 for (i=0; i<d; i++) if ((index[i]==0) | (index[i]==mg[i]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1060 { setzero(M,(1+d)*d*d);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1061 k = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1062 for (j=0; j<d; j++) if (j!=i)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1063 { M[k*d+j] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1064 k++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1065 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1066 M[(d-1)*d+i] = (index[i]==0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1067 nrb = fb(x,d,res2,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1068 zb = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1069 for (j=0; j<d; j++) if (i!=j) zb *= delta[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1070 if ((ct==0) && (i==0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1071 for (j=0; j<nrb; j++) resb[j] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1072 for (j=0; j<nrb; j++) resb[j] += wt*zb*res2[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1073
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1074 if (fc!=NULL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1075 simp2(fc,fd,x,d,resc,resd,delta,wt,i,mg,ct,res2,index);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1076 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1077 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1078
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1079 void simpson4(f,fb,fc,fd,ll,ur,d,res,resb,resc,resd,mg,res2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1080 int (*f)(), (*fb)(), (*fc)(), (*fd)(), d, *mg;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1081 double *ll, *ur, *res, *resb, *resc, *resd, *res2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1082 { int ct, i, j, nr, wt, index[MXIDIM];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1083 double x[MXIDIM], delta[MXIDIM], z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1084
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1085 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1086 { index[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1087 x[i] = ll[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1088 if (mg[i]&1) mg[i]++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1089 delta[i] = (ur[i]-ll[i])/(3*mg[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1090 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1091 ct = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1092
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1093 while(1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1094 { wt = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1095 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1096 wt *= (4-2*(index[i]%2==0)-(index[i]==0)-(index[i]==mg[i]));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1097 nr = f(x,d,res2,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1098 if (ct==0) setzero(res,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1099 for (i=0; i<nr; i++) res[i] += wt*res2[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1100
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1101 if (fb!=NULL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1102 simp1(fb,fc,fd,x,d,resb,resc,resd,delta,wt,mg,ct,res2,index);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1103
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1104 /* compute next grid point */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1105 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1106 { index[i]++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1107 if (index[i]>mg[i])
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1108 { index[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1109 x[i] = ll[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1110 if (i==d-1) /* done */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1111 { z = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1112 for (j=0; j<d; j++) z *= delta[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1113 for (j=0; j<nr; j++) res[j] *= z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1114 return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1115 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1116 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1117 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1118 { x[i] = ll[i] + 3*delta[i]*index[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1119 i = d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1120 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1121 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1122 ct++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1123 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1124 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1125
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1126 void simpsonm(f,ll,ur,d,res,mg,res2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1127 int (*f)(), d, *mg;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1128 double *ll, *ur, *res, *res2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1129 { simpson4(f,NULL,NULL,NULL,ll,ur,d,res,NULL,NULL,NULL,mg,res2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1130 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1131
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1132 double simpson(f,l0,l1,m)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1133 double (*f)(), l0, l1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1134 int m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1135 { double x, sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1136 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1137 sum = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1138 for (i=0; i<=m; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1139 { x = ((m-i)*l0 + i*l1)/m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1140 sum += (2+2*(i&1)-(i==0)-(i==m)) * f(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1141 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1142 return( (l1-l0) * sum / (3*m) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1143 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1144 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1145 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1146 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1147 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1148
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1149 static double *res, *resb, *orig, rmin, rmax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1150 static int ct0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1151
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1152 void sphM(M,r,u)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1153 double *M, r, *u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1154 { double h, u1[3], u2[3];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1155
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1156 /* set the orthogonal unit vectors. */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1157 h = sqrt(u[0]*u[0]+u[1]*u[1]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1158 if (h<=0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1159 { u1[0] = u2[1] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1160 u1[1] = u1[2] = u2[0] = u2[2] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1161 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1162 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1163 { u1[0] = u[1]/h; u1[1] = -u[0]/h; u1[2] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1164 u2[0] = u[2]*u[0]/h; u2[1] = u[2]*u[1]/h; u2[2] = -h;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1165 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1166
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1167 /* parameterize the sphere as r(cos(t)cos(v)u + sin(t)u1 + cos(t)sin(v)u2).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1168 * first layer of M is (dx/dt, dx/dv, dx/dr) at t=v=0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1169 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1170 M[0] = r*u1[0]; M[1] = r*u1[1]; M[2] = r*u1[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1171 M[3] = r*u2[0]; M[4] = r*u2[1]; M[5] = r*u2[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1172 M[6] = u[0]; M[7] = u[1]; M[8] = u[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1173
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1174 /* next layers are second derivative matrix of components of x(r,t,v).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1175 * d^2x/dt^2 = d^2x/dv^2 = -ru; d^2x/dtdv = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1176 * d^2x/drdt = u1; d^2x/drdv = u2; d^2x/dr^2 = 0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1177 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1178
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1179 M[9] = M[13] = -r*u[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1180 M[11]= M[15] = u1[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1181 M[14]= M[16] = u2[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1182 M[10]= M[12] = M[17] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1183
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1184 M[18]= M[22] = -r*u[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1185 M[20]= M[24] = u1[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1186 M[23]= M[25] = u2[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1187 M[19]= M[21] = M[26] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1188
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1189 M[27]= M[31] = -r*u[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1190 M[29]= M[33] = u1[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1191 M[32]= M[34] = u2[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1192 M[28]= M[30] = M[35] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1193
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1194 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1195
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1196 double ip3(a,b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1197 double *a, *b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1198 { return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1199 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1200
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1201 void rn3(a)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1202 double *a;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1203 { double s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1204 s = sqrt(ip3(a,a));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1205 a[0] /= s; a[1] /= s; a[2] /= s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1206 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1207
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1208 double sptarea(a,b,c)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1209 double *a, *b, *c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1210 { double ea, eb, ec, yab, yac, ybc, sab, sac, sbc;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1211 double ab[3], ac[3], bc[3], x1[3], x2[3];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1212
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1213 ab[0] = a[0]-b[0]; ab[1] = a[1]-b[1]; ab[2] = a[2]-b[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1214 ac[0] = a[0]-c[0]; ac[1] = a[1]-c[1]; ac[2] = a[2]-c[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1215 bc[0] = b[0]-c[0]; bc[1] = b[1]-c[1]; bc[2] = b[2]-c[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1216
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1217 yab = ip3(ab,a); yac = ip3(ac,a); ybc = ip3(bc,b);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1218
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1219 x1[0] = ab[0] - yab*a[0]; x2[0] = ac[0] - yac*a[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1220 x1[1] = ab[1] - yab*a[1]; x2[1] = ac[1] - yac*a[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1221 x1[2] = ab[2] - yab*a[2]; x2[2] = ac[2] - yac*a[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1222 sab = ip3(x1,x1); sac = ip3(x2,x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1223 ea = acos(ip3(x1,x2)/sqrt(sab*sac));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1224
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1225 x1[0] = ab[0] + yab*b[0]; x2[0] = bc[0] - ybc*b[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1226 x1[1] = ab[1] + yab*b[1]; x2[1] = bc[1] - ybc*b[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1227 x1[2] = ab[2] + yab*b[2]; x2[2] = bc[2] - ybc*b[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1228 sbc = ip3(x2,x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1229 eb = acos(ip3(x1,x2)/sqrt(sab*sbc));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1230
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1231 x1[0] = ac[0] + yac*c[0]; x2[0] = bc[0] + ybc*c[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1232 x1[1] = ac[1] + yac*c[1]; x2[1] = bc[1] + ybc*c[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1233 x1[2] = ac[2] + yac*c[2]; x2[2] = bc[2] + ybc*c[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1234 ec = acos(ip3(x1,x2)/sqrt(sac*sbc));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1235
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1236 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1237 * Euler's formula is a+b+c-PI, except I've cheated...
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1238 * a=ea, c=ec, b=PI-eb, which is more stable.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1239 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1240 return(ea+ec-eb);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1241 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1242
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1243 void li(x,f,fb,mint,ar)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1244 double *x, ar;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1245 int (*f)(), (*fb)(), mint;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1246 { int i, j, nr, nrb, ct1, w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1247 double u[3], r, M[36];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1248 double sres[MXRESULT], tres[MXRESULT];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1249
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1250 /* divide mint by 2, and force to even (Simpson's rule...)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1251 * to make comparable with rectangular interpretation of mint
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1252 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1253 mint <<= 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1254 if (mint&1) mint++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1255
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1256 ct1 = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1257 for (i= (rmin==0) ? 1 : 0; i<=mint; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1258 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1259 r = rmin + (rmax-rmin)*i/mint;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1260 w = 2+2*(i&1)-(i==0)-(i==mint);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1261 u[0] = orig[0]+x[0]*r;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1262 u[1] = orig[1]+x[1]*r;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1263 u[2] = orig[2]+x[2]*r;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1264 nr = f(u,3,tres,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1265 if (ct1==0) setzero(sres,nr);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1266 for (j=0; j<nr; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1267 sres[j] += w*r*r*tres[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1268 ct1++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1269
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1270 if ((fb!=NULL) && (i==mint)) /* boundary */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1271 { sphM(M,rmax,x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1272 nrb = fb(u,3,tres,M);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1273 if (ct0==0) for (j=0; j<nrb; j++) resb[j] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1274 for (j=0; j<nrb; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1275 resb[j] += tres[j]*ar;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1276 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1277 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1278
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1279 if (ct0==0) for (j=0; j<nr; j++) res[j] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1280 ct0++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1281
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1282 for (j=0; j<nr; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1283 res[j] += sres[j] * ar * (rmax-rmin)/(3*mint);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1284 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1285
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1286 void sphint(f,fb,a,b,c,lev,mint,cent)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1287 double *a, *b, *c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1288 int (*f)(), (*fb)(), lev, mint, cent;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1289 { double x[3], ab[3], ac[3], bc[3], ar;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1290 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1291
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1292 if (lev>1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1293 { ab[0] = a[0]+b[0]; ab[1] = a[1]+b[1]; ab[2] = a[2]+b[2]; rn3(ab);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1294 ac[0] = a[0]+c[0]; ac[1] = a[1]+c[1]; ac[2] = a[2]+c[2]; rn3(ac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1295 bc[0] = b[0]+c[0]; bc[1] = b[1]+c[1]; bc[2] = b[2]+c[2]; rn3(bc);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1296 lev >>= 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1297 if (cent==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1298 { sphint(f,fb,a,ab,ac,lev,mint,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1299 sphint(f,fb,ab,bc,ac,lev,mint,0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1300 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1301 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1302 { sphint(f,fb,a,ab,ac,lev,mint,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1303 sphint(f,fb,b,ab,bc,lev,mint,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1304 sphint(f,fb,c,ac,bc,lev,mint,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1305 sphint(f,fb,ab,bc,ac,lev,mint,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1306 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1307 return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1308 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1309
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1310 x[0] = a[0]+b[0]+c[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1311 x[1] = a[1]+b[1]+c[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1312 x[2] = a[2]+b[2]+c[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1313 rn3(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1314 ar = sptarea(a,b,c);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1315
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1316 for (i=0; i<8; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1317 { if (i>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1318 { x[0] = -x[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1319 if (i%2 == 0) x[1] = -x[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1320 if (i==4) x[2] = -x[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1321 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1322 switch(cent)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1323 { case 2: /* the reflection and its 120', 240' rotations */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1324 ab[0] = x[0]; ab[1] = x[2]; ab[2] = x[1]; li(ab,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1325 ab[0] = x[2]; ab[1] = x[1]; ab[2] = x[0]; li(ab,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1326 ab[0] = x[1]; ab[1] = x[0]; ab[2] = x[2]; li(ab,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1327 case 1: /* and the 120' and 240' rotations */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1328 ab[0] = x[1]; ab[1] = x[2]; ab[2] = x[0]; li(ab,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1329 ac[0] = x[2]; ac[1] = x[0]; ac[2] = x[1]; li(ac,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1330 case 0: /* and the triangle itself. */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1331 li( x,f,fb,mint,ar);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1332 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1333 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1334 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1335
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1336 void integ_sphere(f,fb,fl,Res,Resb,mg)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1337 double *fl, *Res, *Resb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1338 int (*f)(), (*fb)(), *mg;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1339 { double a[3], b[3], c[3];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1340
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1341 a[0] = 1; a[1] = a[2] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1342 b[1] = 1; b[0] = b[2] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1343 c[2] = 1; c[0] = c[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1344
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1345 res = Res;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1346 resb=Resb;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1347 orig = &fl[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1348 rmin = fl[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1349 rmax = fl[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1350
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1351 ct0 = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1352 sphint(f,fb,a,b,c,mg[1],mg[0],0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1353 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1354 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1355 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1356 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1357 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1358 * solving symmetric equations using the jacobian structure. Currently, three
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1359 * methods can be used: cholesky decomposition, eigenvalues, eigenvalues on
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1360 * the correlation matrix.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1361 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1362 * jacob_dec(J,meth) decompose the matrix, meth=JAC_CHOL, JAC_EIG, JAC_EIGD
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1363 * jacob_solve(J,v) J^{-1}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1364 * jacob_hsolve(J,v) (R')^{-1/2}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1365 * jacob_isolve(J,v) (R)^{-1/2}v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1366 * jacob_qf(J,v) v' J^{-1} v
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1367 * jacob_mult(J,v) (R'R) v (pres. CHOL only)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1368 * where for each decomposition, R'R=J, although the different decomp's will
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1369 * produce different R's.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1370 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1371 * To set up the J matrix:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1372 * first, allocate storage: jac_alloc(J,p,wk)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1373 * where p=dimension of matrix, wk is a numeric vector of length
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1374 * jac_reqd(p) (or NULL, to allocate automatically).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1375 * now, copy the numeric values to J->Z (numeric vector with length p*p).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1376 * (or, just set J->Z to point to the data vector. But remember this
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1377 * will be overwritten by the decomposition).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1378 * finally, set:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1379 * J->st=JAC_RAW;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1380 * J->p = p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1381 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1382 * now, call jac_dec(J,meth) (optional) and the solve functions as required.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1383 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1384 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1385
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1386 #include "math.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1387 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1388
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1389 #define DEF_METH JAC_EIGD
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1390
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1391 int jac_reqd(int p) { return(2*p*(p+1)); }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1392
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1393 double *jac_alloc(J,p,wk)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1394 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1395 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1396 double *wk;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1397 { if (wk==NULL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1398 wk = (double *)calloc(2*p*(p+1),sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1399 if ( wk == NULL ) {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1400 printf("Problem allocating memory for wk\n");fflush(stdout);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1401 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1402 J->Z = wk; wk += p*p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1403 J->Q = wk; wk += p*p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1404 J->wk= wk; wk += p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1405 J->dg= wk; wk += p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1406 return(wk);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1407 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1408
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1409 void jacob_dec(J, meth)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1410 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1411 int meth;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1412 { int i, j, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1413
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1414 if (J->st != JAC_RAW) return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1415
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1416 J->sm = J->st = meth;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1417 switch(meth)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1418 { case JAC_EIG:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1419 eig_dec(J->Z,J->Q,J->p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1420 return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1421 case JAC_EIGD:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1422 p = J->p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1423 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1424 J->dg[i] = (J->Z[i*(p+1)]<=0) ? 0.0 : 1/sqrt(J->Z[i*(p+1)]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1425 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1426 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1427 J->Z[i*p+j] *= J->dg[i]*J->dg[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1428 eig_dec(J->Z,J->Q,J->p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1429 J->st = JAC_EIGD;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1430 return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1431 case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1432 chol_dec(J->Z,J->p,J->p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1433 return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1434 default: mut_printf("jacob_dec: unknown method %d",meth);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1435 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1436 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1437
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1438 int jacob_solve(J,v) /* (X^T W X)^{-1} v */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1439 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1440 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1441 { int i, rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1442
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1443 if (J->st == JAC_RAW) jacob_dec(J,DEF_METH);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1444
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1445 switch(J->st)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1446 { case JAC_EIG:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1447 return(eig_solve(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1448 case JAC_EIGD:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1449 for (i=0; i<J->p; i++) v[i] *= J->dg[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1450 rank = eig_solve(J,v);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1451 for (i=0; i<J->p; i++) v[i] *= J->dg[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1452 return(rank);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1453 case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1454 return(chol_solve(J->Z,v,J->p,J->p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1455 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1456 mut_printf("jacob_solve: unknown method %d",J->st);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1457 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1458 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1459
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1460 int jacob_hsolve(J,v) /* J^{-1/2} v */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1461 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1462 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1463 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1464
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1465 if (J->st == JAC_RAW) jacob_dec(J,DEF_METH);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1466
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1467 switch(J->st)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1468 { case JAC_EIG:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1469 return(eig_hsolve(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1470 case JAC_EIGD: /* eigenvalues on corr matrix */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1471 for (i=0; i<J->p; i++) v[i] *= J->dg[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1472 return(eig_hsolve(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1473 case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1474 return(chol_hsolve(J->Z,v,J->p,J->p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1475 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1476 mut_printf("jacob_hsolve: unknown method %d\n",J->st);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1477 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1478 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1479
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1480 int jacob_isolve(J,v) /* J^{-1/2} v */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1481 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1482 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1483 { int i, r;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1484
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1485 if (J->st == JAC_RAW) jacob_dec(J,DEF_METH);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1486
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1487 switch(J->st)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1488 { case JAC_EIG:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1489 return(eig_isolve(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1490 case JAC_EIGD: /* eigenvalues on corr matrix */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1491 r = eig_isolve(J,v);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1492 for (i=0; i<J->p; i++) v[i] *= J->dg[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1493 return(r);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1494 case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1495 return(chol_isolve(J->Z,v,J->p,J->p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1496 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1497 mut_printf("jacob_hsolve: unknown method %d\n",J->st);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1498 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1499 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1500
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1501 double jacob_qf(J,v) /* vT J^{-1} v */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1502 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1503 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1504 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1505
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1506 if (J->st == JAC_RAW) jacob_dec(J,DEF_METH);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1507
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1508 switch (J->st)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1509 { case JAC_EIG:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1510 return(eig_qf(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1511 case JAC_EIGD:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1512 for (i=0; i<J->p; i++) v[i] *= J->dg[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1513 return(eig_qf(J,v));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1514 case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1515 return(chol_qf(J->Z,v,J->p,J->p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1516 default:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1517 mut_printf("jacob_qf: invalid method\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1518 return(0.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1519 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1520 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1521
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1522 int jacob_mult(J,v) /* J v */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1523 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1524 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1525 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1526 if (J->st == JAC_RAW) jacob_dec(J,DEF_METH);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1527 switch (J->st)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1528 { case JAC_CHOL:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1529 return(chol_mult(J->Z,v,J->p,J->p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1530 default:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1531 mut_printf("jacob_mult: invalid method\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1532 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1533 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1534 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1535 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1536 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1537 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1538 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1539 * Routines for maximization of a one dimensional function f()
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1540 * over an interval [xlo,xhi]. In all cases. the flag argument
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1541 * controls the return:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1542 * flag='x', the maximizer xmax is returned.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1543 * otherwise, maximum f(xmax) is returned.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1544 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1545 * max_grid(f,xlo,xhi,n,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1546 * grid maximization of f() over [xlo,xhi] with n intervals.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1547 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1548 * max_golden(f,xlo,xhi,n,tol,err,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1549 * golden section maximization.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1550 * If n>2, an initial grid search is performed with n intervals
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1551 * (this helps deal with local maxima).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1552 * convergence criterion is |x-xmax| < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1553 * err is an error flag.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1554 * if flag='x', return value is xmax.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1555 * otherwise, return value is f(xmax).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1556 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1557 * max_quad(f,xlo,xhi,n,tol,err,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1558 * quadratic maximization.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1559 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1560 * max_nr()
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1561 * newton-raphson, handles multivariate case.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1562 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1563 * TODO: additional error checking, non-convergence stop.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1564 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1565
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1566 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1567 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1568
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1569 #define max_val(a,b) ((flag=='x') ? a : b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1570
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1571 double max_grid(f,xlo,xhi,n,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1572 double (*f)(), xlo, xhi;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1573 int n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1574 char flag;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1575 { int i, mi;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1576 double x, y, mx, my;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1577 for (i=0; i<=n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1578 { x = xlo + (xhi-xlo)*i/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1579 y = f(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1580 if ((i==0) || (y>my))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1581 { mx = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1582 my = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1583 mi = i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1584 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1585 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1586 if (mi==0) return(max_val(xlo,my));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1587 if (mi==n) return(max_val(xhi,my));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1588 return(max_val(mx,my));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1589 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1590
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1591 double max_golden(f,xlo,xhi,n,tol,err,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1592 double (*f)(), xhi, xlo, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1593 int n, *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1594 char flag;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1595 { double dlt, x0, x1, x2, x3, y0, y1, y2, y3;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1596 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1597
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1598 if (n>2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1599 { dlt = (xhi-xlo)/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1600 x0 = max_grid(f,xlo,xhi,n,'x');
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1601 if (xlo<x0) xlo = x0-dlt;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1602 if (xhi>x0) xhi = x0+dlt;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1603 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1604
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1605 x0 = xlo; y0 = f(xlo);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1606 x3 = xhi; y3 = f(xhi);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1607 x1 = gold_rat*x0 + (1-gold_rat)*x3; y1 = f(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1608 x2 = gold_rat*x3 + (1-gold_rat)*x0; y2 = f(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1609
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1610 while (fabs(x3-x0)>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1611 { if ((y1>=y0) && (y1>=y2))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1612 { x3 = x2; y3 = y2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1613 x2 = x1; y2 = y1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1614 x1 = gold_rat*x0 + (1-gold_rat)*x3; y1 = f(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1615 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1616 else if ((y2>=y3) && (y2>=y1))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1617 { x0 = x1; y0 = y1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1618 x1 = x2; y1 = y2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1619 x2 = gold_rat*x3 + (1-gold_rat)*x0; y2 = f(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1620 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1621 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1622 { if (y3>y0) { x0 = x2; y0 = y2; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1623 else { x3 = x1; y3 = y1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1624 x1 = gold_rat*x0 + (1-gold_rat)*x3; y1 = f(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1625 x2 = gold_rat*x3 + (1-gold_rat)*x0; y2 = f(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1626 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1627 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1628 if (y0>=y1) return(max_val(x0,y0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1629 if (y3>=y2) return(max_val(x3,y3));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1630 return((y1>y2) ? max_val(x1,y1) : max_val(x2,y2));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1631 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1632
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1633 double max_quad(f,xlo,xhi,n,tol,err,flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1634 double (*f)(), xhi, xlo, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1635 int n, *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1636 char flag;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1637 { double x0, x1, x2, xnew, y0, y1, y2, ynew, a, b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1638 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1639
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1640 if (n>2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1641 { x0 = max_grid(f,xlo,xhi,n,'x');
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1642 if (xlo<x0) xlo = x0-1.0/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1643 if (xhi>x0) xhi = x0+1.0/n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1644 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1645
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1646 x0 = xlo; y0 = f(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1647 x2 = xhi; y2 = f(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1648 x1 = (x0+x2)/2; y1 = f(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1649
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1650 while (x2-x0>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1651 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1652 /* first, check (y0,y1,y2) is a peak. If not,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1653 * next interval is the halve with larger of (y0,y2).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1654 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1655 if ((y0>y1) | (y2>y1))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1656 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1657 if (y0>y2) { x2 = x1; y2 = y1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1658 else { x0 = x1; y0 = y1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1659 x1 = (x0+x2)/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1660 y1 = f(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1661 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1662 else /* peak */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1663 { a = (y1-y0)*(x2-x1) + (y1-y2)*(x1-x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1664 b = ((y1-y0)*(x2-x1)*(x2+x1) + (y1-y2)*(x1-x0)*(x1+x0))/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1665 /* quadratic maximizer is b/a. But first check if a's too
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1666 * small, since we may be close to constant.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1667 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1668 if ((a<=0) | (b<x0*a) | (b>x2*a))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1669 { /* split the larger halve */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1670 xnew = ((x2-x1) > (x1-x0)) ? (x1+x2)/2 : (x0+x1)/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1671 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1672 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1673 { xnew = b/a;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1674 if (10*xnew < (9*x0+x1)) xnew = (9*x0+x1)/10;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1675 if (10*xnew > (9*x2+x1)) xnew = (9*x2+x1)/10;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1676 if (fabs(xnew-x1) < 0.001*(x2-x0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1677 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1678 if ((x2-x1) > (x1-x0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1679 xnew = (99*x1+x2)/100;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1680 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1681 xnew = (99*x1+x0)/100;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1682 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1683 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1684 ynew = f(xnew);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1685 if (xnew>x1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1686 { if (ynew >= y1) { x0 = x1; y0 = y1; x1 = xnew; y1 = ynew; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1687 else { x2 = xnew; y2 = ynew; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1688 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1689 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1690 { if (ynew >= y1) { x2 = x1; y2 = y1; x1 = xnew; y1 = ynew; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1691 else { x0 = xnew; y0 = ynew; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1692 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1693 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1694 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1695 return(max_val(x1,y1));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1696 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1697
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1698 double max_nr(F, coef, old_coef, f1, delta, J, p, maxit, tol, err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1699 double *coef, *old_coef, *f1, *delta, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1700 int (*F)(), p, maxit, *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1701 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1702 { double old_f, f, lambda;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1703 int i, j, fr;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1704 double nc, nd, cut;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1705 int rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1706
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1707 *err = NR_OK;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1708 J->p = p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1709 fr = F(coef, &f, f1, J->Z); J->st = JAC_RAW;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1710
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1711 for (i=0; i<maxit; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1712 { memcpy(old_coef,coef,p*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1713 old_f = f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1714 rank = jacob_solve(J,f1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1715 memcpy(delta,f1,p*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1716
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1717 if (rank==0) /* NR won't move! */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1718 delta[0] = -f/f1[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1719
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1720 lambda = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1721
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1722 nc = innerprod(old_coef,old_coef,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1723 nd = innerprod(delta, delta, p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1724 cut = sqrt(nc/nd);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1725 if (cut>1.0) cut = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1726 cut *= 0.0001;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1727 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1728 { for (j=0; j<p; j++) coef[j] = old_coef[j] + lambda*delta[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1729 f = old_f - 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1730 fr = F(coef, &f, f1, J->Z); J->st = JAC_RAW;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1731 if (fr==NR_BREAK) return(old_f);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1732
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1733 lambda = (fr==NR_REDUCE) ? lambda/2 : lambda/10.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1734 } while ((lambda>cut) & (f <= old_f - 1.0e-3));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1735
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1736 if (f < old_f - 1.0e-3)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1737 { *err = NR_NDIV;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1738 return(f);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1739 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1740 if (fr==NR_REDUCE) return(f);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1741
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1742 if (fabs(f-old_f) < tol) return(f);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1743
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1744 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1745 *err = NR_NCON;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1746 return(f);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1747 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1748 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1749 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1750 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1751 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1752 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1753
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1754 /* qr decomposition of X (n*p organized by column).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1755 * Take w for the ride, if not NULL.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1756 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1757 void qr(X,n,p,w)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1758 double *X, *w;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1759 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1760 { int i, j, k, mi;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1761 double c, s, mx, nx, t;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1762
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1763 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1764 { mi = j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1765 mx = fabs(X[(n+1)*j]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1766 nx = mx*mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1767
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1768 /* find the largest remaining element in j'th column, row mi.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1769 * flip that row with row j.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1770 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1771 for (i=j+1; i<n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1772 { nx += X[j*n+i]*X[j*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1773 if (fabs(X[j*n+i])>mx)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1774 { mi = i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1775 mx = fabs(X[j*n+i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1776 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1777 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1778 for (i=j; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1779 { t = X[i*n+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1780 X[i*n+j] = X[i*n+mi];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1781 X[i*n+mi] = t;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1782 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1783 if (w!=NULL) { t = w[j]; w[j] = w[mi]; w[mi] = t; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1784
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1785 /* want the diag. element -ve, so we do the `good' Householder reflect.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1786 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1787 if (X[(n+1)*j]>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1788 { for (i=j; i<p; i++) X[i*n+j] = -X[i*n+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1789 if (w!=NULL) w[j] = -w[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1790 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1791
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1792 nx = sqrt(nx);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1793 c = nx*(nx-X[(n+1)*j]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1794 if (c!=0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1795 { for (i=j+1; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1796 { s = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1797 for (k=j; k<n; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1798 s += X[i*n+k]*X[j*n+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1799 s = (s-nx*X[i*n+j])/c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1800 for (k=j; k<n; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1801 X[i*n+k] -= s*X[j*n+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1802 X[i*n+j] += s*nx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1803 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1804 if (w != NULL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1805 { s = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1806 for (k=j; k<n; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1807 s += w[k]*X[n*j+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1808 s = (s-nx*w[j])/c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1809 for (k=j; k<n; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1810 w[k] -= s*X[n*j+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1811 w[j] += s*nx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1812 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1813 X[j*n+j] = nx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1814 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1815 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1816 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1817
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1818 void qrinvx(R,x,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1819 double *R, *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1820 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1821 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1822 for (i=p-1; i>=0; i--)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1823 { for (j=i+1; j<p; j++) x[i] -= R[j*n+i]*x[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1824 x[i] /= R[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1825 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1826 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1827
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1828 void qrtinvx(R,x,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1829 double *R, *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1830 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1831 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1832 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1833 { for (j=0; j<i; j++) x[i] -= R[i*n+j]*x[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1834 x[i] /= R[i*n+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1835 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1836 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1837
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1838 void qrsolv(R,x,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1839 double *R, *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1840 int n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1841 { qrtinvx(R,x,n,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1842 qrinvx(R,x,n,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1843 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1844 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1845 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1846 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1847 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1848 * solve f(x)=c by various methods, with varying stability etc...
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1849 * xlo and xhi should be initial bounds for the solution.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1850 * convergence criterion is |f(x)-c| < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1851 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1852 * double solve_bisect(f,c,xmin,xmax,tol,bd_flag,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1853 * double solve_secant(f,c,xmin,xmax,tol,bd_flag,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1854 * Bisection and secant methods for solving of f(x)=c.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1855 * xmin and xmax are starting values and bound for solution.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1856 * tol = convergence criterion, |f(x)-c| < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1857 * bd_flag = if (xmin,xmax) doesn't bound a solution, what action to take?
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1858 * BDF_NONE returns error.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1859 * BDF_EXPRIGHT increases xmax.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1860 * BDF_EXPLEFT decreases xmin.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1861 * err = error flag.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1862 * The (xmin,xmax) bound is not formally necessary for the secant method.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1863 * But having such a bound vastly improves stability; the code performs
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1864 * a bisection step whenever the iterations run outside the bounds.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1865 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1866 * double solve_nr(f,f1,c,x0,tol,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1867 * Newton-Raphson solution of f(x)=c.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1868 * f1 = f'(x).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1869 * x0 = starting value.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1870 * tol = convergence criteria, |f(x)-c| < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1871 * err = error flag.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1872 * No stability checks at present.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1873 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1874 * double solve_fp(f,x0,tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1875 * fixed-point iteration to solve f(x)=x.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1876 * x0 = starting value.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1877 * tol = convergence criteria, stops when |f(x)-x| < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1878 * Convergence requires |f'(x)|<1 in neighborhood of true solution;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1879 * f'(x) \approx 0 gives the fastest convergence.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1880 * No stability checks at present.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1881 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1882 * TODO: additional error checking, non-convergence stop.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1883 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1884
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1885 #include <math.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1886 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1887
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1888 typedef struct {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1889 double xmin, xmax, x0, x1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1890 double ymin, ymax, y0, y1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1891 } solvest;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1892
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1893 int step_expand(f,c,sv,bd_flag)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1894 double (*f)(), c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1895 solvest *sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1896 int bd_flag;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1897 { double x, y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1898 if (sv->ymin*sv->ymax <= 0.0) return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1899 if (bd_flag == BDF_NONE)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1900 { mut_printf("invalid bracket\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1901 return(1); /* error */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1902 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1903 if (bd_flag == BDF_EXPRIGHT)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1904 { while (sv->ymin*sv->ymax > 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1905 { x = sv->xmax + 2*(sv->xmax-sv->xmin);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1906 y = f(x) - c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1907 sv->xmin = sv->xmax; sv->xmax = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1908 sv->ymin = sv->ymax; sv->ymax = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1909 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1910 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1911 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1912 if (bd_flag == BDF_EXPLEFT)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1913 { while (sv->ymin*sv->ymax > 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1914 { x = sv->xmin - 2*(sv->xmax-sv->xmin);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1915 y = f(x) - c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1916 sv->xmax = sv->xmin; sv->xmin = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1917 sv->ymax = sv->ymin; sv->ymin = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1918 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1919 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1920 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1921 mut_printf("step_expand: unknown bd_flag %d.\n",bd_flag);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1922 return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1923 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1924
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1925 int step_addin(sv,x,y)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1926 solvest *sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1927 double x, y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1928 { sv->x1 = sv->x0; sv->x0 = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1929 sv->y1 = sv->y0; sv->y0 = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1930 if (y*sv->ymin > 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1931 { sv->xmin = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1932 sv->ymin = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1933 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1934 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1935 if (y*sv->ymax > 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1936 { sv->xmax = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1937 sv->ymax = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1938 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1939 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1940 if (y==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1941 { sv->xmin = sv->xmax = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1942 sv->ymin = sv->ymax = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1943 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1944 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1945 return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1946 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1947
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1948 int step_bisect(f,c,sv)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1949 double (*f)(), c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1950 solvest *sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1951 { double x, y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1952 x = sv->x0 = (sv->xmin + sv->xmax)/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1953 y = sv->y0 = f(x)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1954 return(step_addin(sv,x,y));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1955 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1956
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1957 double solve_bisect(f,c,xmin,xmax,tol,bd_flag,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1958 double (*f)(), c, xmin, xmax, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1959 int bd_flag, *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1960 { solvest sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1961 int z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1962 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1963 sv.xmin = xmin; sv.ymin = f(xmin)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1964 sv.xmax = xmax; sv.ymax = f(xmax)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1965 *err = step_expand(f,c,&sv,bd_flag);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1966 if (*err>0) return(sv.xmin);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1967 while(1) /* infinite loop if f is discontinuous */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1968 { z = step_bisect(f,c,&sv);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1969 if (z)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1970 { *err = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1971 return(sv.x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1972 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1973 if (fabs(sv.y0)<tol) return(sv.x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1974 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1975 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1976
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1977 int step_secant(f,c,sv)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1978 double (*f)(), c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1979 solvest *sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1980 { double x, y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1981 if (sv->y0==sv->y1) return(step_bisect(f,c,sv));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1982 x = sv->x0 + (sv->x1-sv->x0)*sv->y0/(sv->y0-sv->y1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1983 if ((x<=sv->xmin) | (x>=sv->xmax)) return(step_bisect(f,c,sv));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1984 y = f(x)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1985 return(step_addin(sv,x,y));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1986 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1987
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1988 double solve_secant(f,c,xmin,xmax,tol,bd_flag,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1989 double (*f)(), c, xmin, xmax, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1990 int bd_flag, *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1991 { solvest sv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1992 int z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1993 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1994 sv.xmin = xmin; sv.ymin = f(xmin)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1995 sv.xmax = xmax; sv.ymax = f(xmax)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1996 *err = step_expand(f,c,&sv,bd_flag);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1997 if (*err>0) return(sv.xmin);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1998 sv.x0 = sv.xmin; sv.y0 = sv.ymin;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
1999 sv.x1 = sv.xmax; sv.y1 = sv.ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2000 while(1) /* infinite loop if f is discontinuous */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2001 { z = step_secant(f,c,&sv);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2002 if (z)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2003 { *err = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2004 return(sv.x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2005 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2006 if (fabs(sv.y0)<tol) return(sv.x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2007 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2008 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2009
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2010 double solve_nr(f,f1,c,x0,tol,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2011 double (*f)(), (*f1)(), c, x0, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2012 int *err;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2013 { double y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2014 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2015 { y = f(x0)-c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2016 x0 -= y/f1(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2017 } while (fabs(y)>tol);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2018 return(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2019 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2020
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2021 double solve_fp(f,x0,tol,maxit)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2022 double (*f)(), x0, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2023 int maxit;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2024 { double x1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2025 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2026 for (i=0; i<maxit; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2027 { x1 = f(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2028 if (fabs(x1-x0)<tol) return(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2029 x0 = x1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2030 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2031 return(x1); /* although it hasn't converged */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2032 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2033 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2034 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2035 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2036 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2037
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2038 void svd(x,p,q,d,mxit) /* svd of square matrix */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2039 double *x, *p, *q;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2040 int d, mxit;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2041 { int i, j, k, iter, ms, zer;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2042 double r, u, v, cp, cm, sp, sm, c1, c2, s1, s2, mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2043 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2044 for (j=0; j<d; j++) p[i*d+j] = q[i*d+j] = (i==j);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2045 for (iter=0; iter<mxit; iter++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2046 { ms = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2047 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2048 for (j=i+1; j<d; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2049 { s1 = fabs(x[i*d+j]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2050 s2 = fabs(x[j*d+i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2051 mx = (s1>s2) ? s1 : s2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2052 zer = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2053 if (mx*mx>1.0e-15*fabs(x[i*d+i]*x[j*d+j]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2054 { if (fabs(x[i*(d+1)])<fabs(x[j*(d+1)]))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2055 { for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2056 { u = x[i*d+k]; x[i*d+k] = x[j*d+k]; x[j*d+k] = u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2057 u = p[k*d+i]; p[k*d+i] = p[k*d+j]; p[k*d+j] = u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2058 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2059 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2060 { u = x[k*d+i]; x[k*d+i] = x[k*d+j]; x[k*d+j] = u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2061 u = q[k*d+i]; q[k*d+i] = q[k*d+j]; q[k*d+j] = u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2062 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2063 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2064 cp = x[i*(d+1)]+x[j*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2065 sp = x[j*d+i]-x[i*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2066 r = sqrt(cp*cp+sp*sp);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2067 if (r>0) { cp /= r; sp /= r; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2068 else { cp = 1.0; zer = 0;}
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2069 cm = x[i*(d+1)]-x[j*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2070 sm = x[i*d+j]+x[j*d+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2071 r = sqrt(cm*cm+sm*sm);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2072 if (r>0) { cm /= r; sm /= r; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2073 else { cm = 1.0; zer = 0;}
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2074 c1 = cm+cp;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2075 s1 = sm+sp;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2076 r = sqrt(c1*c1+s1*s1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2077 if (r>0) { c1 /= r; s1 /= r; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2078 else { c1 = 1.0; zer = 0;}
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2079 if (fabs(s1)>ms) ms = fabs(s1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2080 c2 = cm+cp;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2081 s2 = sp-sm;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2082 r = sqrt(c2*c2+s2*s2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2083 if (r>0) { c2 /= r; s2 /= r; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2084 else { c2 = 1.0; zer = 0;}
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2085 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2086 { u = x[i*d+k]; v = x[j*d+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2087 x[i*d+k] = c1*u+s1*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2088 x[j*d+k] = c1*v-s1*u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2089 u = p[k*d+i]; v = p[k*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2090 p[k*d+i] = c1*u+s1*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2091 p[k*d+j] = c1*v-s1*u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2092 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2093 for (k=0; k<d; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2094 { u = x[k*d+i]; v = x[k*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2095 x[k*d+i] = c2*u-s2*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2096 x[k*d+j] = s2*u+c2*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2097 u = q[k*d+i]; v = q[k*d+j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2098 q[k*d+i] = c2*u-s2*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2099 q[k*d+j] = s2*u+c2*v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2100 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2101 if (zer) x[i*d+j] = x[j*d+i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2102 ms = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2103 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2104 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2105 if (ms==0) iter=mxit+10;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2106 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2107 if (iter==mxit) mut_printf("Warning: svd not converged.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2108 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2109 if (x[i*d+i]<0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2110 { x[i*d+i] = -x[i*d+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2111 for (j=0; j<d; j++) p[j*d+i] = -p[j*d+i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2112 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2113 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2114
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2115 int svdsolve(x,w,P,D,Q,d,tol) /* original X = PDQ^T; comp. QD^{-1}P^T x */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2116 double *x, *w, *P, *D, *Q, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2117 int d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2118 { int i, j, rank;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2119 double mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2120 if (tol>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2121 { mx = D[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2122 for (i=1; i<d; i++) if (D[i*(d+1)]>mx) mx = D[i*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2123 tol *= mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2124 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2125 rank = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2126 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2127 { w[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2128 for (j=0; j<d; j++) w[i] += P[j*d+i]*x[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2129 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2130 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2131 if (D[i*d+i]>tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2132 { w[i] /= D[i*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2133 rank++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2134 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2135 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2136 { x[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2137 for (j=0; j<d; j++) x[i] += Q[i*d+j]*w[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2138 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2139 return(rank);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2140 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2141
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2142 void hsvdsolve(x,w,P,D,Q,d,tol) /* original X = PDQ^T; comp. D^{-1/2}P^T x */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2143 double *x, *w, *P, *D, *Q, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2144 int d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2145 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2146 double mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2147 if (tol>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2148 { mx = D[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2149 for (i=1; i<d; i++) if (D[i*(d+1)]>mx) mx = D[i*(d+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2150 tol *= mx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2151 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2152 for (i=0; i<d; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2153 { w[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2154 for (j=0; j<d; j++) w[i] += P[j*d+i]*x[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2155 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2156 for (i=0; i<d; i++) if (D[i*d+i]>tol) w[i] /= sqrt(D[i*(d+1)]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2157 for (i=0; i<d; i++) x[i] = w[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2158 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2159 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2160 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2161 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2162 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2163 * Includes some miscellaneous vector functions:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2164 * setzero(v,p) sets all elements of v to 0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2165 * unitvec(x,k,p) sets x to k'th unit vector e_k.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2166 * innerprod(v1,v2,p) inner product.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2167 * addouter(A,v1,v2,p,c) A <- A + c * v_1 v2^T
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2168 * multmatscal(A,z,n) A <- A*z
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2169 * matrixmultiply(A,B,C,m,n,p) C(m*p) <- A(m*n) * B(n*p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2170 * transpose(x,m,n) inline transpose
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2171 * m_trace(x,n) trace
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2172 * vecsum(x,n) sum elements.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2173 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2174
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2175 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2176
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2177 void setzero(v,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2178 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2179 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2180 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2181 for (i=0; i<p; i++) v[i] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2182 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2183
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2184 void unitvec(x,k,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2185 double *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2186 int k, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2187 { setzero(x,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2188 x[k] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2189 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2190
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2191 double innerprod(v1,v2,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2192 double *v1, *v2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2193 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2194 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2195 double s;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2196 s = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2197 for (i=0; i<p; i++) s += v1[i]*v2[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2198 return(s);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2199 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2200
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2201 void addouter(A,v1,v2,p,c)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2202 double *A, *v1, *v2, c;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2203 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2204 { int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2205 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2206 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2207 A[i*p+j] += c*v1[i]*v2[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2208 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2209
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2210 void multmatscal(A,z,n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2211 double *A, z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2212 int n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2213 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2214 for (i=0; i<n; i++) A[i] *= z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2215 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2216
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2217 /* matrix multiply A (m*n) times B (n*p).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2218 * store in C (m*p).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2219 * all matrices stored by column.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2220 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2221 void matrixmultiply(A,B,C,m,n,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2222 double *A, *B, *C;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2223 int m, n, p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2224 { int i, j, k, ij;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2225 for (i=0; i<m; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2226 for (j=0; j<p; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2227 { ij = j*m+i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2228 C[ij] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2229 for (k=0; k<n; k++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2230 C[ij] += A[k*m+i] * B[j*n+k];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2231 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2232 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2233
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2234 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2235 * transpose() transposes an m*n matrix in place.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2236 * At input, the matrix has n rows, m columns and
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2237 * x[0..n-1] is the is the first column.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2238 * At output, the matrix has m rows, n columns and
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2239 * x[0..m-1] is the first column.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2240 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2241 void transpose(x,m,n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2242 double *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2243 int m, n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2244 { int t0, t, ti, tj;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2245 double z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2246 for (t0=1; t0<m*n-2; t0++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2247 { ti = t0%m; tj = t0/m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2248 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2249 { t = ti*n+tj;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2250 ti= t%m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2251 tj= t/m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2252 } while (t<t0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2253 z = x[t];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2254 x[t] = x[t0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2255 x[t0] = z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2256 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2257 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2258
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2259 /* trace of an n*n square matrix. */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2260 double m_trace(x,n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2261 double *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2262 int n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2263 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2264 double sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2265 sum = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2266 for (i=0; i<n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2267 sum += x[i*(n+1)];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2268 return(sum);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2269 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2270
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2271 double vecsum(v,n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2272 double *v;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2273 int n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2274 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2275 double sum;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2276 sum = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2277 for (i=0; i<n; i++) sum += v[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2278 return(sum);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2279 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2280 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2281 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2282 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2283 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2284 miscellaneous functions that may not be defined in the math
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2285 libraries. The implementations are crude.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2286 mut_daws(x) -- dawson's function
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2287 mut_exp(x) -- exp(x), but it won't overflow.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2288
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2289 where required, these must be #define'd in header files.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2290
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2291 also includes
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2292 ptail(x) -- exp(x*x/2)*int_{-\infty}^x exp(-u^2/2)du for x < -6.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2293 logit(x) -- logistic function.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2294 expit(x) -- inverse of logit.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2295 factorial(n)-- factorial
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2296 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2297
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2298 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2299
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2300 double mut_exp(x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2301 double x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2302 { if (x>700.0) return(1.014232054735004e+304);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2303 return(exp(x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2304 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2305
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2306 double mut_daws(x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2307 double x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2308 { static double val[] = {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2309 0, 0.24485619356002, 0.46034428261948, 0.62399959848185, 0.72477845900708,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2310 0.76388186132749, 0.75213621001998, 0.70541701910853, 0.63998807456541,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2311 0.56917098836654, 0.50187821196415, 0.44274283060424, 0.39316687916687,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2312 0.35260646480842, 0.31964847250685, 0.29271122077502, 0.27039629581340,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2313 0.25160207761769, 0.23551176224443, 0.22153505358518, 0.20924575719548,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2314 0.19833146819662, 0.18855782729305, 0.17974461154688, 0.17175005072385 };
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2315 double h, f0, f1, f2, y, z, xx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2316 int j, m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2317 if (x<0) return(-mut_daws(-x));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2318 if (x>6)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2319 { /* Tail series: 1/x + 1/x^3 + 1.3/x^5 + 1.3.5/x^7 + ... */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2320 y = z = 1/x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2321 j = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2322 while (((f0=(2*j+1)/(x*x))<1) && (y>1.0e-10*z))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2323 { y *= f0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2324 z += y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2325 j++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2326 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2327 return(z);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2328 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2329 m = (int) (4*x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2330 h = x-0.25*m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2331 if (h>0.125)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2332 { m++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2333 h = h-0.25;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2334 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2335 xx = 0.25*m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2336 f0 = val[m];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2337 f1 = 1-xx*f0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2338 z = f0+h*f1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2339 y = h;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2340 j = 2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2341 while (fabs(y)>z*1.0e-10)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2342 { f2 = -(j-1)*f0-xx*f1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2343 y *= h/j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2344 z += y*f2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2345 f0 = f1; f1 = f2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2346 j++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2347 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2348 return(z);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2349 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2350
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2351 double ptail(x) /* exp(x*x/2)*int_{-\infty}^x exp(-u^2/2)du for x < -6 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2352 double x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2353 { double y, z, f0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2354 int j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2355 y = z = -1.0/x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2356 j = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2357 while ((fabs(f0= -(2*j+1)/(x*x))<1) && (fabs(y)>1.0e-10*z))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2358 { y *= f0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2359 z += y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2360 j++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2361 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2362 return(z);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2363 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2364
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2365 double logit(x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2366 double x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2367 { return(log(x/(1-x)));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2368 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2369
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2370 double expit(x)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2371 double x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2372 { double u;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2373 if (x<0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2374 { u = exp(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2375 return(u/(1+u));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2376 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2377 return(1/(1+exp(-x)));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2378 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2379
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2380 int factorial(n)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2381 int n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2382 { if (n<=1) return(1.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2383 return(n*factorial(n-1));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2384 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2385 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2386 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2387 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2388 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2389 * Constrained maximization of a bivariate function.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2390 * maxbvgrid(f,x,ll,ur,m0,m1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2391 * maximizes over a grid of m0*m1 points. Returns the maximum,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2392 * and the maximizer through the array x. Usually this is a starter,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2393 * to choose between local maxima, followed by other routines to refine.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2394 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2395 * maxbvstep(f,x,ymax,h,ll,ur,err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2396 * essentially multivariate bisection. A 3x3 grid of points is
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2397 * built around the starting value (x,ymax). This grid is moved
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2398 * around (step size h[0] and h[1] in the two dimensions) until
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2399 * the maximum is in the middle. Then, the step size is halved.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2400 * Usually, this will be called in a loop.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2401 * The error flag is set if the maximum can't be centered in a
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2402 * reasonable number of steps.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2403 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2404 * maxbv(f,x,h,ll,ur,m0,m1,tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2405 * combines the two previous functions. It begins with a grid search
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2406 * (if m0>0 and m1>0), followed by refinement. Refines until both h
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2407 * components are < tol.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2408 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2409 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2410
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2411 #define max(a,b) ((a)>(b) ? (a) : (b))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2412 #define min(a,b) ((a)<(b) ? (a) : (b))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2413
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2414 double maxbvgrid(f,x,ll,ur,m0,m1,con)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2415 double (*f)(), *x, *ll, *ur;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2416 int m0, m1, *con;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2417 { int i, j, im, jm;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2418 double y, ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2419
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2420 im = -1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2421 for (i=0; i<=m0; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2422 { x[0] = ((m0-i)*ll[0] + i*ur[0])/m0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2423 for (j=0; j<=m1; j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2424 { x[1] = ((m1-j)*ll[1] + j*ur[1])/m1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2425 y = f(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2426 if ((im==-1) || (y>ymax))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2427 { im = i; jm = j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2428 ymax = y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2429 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2430 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2431 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2432
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2433 x[0] = ((m0-im)*ll[0] + im*ur[0])/m0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2434 x[1] = ((m1-jm)*ll[1] + jm*ur[1])/m1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2435 con[0] = (im==m0)-(im==0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2436 con[1] = (jm==m1)-(jm==0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2437 return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2438 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2439
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2440 double maxbvstep(f,x,ymax,h,ll,ur,err,con)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2441 double (*f)(), *x, ymax, *h, *ll, *ur;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2442 int *err, *con;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2443 { int i, j, ij, imax, steps, cts[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2444 double newx, X[9][2], y[9];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2445
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2446 imax =4; y[4] = ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2447
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2448 for (i=(con[0]==-1)-1; i<2-(con[0]==1); i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2449 for (j=(con[1]==-1)-1; j<2-(con[1]==1); j++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2450 { ij = 3*i+j+4;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2451 X[ij][0] = x[0]+i*h[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2452 if (X[ij][0] < ll[0]+0.001*h[0]) X[ij][0] = ll[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2453 if (X[ij][0] > ur[0]-0.001*h[0]) X[ij][0] = ur[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2454 X[ij][1] = x[1]+j*h[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2455 if (X[ij][1] < ll[1]+0.001*h[1]) X[ij][1] = ll[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2456 if (X[ij][1] > ur[1]-0.001*h[1]) X[ij][1] = ur[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2457 if (ij != 4)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2458 { y[ij] = f(X[ij]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2459 if (y[ij]>ymax) { imax = ij; ymax = y[ij]; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2460 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2461 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2462
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2463 steps = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2464 cts[0] = cts[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2465 while ((steps<20) && (imax != 4))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2466 { steps++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2467 if ((con[0]>-1) && ((imax/3)==0)) /* shift right */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2468 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2469 cts[0]--;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2470 for (i=8; i>2; i--)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2471 { X[i][0] = X[i-3][0]; y[i] = y[i-3];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2472 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2473 imax = imax+3;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2474 if (X[imax][0]==ll[0])
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2475 con[0] = -1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2476 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2477 { newx = X[imax][0]-h[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2478 if (newx < ll[0]+0.001*h[0]) newx = ll[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2479 for (i=(con[1]==-1); i<3-(con[1]==1); i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2480 { X[i][0] = newx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2481 y[i] = f(X[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2482 if (y[i]>ymax) { ymax = y[i]; imax = i; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2483 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2484 con[0] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2485 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2486 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2487
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2488 if ((con[0]<1) && ((imax/3)==2)) /* shift left */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2489 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2490 cts[0]++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2491 for (i=0; i<6; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2492 { X[i][0] = X[i+3][0]; y[i] = y[i+3];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2493 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2494 imax = imax-3;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2495 if (X[imax][0]==ur[0])
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2496 con[0] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2497 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2498 { newx = X[imax][0]+h[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2499 if (newx > ur[0]-0.001*h[0]) newx = ur[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2500 for (i=6+(con[1]==-1); i<9-(con[1]==1); i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2501 { X[i][0] = newx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2502 y[i] = f(X[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2503 if (y[i]>ymax) { ymax = y[i]; imax = i; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2504 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2505 con[0] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2506 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2507 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2508
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2509 if ((con[1]>-1) && ((imax%3)==0)) /* shift up */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2510 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2511 cts[1]--;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2512 for (i=9; i>0; i--) if (i%3 > 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2513 { X[i][1] = X[i-1][1]; y[i] = y[i-1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2514 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2515 imax = imax+1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2516 if (X[imax][1]==ll[1])
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2517 con[1] = -1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2518 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2519 { newx = X[imax][1]-h[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2520 if (newx < ll[1]+0.001*h[1]) newx = ll[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2521 for (i=3*(con[0]==-1); i<7-(con[0]==1); i=i+3)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2522 { X[i][1] = newx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2523 y[i] = f(X[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2524 if (y[i]>ymax) { ymax = y[i]; imax = i; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2525 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2526 con[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2527 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2528 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2529
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2530 if ((con[1]<1) && ((imax%3)==2)) /* shift down */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2531 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2532 cts[1]++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2533 for (i=0; i<9; i++) if (i%3 < 2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2534 { X[i][1] = X[i+1][1]; y[i] = y[i+1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2535 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2536 imax = imax-1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2537 if (X[imax][1]==ur[1])
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2538 con[1] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2539 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2540 { newx = X[imax][1]+h[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2541 if (newx > ur[1]-0.001*h[1]) newx = ur[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2542 for (i=2+3*(con[0]==-1); i<9-(con[0]==1); i=i+3)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2543 { X[i][1] = newx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2544 y[i] = f(X[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2545 if (y[i]>ymax) { ymax = y[i]; imax = i; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2546 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2547 con[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2548 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2549 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2550 /* if we've taken 3 steps in one direction, try increasing the
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2551 * corresponding h.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2552 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2553 if ((cts[0]==-2) | (cts[0]==2))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2554 { h[0] = 2*h[0]; cts[0] = 0; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2555 if ((cts[1]==-2) | (cts[1]==2))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2556 { h[1] = 2*h[1]; cts[1] = 0; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2557 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2558
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2559 if (steps==40)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2560 *err = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2561 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2562 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2563 h[0] /= 2.0; h[1] /= 2.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2564 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2565 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2566
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2567 x[0] = X[imax][0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2568 x[1] = X[imax][1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2569 return(y[imax]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2570 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2571
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2572 #define BQMmaxp 5
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2573
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2574 int boxquadmin(J,b0,p,x0,ll,ur)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2575 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2576 double *b0, *x0, *ll, *ur;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2577 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2578 { double b[BQMmaxp], x[BQMmaxp], L[BQMmaxp*BQMmaxp], C[BQMmaxp*BQMmaxp], d[BQMmaxp];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2579 double f, fmin;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2580 int i, imin, m, con[BQMmaxp], rlx;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2581
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2582 if (p>BQMmaxp) mut_printf("boxquadmin: maxp is 5.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2583 if (J->st != JAC_RAW) mut_printf("boxquadmin: must start with JAC_RAW.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2584
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2585 m = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2586 setzero(L,p*p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2587 setzero(x,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2588 memcpy(C,J->Z,p*p*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2589 for (i=0; i<p; i++) con[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2590
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2591 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2592 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2593 /* first, keep minimizing and add constraints, one at a time.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2594 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2595 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2596 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2597 matrixmultiply(C,x,b,p,p,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2598 for (i=0; i<p; i++) b[i] += b0[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2599 conquadmin(J,b,p,L,d,m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2600 /* if C matrix is not pd, don't even bother.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2601 * this relies on having used cholesky dec.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2602 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2603 if ((J->Z[0]==0.0) | (J->Z[3]==0.0)) return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2604 fmin = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2605 for (i=0; i<p; i++) if (con[i]==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2606 { f = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2607 if (x0[i]+x[i]+b[i] < ll[i]) f = (ll[i]-x[i]-x0[i])/b[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2608 if (x0[i]+x[i]+b[i] > ur[i]) f = (ur[i]-x[i]-x0[i])/b[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2609 if (f<fmin) fmin = f;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2610 imin = i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2611 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2612 for (i=0; i<p; i++) x[i] += fmin*b[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2613 if (fmin<1.0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2614 { L[m*p+imin] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2615 m++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2616 con[imin] = (b[imin]<0) ? -1 : 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2617 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2618 } while ((fmin < 1.0) & (m<p));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2619
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2620 /* now, can I relax any constraints?
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2621 * compute slopes at current point. Can relax if:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2622 * slope is -ve on a lower boundary.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2623 * slope is +ve on an upper boundary.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2624 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2625 rlx = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2626 if (m>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2627 { matrixmultiply(C,x,b,p,p,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2628 for (i=0; i<p; i++) b[i] += b0[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2629 for (i=0; i<p; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2630 { if ((con[i]==-1)&& (b[i]<0)) { con[i] = 0; rlx = 1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2631 if ((con[i]==1) && (b[i]>0)) { con[i] = 0; rlx = 1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2632 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2633
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2634 if (rlx) /* reconstruct the constraint matrix */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2635 { setzero(L,p*p); m = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2636 for (i=0; i<p; i++) if (con[i] != 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2637 { L[m*p+i] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2638 m++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2639 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2640 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2641 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2642 } while (rlx);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2643
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2644 memcpy(b0,x,p*sizeof(double)); /* this is how far we should move from x0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2645 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2646 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2647
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2648 double maxquadstep(f,x,ymax,h,ll,ur,err,con)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2649 double (*f)(), *x, ymax, *h, *ll, *ur;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2650 int *err, *con;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2651 { jacobian J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2652 double b[2], c[2], d, jwork[12];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2653 double x0, x1, y0, y1, ym, h0, xl[2], xu[2], xi[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2654 int i, m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2655
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2656 *err = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2657
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2658 /* first, can we relax any of the initial constraints?
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2659 * if so, just do one step away from the boundary, and
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2660 * return for restart.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2661 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2662 for (i=0; i<2; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2663 if (con[i] != 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2664 { xi[0] = x[0]; xi[1] = x[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2665 xi[i] = x[i]-con[i]*h[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2666 y0 = f(xi);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2667 if (y0>ymax)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2668 { memcpy(x,xi,2*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2669 con[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2670 return(y0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2671 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2672 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2673
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2674 /* now, all initial constraints remain active.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2675 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2676
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2677 m = 9;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2678 for (i=0; i<2; i++) if (con[i]==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2679 { m /= 3;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2680 xl[0] = x[0]; xl[1] = x[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2681 xl[i] = max(x[i]-h[i],ll[i]); y0 = f(xl);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2682 x0 = xl[i]-x[i]; y0 -= ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2683 xu[0] = x[0]; xu[1] = x[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2684 xu[i] = min(x[i]+h[i],ur[i]); y1 = f(xu);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2685 x1 = xu[i]-x[i]; y1 -= ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2686 if (x0*x1*(x1-x0)==0) { *err = 1; return(0.0); }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2687 b[i] = (x0*x0*y1-x1*x1*y0)/(x0*x1*(x0-x1));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2688 c[i] = 2*(x0*y1-x1*y0)/(x0*x1*(x1-x0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2689 if (c[i] >= 0.0) { *err = 1; return(0.0); }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2690 xi[i] = (b[i]<0) ? xl[i] : xu[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2691 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2692 else { c[i] = -1.0; b[i] = 0.0; } /* enforce initial constraints */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2693
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2694 if ((con[0]==0) && (con[1]==0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2695 { x0 = xi[0]-x[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2696 x1 = xi[1]-x[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2697 ym = f(xi) - ymax - b[0]*x0 - c[0]*x0*x0/2 - b[1]*x1 - c[1]*x1*x1/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2698 d = ym/(x0*x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2699 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2700 else d = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2701
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2702 /* now, maximize the quadratic.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2703 * y[4] + b0*x0 + b1*x1 + 0.5(c0*x0*x0 + c1*x1*x1 + 2*d*x0*x1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2704 * -ve everything, to call quadmin.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2705 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2706 jac_alloc(&J,2,jwork);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2707 J.Z[0] = -c[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2708 J.Z[1] = J.Z[2] = -d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2709 J.Z[3] = -c[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2710 J.st = JAC_RAW;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2711 J.p = 2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2712 b[0] = -b[0]; b[1] = -b[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2713 *err = boxquadmin(&J,b,2,x,ll,ur);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2714 if (*err) return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2715
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2716 /* test to see if this step successfully increases...
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2717 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2718 for (i=0; i<2; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2719 { xi[i] = x[i]+b[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2720 if (xi[i]<ll[i]+1e-8*h[i]) xi[i] = ll[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2721 if (xi[i]>ur[i]-1e-8*h[i]) xi[i] = ur[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2722 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2723 y1 = f(xi);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2724 if (y1 < ymax) /* no increase */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2725 { *err = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2726 return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2727 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2728
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2729 /* wonderful. update x, h, with the restriction that h can't decrease
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2730 * by a factor over 10, or increase by over 2.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2731 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2732 for (i=0; i<2; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2733 { x[i] = xi[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2734 if (x[i]==ll[i]) con[i] = -1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2735 if (x[i]==ur[i]) con[i] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2736 h0 = fabs(b[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2737 h0 = min(h0,2*h[i]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2738 h0 = max(h0,h[i]/10);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2739 h[i] = min(h0,(ur[i]-ll[i])/2.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2740 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2741 return(y1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2742 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2743
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2744 double maxbv(f,x,h,ll,ur,m0,m1,tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2745 double (*f)(), *x, *h, *ll, *ur, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2746 int m0, m1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2747 { double ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2748 int err, con[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2749
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2750 con[0] = con[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2751 if ((m0>0) & (m1>0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2752 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2753 ymax = maxbvgrid(f,x,ll,ur,m0,m1,con);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2754 h[0] = (ur[0]-ll[0])/(2*m0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2755 h[1] = (ur[1]-ll[1])/(2*m1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2756 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2757 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2758 { x[0] = (ll[0]+ur[0])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2759 x[1] = (ll[1]+ur[1])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2760 h[0] = (ur[0]-ll[0])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2761 h[1] = (ur[1]-ll[1])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2762 ymax = f(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2763 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2764
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2765 while ((h[0]>tol) | (h[1]>tol))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2766 { ymax = maxbvstep(f,x,ymax,h,ll,ur,&err,con);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2767 if (err) mut_printf("maxbvstep failure\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2768 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2769
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2770 return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2771 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2772
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2773 double maxbvq(f,x,h,ll,ur,m0,m1,tol)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2774 double (*f)(), *x, *h, *ll, *ur, tol;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2775 int m0, m1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2776 { double ymax;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2777 int err, con[2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2778
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2779 con[0] = con[1] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2780 if ((m0>0) & (m1>0))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2781 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2782 ymax = maxbvgrid(f,x,ll,ur,m0,m1,con);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2783 h[0] = (ur[0]-ll[0])/(2*m0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2784 h[1] = (ur[1]-ll[1])/(2*m1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2785 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2786 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2787 { x[0] = (ll[0]+ur[0])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2788 x[1] = (ll[1]+ur[1])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2789 h[0] = (ur[0]-ll[0])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2790 h[1] = (ur[1]-ll[1])/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2791 ymax = f(x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2792 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2793
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2794 while ((h[0]>tol) | (h[1]>tol))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2795 { /* first, try a quadratric step */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2796 ymax = maxquadstep(f,x,ymax,h,ll,ur,&err,con);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2797 /* if the quadratic step fails, move the grid around */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2798 if (err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2799 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2800 ymax = maxbvstep(f,x,ymax,h,ll,ur,&err,con);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2801 if (err)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2802 { mut_printf("maxbvstep failure\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2803 return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2804 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2805 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2806 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2807
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2808 return(ymax);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2809 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2810 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2811 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2812 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2813 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2814
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2815 prf mut_printf = (prf)printf;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2816
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2817 void mut_redirect(newprf)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2818 prf newprf;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2819 { mut_printf = newprf;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2820 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2821 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2822 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2823 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2824 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2825 * function to find order of observations in an array.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2826 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2827 * mut_order(x,ind,i0,i1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2828 * x array to find order of.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2829 * ind integer array of indexes.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2830 * i0,i1 (integers) range to order.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2831 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2832 * at output, ind[i0...i1] are permuted so that
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2833 * x[ind[i0]] <= x[ind[i0+1]] <= ... <= x[ind[i1]].
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2834 * (with ties, output order of corresponding indices is arbitrary).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2835 * The array x is unchanged.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2836 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2837 * Typically, if x has length n, then i0=0, i1=n-1 and
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2838 * ind is (any permutation of) 0...n-1.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2839 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2840
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2841 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2842
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2843 double med3(x0,x1,x2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2844 double x0, x1, x2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2845 { if (x0<x1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2846 { if (x2<x0) return(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2847 if (x1<x2) return(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2848 return(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2849 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2850 /* x1 < x0 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2851 if (x2<x1) return(x1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2852 if (x0<x2) return(x0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2853 return(x2);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2854 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2855
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2856 void mut_order(x,ind,i0,i1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2857 double *x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2858 int *ind, i0, i1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2859 { double piv;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2860 int i, l, r, z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2861
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2862 if (i1<=i0) return;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2863 piv = med3(x[ind[i0]],x[ind[i1]],x[ind[(i0+i1)/2]]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2864 l = i0; r = i0-1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2865
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2866 /* at each stage,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2867 * x[i0..l-1] < piv
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2868 * x[l..r] = piv
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2869 * x[r+1..i-1] > piv
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2870 * then, decide where to put x[i].
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2871 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2872 for (i=i0; i<=i1; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2873 { if (x[ind[i]]==piv)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2874 { r++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2875 z = ind[i]; ind[i] = ind[r]; ind[r] = z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2876 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2877 else if (x[ind[i]]<piv)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2878 { r++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2879 z = ind[i]; ind[i] = ind[r]; ind[r] = ind[l]; ind[l] = z;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2880 l++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2881 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2882 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2883
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2884 if (l>i0) mut_order(x,ind,i0,l-1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2885 if (r<i1) mut_order(x,ind,r+1,i1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2886 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2887 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2888 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2889 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2890 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2891
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2892 #define LOG_2 0.6931471805599453094172321214581765680755
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2893 #define IBETA_LARGE 1.0e30
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2894 #define IBETA_SMALL 1.0e-30
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2895 #define IGAMMA_LARGE 1.0e30
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2896 #define DOUBLE_EP 2.2204460492503131E-16
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2897
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2898 double ibeta(x, a, b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2899 double x, a, b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2900 { int flipped = 0, i, k, count;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2901 double I = 0, temp, pn[6], ak, bk, next, prev, factor, val;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2902 if (x <= 0) return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2903 if (x >= 1) return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2904 /* use ibeta(x,a,b) = 1-ibeta(1-x,b,z) */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2905 if ((a+b+1)*x > (a+1))
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2906 { flipped = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2907 temp = a;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2908 a = b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2909 b = temp;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2910 x = 1 - x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2911 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2912 pn[0] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2913 pn[2] = pn[3] = pn[1] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2914 count = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2915 val = x/(1.0-x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2916 bk = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2917 next = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2918 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2919 { count++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2920 k = count/2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2921 prev = next;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2922 if (count%2 == 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2923 ak = -((a+k-1.0)*(b-k)*val)/((a+2.0*k-2.0)*(a+2.0*k-1.0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2924 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2925 ak = ((a+b+k-1.0)*k*val)/((a+2.0*k)*(a+2.0*k-1.0));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2926 pn[4] = bk*pn[2] + ak*pn[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2927 pn[5] = bk*pn[3] + ak*pn[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2928 next = pn[4] / pn[5];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2929 for (i=0; i<=3; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2930 pn[i] = pn[i+2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2931 if (fabs(pn[4]) >= IBETA_LARGE)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2932 for (i=0; i<=3; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2933 pn[i] /= IBETA_LARGE;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2934 if (fabs(pn[4]) <= IBETA_SMALL)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2935 for (i=0; i<=3; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2936 pn[i] /= IBETA_SMALL;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2937 } while (fabs(next-prev) > DOUBLE_EP*prev);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2938 /* factor = a*log(x) + (b-1)*log(1-x);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2939 factor -= mut_lgamma(a+1) + mut_lgamma(b) - mut_lgamma(a+b); */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2940 factor = dbeta(x,a,b,1) + log(x/a);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2941 I = exp(factor) * next;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2942 return(flipped ? 1-I : I);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2943 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2944
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2945 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2946 * Incomplete gamma function.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2947 * int_0^x u^{df-1} e^{-u} du / Gamma(df).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2948 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2949 double igamma(x, df)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2950 double x, df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2951 { double factor, term, gintegral, pn[6], rn, ak, bk;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2952 int i, count, k;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2953 if (x <= 0.0) return(0.0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2954
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2955 if (df < 1.0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2956 return( dgamma(x,df+1.0,1.0,0) + igamma(x,df+1.0) );
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2957
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2958 factor = x * dgamma(x,df,1.0,0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2959 /* factor = exp(df*log(x) - x - lgamma(df)); */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2960
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2961 if (x > 1.0 && x >= df)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2962 {
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2963 pn[0] = 0.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2964 pn[2] = pn[1] = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2965 pn[3] = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2966 count = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2967 rn = 1.0 / x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2968 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2969 { count++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2970 k = count / 2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2971 gintegral = rn;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2972 if (count%2 == 0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2973 { bk = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2974 ak = (double)k - df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2975 } else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2976 { bk = x;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2977 ak = (double)k;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2978 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2979 pn[4] = bk*pn[2] + ak*pn[0];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2980 pn[5] = bk*pn[3] + ak*pn[1];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2981 rn = pn[4] / pn[5];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2982 for (i=0; i<4; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2983 pn[i] = pn[i+2];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2984 if (pn[4] > IGAMMA_LARGE)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2985 for (i=0; i<4; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2986 pn[i] /= IGAMMA_LARGE;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2987 } while (fabs(gintegral-rn) > DOUBLE_EP*rn);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2988 gintegral = 1.0 - factor*rn;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2989 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2990 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2991 { /* For x<df, use the series
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2992 * dpois(df,x)*( 1 + x/(df+1) + x^2/((df+1)(df+2)) + ... )
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2993 * This could be slow if df large and x/df is close to 1.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2994 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2995 gintegral = term = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2996 rn = df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2997 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2998 { rn += 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
2999 term *= x/rn;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3000 gintegral += term;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3001 } while (term > DOUBLE_EP*gintegral);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3002 gintegral *= factor/df;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3003 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3004 return(gintegral);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3005 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3006
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3007 double pf(q, df1, df2)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3008 double q, df1, df2;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3009 { return(ibeta(q*df1/(df2+q*df1), df1/2, df2/2));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3010 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3011 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3012 * Copyright 1996-2006 Catherine Loader.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3013 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3014 #include "mut.h"
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3015 #include <string.h>
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3016
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3017 /* quadmin: minimize the quadratic,
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3018 * 2<x,b> + x^T A x.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3019 * x = -A^{-1} b.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3020 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3021 * conquadmin: min. subject to L'x = d (m constraints)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3022 * x = -A^{-1}(b+Ly) (y = Lagrange multiplier)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3023 * y = -(L'A^{-1}L)^{-1} (L'A^{-1}b)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3024 * x = -A^{-1}b + A^{-1}L (L'A^{-1}L)^{-1} [(L'A^{-1})b + d]
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3025 * (non-zero d to be added!!)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3026 *
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3027 * qprogmin: min. subject to L'x >= 0.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3028 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3029
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3030 void quadmin(J,b,p)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3031 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3032 double *b;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3033 int p;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3034 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3035 jacob_dec(J,JAC_CHOL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3036 i = jacob_solve(J,b);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3037 if (i<p) mut_printf("quadmin singular %2d %2d\n",i,p);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3038 for (i=0; i<p; i++) b[i] = -b[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3039 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3040
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3041 /* project vector a (length n) onto
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3042 * columns of X (n rows, m columns, organized by column).
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3043 * store result in y.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3044 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3045 #define pmaxm 10
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3046 #define pmaxn 100
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3047 void project(a,X,y,n,m)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3048 double *a, *X, *y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3049 int n, m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3050 { double xta[pmaxm], R[pmaxn*pmaxm];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3051 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3052
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3053 if (n>pmaxn) mut_printf("project: n too large\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3054 if (m>pmaxm) mut_printf("project: m too large\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3055
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3056 for (i=0; i<m; i++) xta[i] = innerprod(a,&X[i*n],n);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3057 memcpy(R,X,m*n*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3058 qr(R,n,m,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3059 qrsolv(R,xta,n,m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3060
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3061 matrixmultiply(X,xta,y,n,m,1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3062 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3063
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3064 void resproj(a,X,y,n,m)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3065 double *a, *X, *y;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3066 int n, m;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3067 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3068 project(a,X,y,n,m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3069 for (i=0; i<n; i++) y[i] = a[i]-y[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3070 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3071
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3072 /* x = -A^{-1}b + A^{-1}L (L'A^{-1}L)^{-1} [(L'A^{-1})b + d] */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3073 void conquadmin(J,b,n,L,d,m)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3074 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3075 double *b, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3076 int m, n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3077 { double bp[10], L0[100];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3078 int i, j;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3079
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3080 if (n>10) mut_printf("conquadmin: max. n is 10.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3081 memcpy(L0,L,n*m*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3082 jacob_dec(J,JAC_CHOL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3083 for (i=0; i<m; i++) jacob_hsolve(J,&L[i*n]);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3084 jacob_hsolve(J,b);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3085
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3086 resproj(b,L,bp,n,m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3087
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3088 jacob_isolve(J,bp);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3089 for (i=0; i<n; i++) b[i] = -bp[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3090
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3091 qr(L,n,m,NULL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3092 qrsolv(L,d,n,m);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3093 for (i=0; i<n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3094 { bp[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3095 for (j=0; j<m; j++) bp[i] += L0[j*n+i]*d[j];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3096 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3097 jacob_solve(J,bp);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3098 for (i=0; i<n; i++) b[i] += bp[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3099 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3100
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3101 void qactivemin(J,b,n,L,d,m,ac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3102 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3103 double *b, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3104 int m, n, *ac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3105 { int i, nac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3106 double M[100], dd[10];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3107 nac = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3108 for (i=0; i<m; i++) if (ac[i]>0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3109 { memcpy(&M[nac*n],&L[i*n],n*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3110 dd[nac] = d[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3111 nac++;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3112 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3113 conquadmin(J,b,n,M,dd,nac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3114 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3115
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3116 /* return 1 for full step; 0 if new constraint imposed. */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3117 int movefrom(x0,x,n,L,d,m,ac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3118 double *x0, *x, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3119 int n, m, *ac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3120 { int i, imin;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3121 double c0, c1, lb, lmin;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3122 lmin = 1.0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3123 for (i=0; i<m; i++) if (ac[i]==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3124 { c1 = innerprod(&L[i*n],x,n)-d[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3125 if (c1<0.0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3126 { c0 = innerprod(&L[i*n],x0,n)-d[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3127 if (c0<0.0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3128 { if (c1<c0) { lmin = 0.0; imin = 1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3129 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3130 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3131 { lb = c0/(c0-c1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3132 if (lb<lmin) { lmin = lb; imin = i; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3133 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3134 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3135 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3136 for (i=0; i<n; i++)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3137 x0[i] = lmin*x[i]+(1-lmin)*x0[i];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3138 if (lmin==1.0) return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3139 ac[imin] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3140 return(0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3141 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3142
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3143 int qstep(J,b,x0,n,L,d,m,ac,deac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3144 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3145 double *b, *x0, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3146 int m, n, *ac, deac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3147 { double x[10];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3148 int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3149
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3150 if (m>10) mut_printf("qstep: too many constraints.\n");
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3151 if (deac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3152 { for (i=0; i<m; i++) if (ac[i]==1)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3153 { ac[i] = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3154 memcpy(x,b,n*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3155 qactivemin(J,x,n,L,d,m,ac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3156 if (innerprod(&L[i*n],x,n)>d[i]) /* deactivate this constraint; should rem. */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3157 i = m+10;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3158 else
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3159 ac[i] = 1;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3160 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3161 if (i==m) return(0); /* no deactivation possible */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3162 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3163
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3164 do
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3165 { if (!deac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3166 { memcpy(x,b,n*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3167 qactivemin(J,x,n,L,d,m,ac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3168 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3169 i = movefrom(x0,x,n,L,d,m,ac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3170
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3171 deac = 0;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3172 } while (i==0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3173 return(1);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3174 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3175
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3176 /*
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3177 * x0 is starting value; should satisfy constraints.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3178 * L is n*m constraint matrix.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3179 * ac is active constraint vector:
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3180 * ac[i]=0, inactive.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3181 * ac[i]=1, active, but can be deactivated.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3182 * ac[i]=2, active, cannot be deactivated.
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3183 */
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3184
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3185 void qprogmin(J,b,x0,n,L,d,m,ac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3186 jacobian *J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3187 double *b, *x0, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3188 int m, n, *ac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3189 { int i;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3190 for (i=0; i<m; i++) if (ac[i]==0)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3191 { if (innerprod(&L[i*n],x0,n) < d[i]) ac[i] = 1; }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3192 jacob_dec(J,JAC_CHOL);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3193 qstep(J,b,x0,n,L,d,m,ac,0);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3194 while (qstep(J,b,x0,n,L,d,m,ac,1));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3195 }
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3196
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3197 void qpm(A,b,x0,n,L,d,m,ac)
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3198 double *A, *b, *x0, *L, *d;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3199 int *n, *m, *ac;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3200 { jacobian J;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3201 double wk[1000];
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3202 jac_alloc(&J,*n,wk);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3203 memcpy(J.Z,A,(*n)*(*n)*sizeof(double));
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3204 J.p = *n;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3205 J.st = JAC_RAW;
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3206 qprogmin(&J,b,x0,*n,L,d,*m,ac);
0f80a5141704 version 0.3 uploaded
vipints
parents:
diff changeset
3207 }