OSDN Git Service

323
[psychlops/silverlight.git] / dev4 / psychlops / extention / math / solver.cs
1 using System.Threading;\r
2 using System;\r
3 using BigNum;\r
4 \r
5 namespace Psychlops\r
6 {\r
7 \r
8         namespace Solver\r
9         {\r
10                 internal static class CONST\r
11                 {\r
12                         public static readonly uint MAX_ARG = 5;\r
13                 }\r
14 \r
15                 \r
16                 static public class Constants\r
17                 {\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
25                 }\r
26 \r
27 \r
28                 static public class Binomial\r
29                 {\r
30                         public static double factorial(int fact)\r
31                         {\r
32                                 double x = 1;\r
33                                 for (int i = 1; i <= fact; i++)\r
34                                 {\r
35                                         x *= i;\r
36                                 }\r
37                                 return x;\r
38                         }\r
39                         public static double combination(int nn, int kk)\r
40                         {\r
41                                 return (double)(Int64)(factorial(nn) / (factorial(kk) * factorial(nn - kk)));\r
42                                 /*\r
43                                 BigInt n = new BigInt((Int64)nn, new PrecisionSpec());\r
44                                 BigInt k = new BigInt((Int64)kk, new PrecisionSpec());\r
45                                 BigInt n_k = n - k;\r
46                                 n.Factorial();\r
47                                 k.Factorial();\r
48                                 n_k.Factorial();\r
49                                 return (double)(Int64)(n / (k * n_k) );\r
50                                  * */\r
51                         }\r
52                         public static double likelihood(double pp, int yes, int no)\r
53                         {\r
54                                 double p;\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
57                         }\r
58 \r
59                         public static double likelihood(double pp, int yes, int no, double comb)\r
60                         {\r
61                                 double p;\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
64                         }\r
65 \r
66                 }\r
67 \r
68 \r
69                 public class BernoulliProcess\r
70                 {\r
71                         public struct Data\r
72                         {\r
73                                 public double x;\r
74                                 public int pos, neg, comb;\r
75                                 public void set(double cond, int posit, int negat)\r
76                                 {\r
77                                         x = cond;\r
78                                         pos = posit;\r
79                                         neg = negat;\r
80                                 }\r
81 \r
82                         };\r
83                         public Data[] elems;\r
84                         public int length;\r
85                         public void set(double[][] num)\r
86                         {\r
87                                 elems = new Data[num.GetLength(0)];\r
88                                 for (int i = 0; i < elems.GetLength(0); i++)\r
89                                 {\r
90                                         elems[i].set(num[i][0], (int)num[i][1], (int)num[i][2]);\r
91                                 }\r
92                         }\r
93                 };\r
94 \r
95 \r
96 \r
97                 class BinomialLikelihoodThread\r
98                 {\r
99                         public bool finished;\r
100                         public static bool started;\r
101                         internal Thread th;\r
102                         public static BinomialLikelihoodThread current;\r
103 \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
109 \r
110 \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
117 \r
118 \r
119                         public BinomialLikelihoodThread()\r
120                         {\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
125                         }\r
126                         public void waitLoop()\r
127                         {\r
128                                 finished = false;\r
129                                 for (int i = 0; i < CONST.MAX_ARG; i++)\r
130                                 {\r
131                                         champ[i] = 0;\r
132                                 }\r
133                                 current = this;\r
134                                 started = false;\r
135                         }\r
136 \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
142                         void loop1_()\r
143                         {\r
144                                 started = true;\r
145                                 double p;\r
146                                 double like = 1.0;\r
147                                 champ_like=0.0;\r
148                                 int L = data.length;\r
149                                 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])\r
150                                 {\r
151                                         like = 1.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
155                                         }\r
156                                         if(like > champ_like) {\r
157                                                 champ_like = like;\r
158                                                 champ[0] = a;\r
159                                         }\r
160                                 }\r
161                                 finished = true;\r
162                         }\r
163                         void loop2_()\r
164                         {\r
165                                 started = true;\r
166                                 double p = 0.0;\r
167                                 double like = 1.0;\r
168                                 champ_like = 0.0;\r
169                                 int L = data.length;\r
170                                 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])\r
171                                 {\r
172                                         for (double b = itvl[1].begin.value; b < itvl[1].end.value; b += step[1])\r
173                                         {\r
174                                                 like = 1.0;\r
175                                                 for (int i = 0; i < L; i++)\r
176                                                 {\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
179                                                 }\r
180                                                 if (like > champ_like)\r
181                                                 {\r
182                                                         champ_like = like;\r
183                                                         champ[0] = a;\r
184                                                         champ[1] = b;\r
185                                                 }\r
186                                         }\r
187                                 }\r
188                                 finished = true;\r
189                         }\r
190                         void loop3_()\r
191                         {\r
192                                 started = true;\r
193                                 double p;\r
194                                 double like = 1.0;\r
195                                 champ_like = 0.0;\r
196                                 int L = data.length;\r
197                                 for (double a = itvl[0].begin.value; a < itvl[0].end.value; a += step[0])\r
198                                 {\r
199                                         for (double b = itvl[1].begin.value; b < itvl[1].end.value; b += step[1])\r
200                                         {\r
201                                                 for (double c = itvl[2].begin.value; c < itvl[2].end.value; c += step[2])\r
202                                                 {\r
203                                                         like = 1.0;\r
204                                                         for (int i = 0; i < L; i++)\r
205                                                         {\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
208                                                         }\r
209                                                         if (like > champ_like)\r
210                                                         {\r
211                                                                 champ_like = like;\r
212                                                                 champ[0] = a;\r
213                                                                 champ[1] = b;\r
214                                                                 champ[1] = c;\r
215                                                         }\r
216                                                 }\r
217                                         }\r
218                                 }\r
219                                 finished = true;\r
220                         }\r
221                         void loop4_()\r
222                         {\r
223                                 started = true;\r
224                                 finished = true;\r
225                         }\r
226                         void loop5_()\r
227                         {\r
228                                 started = true;\r
229                                 finished = true;\r
230                         }\r
231                 };\r
232 \r
233 \r
234 \r
235                 public class BinomialLikelihood\r
236                 {\r
237                         public static void showWindow(Constants.Func1 f)\r
238                         {\r
239                                 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func1>(showWindow_), f);\r
240                         }\r
241                         internal static void showWindow_(Constants.Func1 f)\r
242                         {\r
243                                 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);\r
244                                 page.Show();\r
245                         }\r
246                         public static void showWindow(Constants.Func2 f)\r
247                         {\r
248                                 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func2>(showWindow_), f);\r
249                         }\r
250                         internal static void showWindow_(Constants.Func2 f)\r
251                         {\r
252                                 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);\r
253                                 page.Show();\r
254                         }\r
255                         public static void showWindow(Constants.Func3 f)\r
256                         {\r
257                                 Main.canvas.api_canvas.Dispatcher.BeginInvoke(new Action<Constants.Func3>(showWindow_), f);\r
258                         }\r
259                         internal static void showWindow_(Constants.Func3 f)\r
260                         {\r
261                                 System.Windows.Controls.ChildWindow page = new PsychlopsSilverlight4.Pages.BinomialSolver(f);\r
262                                 page.Show();\r
263                         }\r
264 \r
265                         public int iteration;\r
266 \r
267                         public Interval[] itvl;\r
268                         public double[] step;\r
269                         public double[] champ;\r
270                         public double champ_like;\r
271                         public BernoulliProcess data;\r
272 \r
273                         public Constants.Func0 func0;\r
274                         public Constants.Func1 func1;\r
275                         public Constants.Func2 func2;\r
276                         public Constants.Func3 func3;\r
277                         public Constants.Func4 func4;\r
278                         public Constants.Func5 func5;\r
279 \r
280                         public BinomialLikelihood()\r
281                         {\r
282                                 itvl = new Interval[CONST.MAX_ARG];\r
283                                 step = new double[CONST.MAX_ARG];\r
284                                 champ = new double[CONST.MAX_ARG];\r
285                                 iteration = 2;\r
286                         }\r
287 \r
288                         public void begin(Constants.Func0 d_func)\r
289                         { }\r
290                         public void begin(Constants.Func1 d_func)\r
291                         {\r
292                                 func1 = d_func;\r
293 \r
294                                 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];\r
295                                 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }\r
296 \r
297                                 for (int k = 0; k < iteration; k++)\r
298                                 {\r
299                                         begin_base(l);\r
300                                         for (int i = 0; i < 4; i++)\r
301                                         {\r
302                                                 l[i].data = data;\r
303                                                 l[i].func1 = d_func;\r
304                                                 l[i].loop1();\r
305                                         }\r
306                                         end_base(l);\r
307                                 }\r
308                         }\r
309                         public void begin(Constants.Func2 d_func)\r
310                         {\r
311                                 func2 = d_func;\r
312 \r
313                                 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];\r
314                                 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }\r
315 \r
316                                 for (int k = 0; k < iteration; k++)\r
317                                 {\r
318                                         begin_base(l);\r
319                                         for (int i = 0; i < 4; i++)\r
320                                         {\r
321                                                 l[i].data = data;\r
322                                                 l[i].func2 = d_func;\r
323                                                 l[i].loop2();\r
324                                         }\r
325                                         end_base(l);\r
326                                 }\r
327                         }\r
328                         public void begin(Constants.Func3 d_func)\r
329                         {\r
330                                 func3 = d_func;\r
331 \r
332                                 BinomialLikelihoodThread[] l = new BinomialLikelihoodThread[4];\r
333                                 for (int i = 0; i < 4; i++) { l[i] = new BinomialLikelihoodThread(); }\r
334 \r
335                                 for (int k = 0; k < iteration; k++)\r
336                                 {\r
337                                         begin_base(l);\r
338                                         for(int i=0; i<4; i++) {\r
339                                                 l[i].data = data;\r
340                                                 l[i].func3 = d_func;\r
341                                                 l[i].loop3();\r
342                                         }\r
343                                         end_base(l);\r
344                                 }\r
345                         }\r
346 \r
347                         public void begin(Constants.Func4 d_func)\r
348                         {\r
349                         }\r
350                         public void begin(Constants.Func5 d_func)\r
351                         {\r
352                         }\r
353 \r
354                         void begin_base(BinomialLikelihoodThread[] l)\r
355                         {\r
356                                 champ_like = 0;\r
357 \r
358                                 data.length = data.elems.GetLength(0);\r
359                                 for (int i = 0; i < data.elems.GetLength(0); i++)\r
360                                 {\r
361                                         data.elems[i].comb = (int)Binomial.combination(data.elems[i].pos + data.elems[i].neg, data.elems[i].pos);\r
362                                 }\r
363 \r
364                                 for (int j = 0; j < Constants.LIMIT; j++) { step[j] = (itvl[j].end.value - itvl[j].begin.value) / 256.0; }\r
365                                 for (int i = 0; i < 4; i++)\r
366                                 {\r
367                                         l[i].itvl[0] = new Interval((itvl[0].begin.value) + (i * step[0] * 64), (itvl[0].begin.value) + ((i + 1) * step[0] * 64));\r
368                                         l[i].step[0] = step[0];\r
369                                         for (int j = 1; j < Constants.LIMIT; j++)\r
370                                         {\r
371                                                 l[i].itvl[j] = itvl[j];\r
372                                                 l[i].step[j] = step[j];\r
373                                         }\r
374                                         l[i].data = data;\r
375                                 }\r
376                         }\r
377 \r
378                         void end_base(BinomialLikelihoodThread[] l)\r
379                         {\r
380                                 //for (int i = 0; i < 4; i++) { l[i].th.Join(); }\r
381                                 while (!l[0].finished || !l[1].finished || !l[2].finished || !l[3].finished) { Thread.Sleep(100);  } \r
382 \r
383                                 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = 0; }\r
384                                 champ_like = 0.0;\r
385                                 for(int i=0; i<4; i++) {\r
386                                         if(champ_like < l[i].champ_like) {\r
387                                                 champ_like = l[i].champ_like;\r
388                                                 for(int j=0; j<Constants.LIMIT; j++) { champ[j] = l[i].champ[j]; }\r
389                                         }\r
390                                 }\r
391 \r
392                                 double r, low, high;\r
393                                 for (int j = 0; j < Constants.LIMIT; j++)\r
394                                 {\r
395                                         r = itvl[j].end.value - itvl[j].begin.value;\r
396                                         low = champ[j] - r / 8.0 < itvl[j].begin.value ? itvl[j].begin.value : champ[j] - r / 8.0;\r
397                                         high = champ[j] + r / 8.0 > itvl[j].end.value ? itvl[j].end.value : champ[j] + r / 8.0;\r
398                                         itvl[j] = new Interval(low, high);\r
399                                 }\r
400 \r
401                         }\r
402 \r
403 \r
404                 }\r
405 \r
406 \r
407         }\r
408 \r
409 }