1 using System.Threading;
\r
10 internal static class CONST
\r
12 public static readonly uint MAX_ARG = 5;
\r
16 static public class Constants
\r
18 public static readonly int LIMIT = 5;
\r
19 public delegate double Func0(double x);
\r
20 public delegate double Func1(double x, double a);
\r
21 public delegate double Func2(double x, double a, double b);
\r
22 public delegate double Func3(double x, double a, double b, double c);
\r
23 public delegate double Func4(double x, double a, double b, double c, double d);
\r
24 public delegate double Func5(double x, double a, double b, double c, double d, double e);
\r
28 static public class Binomial
\r
30 public static double factorial(int fact)
\r
33 for (int i = 1; i <= fact; i++)
\r
39 public static double combination(int nn, int kk)
\r
41 //return (double)(Int64)(factorial(n) / (factorial(kk) * factorial(n - kk)));
\r
42 BigInt n = new BigInt((Int64)nn, new PrecisionSpec());
\r
43 BigInt k = new BigInt((Int64)kk, new PrecisionSpec());
\r
48 return (double)(Int64)(n / (k * n_k) );
\r
50 public static double likelihood(double pp, int yes, int no)
\r
53 if (pp < 0) p = 0; else if (pp > 1) p = 1; else p = pp;
\r
54 return combination(yes + no, yes) * System.Math.Pow(p, yes) * System.Math.Pow(1 - p, no);
\r
57 public static double likelihood(double pp, int yes, int no, double comb)
\r
60 if (pp < 0) p = 0; else if (pp > 1) p = 1; else p = pp;
\r
61 return comb * System.Math.Pow(p, yes) * System.Math.Pow(1 - p, no);
\r
67 public class BernoulliProcess
\r
72 public int pos, neg, comb;
\r
73 public void set(double cond, int posit, int negat)
\r
81 public Data[] elems;
\r
83 public void set(double[][] num)
\r
85 elems = new Data[num.GetLength(0)];
\r
86 for (int i = 0; i < elems.GetLength(0); i++)
\r
88 elems[i].set(num[i][0], (int)num[i][1], (int)num[i][2]);
\r
95 class BinomialLikelihoodThread
\r
97 public bool finished;
\r
98 public static bool started;
\r
100 public static BinomialLikelihoodThread current;
\r
102 public Interval[] itvl;
\r
103 public double[] step;
\r
104 public double[] champ;
\r
105 public double champ_like;
\r
106 public BernoulliProcess data;
\r
109 public Constants.Func0 func0;
\r
110 public Constants.Func1 func1;
\r
111 public Constants.Func2 func2;
\r
112 public Constants.Func3 func3;
\r
113 public Constants.Func4 func4;
\r
114 public Constants.Func5 func5;
\r
117 public BinomialLikelihoodThread()
\r
119 itvl = new Interval[CONST.MAX_ARG];
\r
120 step = new double[CONST.MAX_ARG];
\r
121 champ = new double[CONST.MAX_ARG];
\r
122 data = new BernoulliProcess();
\r
124 public void waitLoop()
\r
127 for(int i=0; i<10; i++) {
\r
134 public void loop1() { waitLoop(); th = new Thread(new ThreadStart(loop1_)); }
\r
135 public void loop2() { waitLoop(); th = new Thread(new ThreadStart(loop2_)); }
\r
136 public void loop3() { waitLoop(); th = new Thread(new ThreadStart(loop3_)); }
\r
137 public void loop4() { waitLoop(); th = new Thread(new ThreadStart(loop4_)); }
\r
138 public void loop5() { waitLoop(); th = new Thread(new ThreadStart(loop5_)); }
\r
145 int L = data.length;
\r
146 for (double a = itvl[0].begin.val; a < itvl[0].end.val; a += step[0])
\r
149 for(int i=0; i<L; i++) {
\r
150 p = func1(data.elems[i].x, a);
\r
151 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
153 if(like > champ_like) {
\r
166 int L = data.length;
\r
167 for (double a = itvl[0].begin.val; a < itvl[0].end.val; a += step[0])
\r
169 for (double b = itvl[1].begin.val; b < itvl[1].end.val; b += step[1])
\r
172 for (int i = 0; i < L; i++)
\r
174 p = func2(data.elems[i].x, a, b);
\r
175 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
177 if (like > champ_like)
\r
192 int L = data.length;
\r
193 for (double a = itvl[0].begin.val; a < itvl[0].end.val; a += step[0])
\r
195 for (double b = itvl[1].begin.val; b < itvl[1].end.val; b += step[1])
\r
197 for (double c = itvl[2].begin.val; c < itvl[2].end.val; c += step[2])
\r
200 for (int i = 0; i < L; i++)
\r
202 p = func3(data.elems[i].x, a, b, c);
\r
203 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
205 if (like > champ_like)
\r
229 class BinomialLikelihood
\r
231 public int iteration;
\r
233 public Interval[] itvl;
\r
234 public double[] step;
\r
235 public double[] champ;
\r
236 public double champ_like;
\r
237 public BernoulliProcess data;
\r
239 public Constants.Func0 func0;
\r
240 public Constants.Func1 func1;
\r
241 public Constants.Func2 func2;
\r
242 public Constants.Func3 func3;
\r
243 public Constants.Func4 func4;
\r
244 public Constants.Func5 func5;
\r
246 public BinomialLikelihood()
\r
248 itvl = new Interval[CONST.MAX_ARG];
\r
249 step = new double[CONST.MAX_ARG];
\r
250 champ = new double[CONST.MAX_ARG];
\r
254 public void begin(Constants.Func0 d_func)
\r
256 public void begin(Constants.Func1 d_func)
\r
260 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
262 for (int k = 0; k < iteration; k++)
\r
265 for (int i = 0; i < 4; i++)
\r
268 l[i].func1 = d_func;
\r
274 public void begin(Constants.Func2 d_func)
\r
278 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
280 for (int k = 0; k < iteration; k++)
\r
283 for (int i = 0; i < 4; i++)
\r
286 l[i].func2 = d_func;
\r
292 public void begin(Constants.Func3 d_func)
\r
296 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
298 for (int k = 0; k < iteration; k++)
\r
301 for(int i=0; i<4; i++) {
\r
303 l[i].func3 = d_func;
\r
310 public void begin(Constants.Func4 d_func)
\r
313 public void begin(Constants.Func5 d_func)
\r
317 void begin_base(BinomialLikelihoodThread[] l)
\r
321 data.length = data.elems.GetLength(0);
\r
322 for (int i = 0; i < data.elems.GetLength(0); i++)
\r
324 data.elems[i].comb = (int)Binomial.combination(data.elems[i].pos + data.elems[i].neg, data.elems[i].pos);
\r
327 for (int j = 0; j < Constants.LIMIT; j++) { step[j] = (itvl[j].end.val - itvl[j].begin.val) / 256.0; }
\r
328 for (int i = 0; i < 4; i++)
\r
330 l[i].itvl[0] = new Interval((itvl[0].begin.val) + (i * step[0] * 64), (itvl[0].begin.val) + ((i + 1) * step[0] * 64));
\r
331 l[i].step[0] = step[0];
\r
332 for (int j = 1; j < Constants.LIMIT; j++)
\r
334 l[i].itvl[j] = itvl[j];
\r
335 l[i].step[j] = step[j];
\r
341 void end_base(BinomialLikelihoodThread[] l)
\r
343 for (int i = 0; i < 4; i++)
\r
348 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = 0; }
\r
349 for(int i=0; i<4; i++) {
\r
350 if(champ_like < l[i].champ_like) {
\r
351 champ_like = l[i].champ_like;
\r
352 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = l[i].champ[j]; }
\r
356 double r, low, high;
\r
357 for (int j = 0; j < Constants.LIMIT; j++)
\r
359 r = itvl[j].end.val - itvl[j].begin.val;
\r
360 low = champ[j] - r / 8.0 < itvl[j].begin.val ? itvl[j].begin.val : champ[j] - r / 8.0;
\r
361 high = champ[j] + r / 8.0 > itvl[j].end.val ? itvl[j].end.val : champ[j] + r / 8.0;
\r
362 itvl[j] = new Interval(low, high);
\r