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(nn) / (factorial(kk) * factorial(nn - kk)));
\r
43 BigInt n = new BigInt((Int64)nn, new PrecisionSpec());
\r
44 BigInt k = new BigInt((Int64)kk, new PrecisionSpec());
\r
49 return (double)(Int64)(n / (k * n_k) );
\r
52 public static double likelihood(double pp, int yes, int no)
\r
55 if (pp < 0) p = 0; else if (pp > 1) p = 1; else p = pp;
\r
56 return combination(yes + no, yes) * System.Math.Pow(p, yes) * System.Math.Pow(1 - p, no);
\r
59 public static double likelihood(double pp, int yes, int no, double comb)
\r
62 if (pp < 0) p = 0; else if (pp > 1) p = 1; else p = pp;
\r
63 return comb * System.Math.Pow(p, yes) * System.Math.Pow(1 - p, no);
\r
69 public class BernoulliProcess
\r
74 public int pos, neg, comb;
\r
75 public void set(double cond, int posit, int negat)
\r
83 public Data[] elems;
\r
85 public void set(double[][] num)
\r
87 elems = new Data[num.GetLength(0)];
\r
88 for (int i = 0; i < elems.GetLength(0); i++)
\r
90 elems[i].set(num[i][0], (int)num[i][1], (int)num[i][2]);
\r
97 class BinomialLikelihoodThread
\r
99 public bool finished;
\r
100 public static bool started;
\r
101 internal Thread th;
\r
102 public static BinomialLikelihoodThread current;
\r
104 public Interval[] itvl;
\r
105 public double[] step;
\r
106 public double[] champ;
\r
107 public double champ_like;
\r
108 public BernoulliProcess data;
\r
111 public Constants.Func0 func0;
\r
112 public Constants.Func1 func1;
\r
113 public Constants.Func2 func2;
\r
114 public Constants.Func3 func3;
\r
115 public Constants.Func4 func4;
\r
116 public Constants.Func5 func5;
\r
119 public BinomialLikelihoodThread()
\r
121 itvl = new Interval[CONST.MAX_ARG];
\r
122 step = new double[CONST.MAX_ARG];
\r
123 champ = new double[CONST.MAX_ARG];
\r
124 data = new BernoulliProcess();
\r
126 public void waitLoop()
\r
129 for (int i = 0; i < CONST.MAX_ARG; i++)
\r
137 public void loop1() { waitLoop(); th = new Thread(new ThreadStart(loop1_)); th.Start(); }
\r
138 public void loop2() { waitLoop(); th = new Thread(new ThreadStart(loop2_)); th.Start(); }
\r
139 public void loop3() { waitLoop(); th = new Thread(new ThreadStart(loop3_)); th.Start(); }
\r
140 public void loop4() { waitLoop(); th = new Thread(new ThreadStart(loop4_)); th.Start(); }
\r
141 public void loop5() { waitLoop(); th = new Thread(new ThreadStart(loop5_)); th.Start(); }
\r
148 int L = data.length;
\r
149 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])
\r
152 for(int i=0; i<L; i++) {
\r
153 p = func1(data.elems[i].x, a);
\r
154 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
156 if(like > champ_like) {
\r
169 int L = data.length;
\r
170 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])
\r
172 for (double b = itvl[1].begin.value; b < itvl[1].end.value; b += step[1])
\r
175 for (int i = 0; i < L; i++)
\r
177 p = func2(data.elems[i].x, a, b);
\r
178 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
180 if (like > champ_like)
\r
196 int L = data.length;
\r
197 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])
\r
199 for (double b = itvl[1].begin.value; b < itvl[1].end.value; b += step[1])
\r
201 for (double c = itvl[2].begin.value; c < itvl[2].end.value; c += step[2])
\r
204 for (int i = 0; i < L; i++)
\r
206 p = func3(data.elems[i].x, a, b, c);
\r
207 like *= Binomial.likelihood(p, data.elems[i].pos, data.elems[i].neg, data.elems[i].comb);
\r
209 if (like > champ_like)
\r
235 public class BinomialLikelihood
\r
238 public static void showWindow(Constants.Func1 f)
\r
240 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func1>(showWindow_), f);
\r
242 internal static void showWindow_(Constants.Func1 f)
\r
244 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);
\r
247 public static void showWindow(Constants.Func2 f)
\r
249 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func2>(showWindow_), f);
\r
251 internal static void showWindow_(Constants.Func2 f)
\r
253 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);
\r
256 public static void showWindow(Constants.Func3 f)
\r
258 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func3>(showWindow_), f);
\r
260 internal static void showWindow_(Constants.Func3 f)
\r
262 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);
\r
267 public int iteration;
\r
269 public Interval[] itvl;
\r
270 public double[] step;
\r
271 public double[] champ;
\r
272 public double champ_like;
\r
273 public BernoulliProcess data;
\r
275 public Constants.Func0 func0;
\r
276 public Constants.Func1 func1;
\r
277 public Constants.Func2 func2;
\r
278 public Constants.Func3 func3;
\r
279 public Constants.Func4 func4;
\r
280 public Constants.Func5 func5;
\r
282 public BinomialLikelihood()
\r
284 itvl = new Interval[CONST.MAX_ARG];
\r
285 step = new double[CONST.MAX_ARG];
\r
286 champ = new double[CONST.MAX_ARG];
\r
290 public void begin(Constants.Func0 d_func)
\r
292 public void begin(Constants.Func1 d_func)
\r
296 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
297 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }
\r
299 for (int k = 0; k < iteration; k++)
\r
302 for (int i = 0; i < 4; i++)
\r
305 l[i].func1 = d_func;
\r
311 public void begin(Constants.Func2 d_func)
\r
315 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
316 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }
\r
318 for (int k = 0; k < iteration; k++)
\r
321 for (int i = 0; i < 4; i++)
\r
324 l[i].func2 = d_func;
\r
330 public void begin(Constants.Func3 d_func)
\r
334 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];
\r
335 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }
\r
337 for (int k = 0; k < iteration; k++)
\r
340 for(int i=0; i<4; i++) {
\r
342 l[i].func3 = d_func;
\r
349 public void begin(Constants.Func4 d_func)
\r
352 public void begin(Constants.Func5 d_func)
\r
356 void begin_base(BinomialLikelihoodThread[] l)
\r
360 data.length = data.elems.GetLength(0);
\r
361 for (int i = 0; i < data.elems.GetLength(0); i++)
\r
363 data.elems[i].comb = (int)Binomial.combination(data.elems[i].pos + data.elems[i].neg, data.elems[i].pos);
\r
366 for (int j = 0; j < Constants.LIMIT; j++) { step[j] = (itvl[j].end.value - itvl[j].begin.value) / 256.0; }
\r
367 for (int i = 0; i < 4; i++)
\r
369 l[i].itvl[0] = new Interval((itvl[0].begin.value) + (i * step[0] * 64), (itvl[0].begin.value) + ((i + 1) * step[0] * 64));
\r
370 l[i].step[0] = step[0];
\r
371 for (int j = 1; j < Constants.LIMIT; j++)
\r
373 l[i].itvl[j] = itvl[j];
\r
374 l[i].step[j] = step[j];
\r
380 void end_base(BinomialLikelihoodThread[] l)
\r
382 //for (int i = 0; i < 4; i++) { l[i].th.Join(); }
\r
383 while (!l[0].finished || !l[1].finished || !l[2].finished || !l[3].finished) { Thread.Sleep(100); }
\r
385 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = 0; }
\r
387 for(int i=0; i<4; i++) {
\r
388 if(champ_like < l[i].champ_like) {
\r
389 champ_like = l[i].champ_like;
\r
390 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = l[i].champ[j]; }
\r
394 double r, low, high;
\r
395 for (int j = 0; j < Constants.LIMIT; j++)
\r
397 r = itvl[j].end.value - itvl[j].begin.value;
\r
398 low = champ[j] - r / 8.0 < itvl[j].begin.value ? itvl[j].begin.value : champ[j] - r / 8.0;
\r
399 high = champ[j] + r / 8.0 > itvl[j].end.value ? itvl[j].end.value : champ[j] + r / 8.0;
\r
400 itvl[j] = new Interval(low, high);
\r