1 module des.mc.calibrate.util;
2 
3 public import des.math.linear;
4 
5 /+ expected value: мат. ожидание +/
6 @property fSeg expected( in fSeg[] buf )
7 {
8     fSeg mm;
9     foreach( r; buf ) mm += r;
10     return mm / cast(float)buf.length;
11 }
12 unittest
13 {
14     auto r1 = fSeg( vec3(1,2,3), vec3(2,3,4) );
15     auto r2 = fSeg( vec3(4,5,6), vec3(5,2,3) );
16     auto r3 = fSeg( vec3(2,3,4), vec3(1,2,3) );
17     auto re = ( r1 + r2 + r3 ) / 3.0f;
18     assert( [r1,r2,r3].expected == re );
19 }
20 
21 /+ variance: дисперсия +/
22 @property fSeg variance( in fSeg[] buf, in fSeg exp )
23 {
24     vec3 Ds;
25     vec3 De;
26     foreach( r; buf )
27     {
28         Ds += (r.start - exp.start) ^^ 2;
29         De += (r.dir - exp.dir) ^^ 2;
30     }
31     float lm1 = buf.length - 1;
32     return fSeg( Ds / lm1 , De / lm1 );
33 }
34 
35 fSeg approxIntersection( in fSeg s1, in fSeg s2 )
36 { return s1.altitude( s2 ); }
37 
38 unittest
39 {
40     auto r1 = fSeg( vec3(0,0,.1), vec3(1,1,0) );
41     auto r2 = fSeg( vec3(4,0,-0.1), vec3(-4,4,0) );
42     auto res = approxIntersection( r1, r2 );
43     auto ctr = res.start + res.dir/2;
44     assert( ctr == vec3( 2, 2, 0 ) );
45 }
46 
47 unittest
48 {
49     auto r1 = fSeg( vec3(0,0,0), vec3(1,1,0) );
50     auto r2 = fSeg( vec3(1,0,-1), vec3(-4,4,0) );
51     auto res = approxIntersection( r1, r2 );
52     auto ctr = res.start + res.dir/2;
53     assert( ctr == vec3( 0.5, 0.5, -.5 ) );
54 }
55 
56 version(unittest)
57 {
58     private import des.math.method.stat.randn;
59     private auto v = [ 
60         -0.779237,  0.095773,  0.794196,  0.037817,  0.243846, -0.610992,  
61          0.894963,  0.760108,  0.456166,  0.091022,  0.544440, -0.104452,  
62          0.602444,  0.622659,  0.310276, -0.838316, -0.174904,  0.720212, 
63         -0.587296, -0.140814,  0.752186, -0.679231,  0.108245, -0.476829, 
64         -0.149560,  0.488450, -0.338691, -0.337862,  0.182438,  0.430244, 
65         -0.246279, -0.489203, -0.204999,  0.804444, -0.903342, -0.842680,  
66          0.638648,  0.392753, -0.150701, -0.259307, -0.471528, -0.927970, 
67          0.053038,  0.866550, -0.262863, -0.015059,  0.797605, -0.378268, 
68         -0.768152, -0.966215,  0.358892, -0.506356, -0.174640,  0.744792,  
69          0.136404,  0.877210, -0.148166, -0.737943, -0.677909,  0.407338,  
70          0.940582, -0.825226, -0.435503,  0.965236,  0.129071,  0.185805, 
71         -0.323059, -0.055682, -0.077424,  0.583382, -0.000693,  0.315968, 
72         -0.336294, -0.734126, -0.048058,  0.100198,  0.582619, -0.704076, 
73         -0.658022, -0.083976, -0.179074,  0.304228,  0.150274, -0.428972,  
74          0.005536,  0.600618,  0.158177,  0.511973, -0.834075,  0.147372, 
75          0.831916, -0.915125, -0.211189, -0.921590, -0.186989,  0.628901, 
76         -0.726222, -0.735542,  0.941152, -0.978562, -0.124824,  0.193818 ];
77     private static size_t n;
78     float rnd() { return v[n++%$]; }
79     auto rndVec3() { return vec3( rnd(), rnd(), rnd() ); }
80     fSeg rndSeg() { return fSeg( rndVec3() * 0.04, rndVec3() * 0.06 ); }
81 }