OSDN Git Service

faster2
[psychlops/silverlight.git] / dev4 / psychlops / core / math / interval.cs
1 using System;\r
2 using Psychlops.Internal;\r
3 \r
4 \r
5 namespace Psychlops\r
6 {\r
7 \r
8         public struct Interval {\r
9                 public enum OPERATOR { CLOSE, OPEN };\r
10                 public const OPERATOR CLOSE = OPERATOR.CLOSE, OPEN = OPERATOR.OPEN;\r
11                 public struct VAL {\r
12                         public double val;\r
13                         public OPERATOR op;\r
14                         public VAL(double v, OPERATOR o)\r
15                         {\r
16                                 val = v;\r
17                                 op = o;\r
18                         }\r
19                         public bool bounded()\r
20                         {\r
21                                 return !Double.IsNaN(val) && (!Double.IsInfinity(val) || op == OPERATOR.OPEN);\r
22                         }\r
23                 }\r
24                 public VAL begin, end;\r
25 \r
26                 /*\r
27                 public Interval()\r
28                 {\r
29                         begin = new VAL { val = Double.PositiveInfinity, op = OPERATOR.CLOSE };\r
30                         end = new VAL { val = Double.NegativeInfinity, op = OPERATOR.CLOSE };\r
31                 }\r
32                 */\r
33                 public Interval(double floor_val, double ceil_val)\r
34                 {\r
35                         begin.val = floor_val;\r
36                         begin.op =  OPERATOR.CLOSE;\r
37                         end.val = ceil_val;\r
38                         end.op = OPERATOR.CLOSE;\r
39                 }\r
40                 public Interval(double floor_val, OPERATOR floor_op, double ceil_val, OPERATOR ceil_op)\r
41                 {\r
42                         begin.val = floor_val;\r
43                         begin.op = floor_op;\r
44                         end.val = ceil_val;\r
45                         end.op = ceil_op;\r
46                 }\r
47 \r
48                 /*\r
49                 public int int_floor();\r
50                 public int int_floor(int minval);\r
51                 public int int_ceil();\r
52                 public int int_ceil(int maxval);\r
53                 */\r
54                 bool includes(double val)\r
55                 {\r
56                         bool result = false;\r
57                         switch(begin.op) {\r
58                                 case OPERATOR.CLOSE:\r
59                                 result = begin.val<=val ? true : false;\r
60                                 break;\r
61                                 case OPERATOR.OPEN:\r
62                                 result = begin.val<val ? true : false;\r
63                                 break;\r
64                         }\r
65                         switch(end.op) {\r
66                                 case OPERATOR.CLOSE:\r
67                                 result = result && ( end.val>=val ? true : false );\r
68                                 break;\r
69                                 case OPERATOR.OPEN:\r
70                                 result = result && ( end.val>val ? true : false );\r
71                                 break;\r
72                         }\r
73                         return result;\r
74                 }\r
75 \r
76                 public bool bounded()\r
77                 {\r
78                         return begin.bounded() && end.bounded();\r
79                 }\r
80 \r
81                 System.Collections.Generic.IEnumerable<double> step(double steps)\r
82                 {\r
83                         if (steps > 0) throw new Exception("Interval: step must be a positive");\r
84                         //                      return new IntervalIEnumerable(this, steps);\r
85                         Interval it = this;\r
86                         long front_step = (it.begin.op == Interval.OPERATOR.CLOSE ? -1 : 0);\r
87                         long back_step = (long)System.Math.Floor((it.end.val - it.begin.val) / steps);\r
88                         if (it.end.op == Interval.OPERATOR.OPEN && 0 == System.Math.IEEERemainder(it.end.val - it.begin.val, steps))\r
89                         {\r
90                                 back_step -= 1;\r
91                         }\r
92                         while (front_step <= back_step)\r
93                                 yield return steps * front_step + it.begin.val;\r
94                 }\r
95 \r
96 \r
97                 #region accessor generation\r
98 \r
99                 public static IntervalAcc operator <(double val, Interval rng)\r
100                 {\r
101                         return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
102                 }\r
103                 public static IntervalAcc operator <=(double val, Interval rng)\r
104                 {\r
105                         return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
106                 }\r
107                 public static IntervalAcc operator >(double val, Interval rng)\r
108                 {\r
109                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };\r
110                 }\r
111                 public static IntervalAcc operator >=(double val, Interval rng)\r
112                 {\r
113                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };\r
114                 }\r
115                 public static IntervalAcc operator <(Interval rng, double val)\r
116                 {\r
117                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };\r
118                 }\r
119                 public static IntervalAcc operator <=(Interval rng, double val)\r
120                 {\r
121                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };\r
122                 }\r
123                 public static IntervalAcc operator >(Interval rng, double val)\r
124                 {\r
125                         return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
126                 }\r
127                 public static IntervalAcc operator >=(Interval rng, double val)\r
128                 {\r
129                         return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
130                 }\r
131 \r
132                 #endregion\r
133 \r
134         }\r
135 \r
136         namespace Internal\r
137         {\r
138                 #region accessor definition\r
139 \r
140                 public struct IntervalAcc\r
141                 {\r
142                         public Interval instance;\r
143 \r
144                         public static IntervalAcc operator <(double val, IntervalAcc rng)\r
145                         {\r
146                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.val, rng.instance.end.op) };\r
147                         }\r
148                         public static IntervalAcc operator <=(double val, IntervalAcc rng)\r
149                         {\r
150                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) };\r
151                         }\r
152                         public static IntervalAcc operator >(double val, IntervalAcc rng)\r
153                         {\r
154                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };\r
155                         }\r
156                         public static IntervalAcc operator >=(double val, IntervalAcc rng)\r
157                         {\r
158                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\r
159                         }\r
160                         public static IntervalAcc operator <(IntervalAcc rng, double val)\r
161                         {\r
162                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };\r
163                         }\r
164                         public static IntervalAcc operator <=(IntervalAcc rng, double val)\r
165                         {\r
166                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\r
167                         }\r
168                         public static IntervalAcc operator >(IntervalAcc rng, double val)\r
169                         {\r
170                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.val, rng.instance.end.op) };\r
171                         }\r
172                         public static IntervalAcc operator >=(IntervalAcc rng, double val)\r
173                         {\r
174                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) };\r
175                         }\r
176 \r
177                         public static implicit operator Interval(IntervalAcc rhs)\r
178                         {\r
179                                 return rhs.instance;\r
180                         }\r
181                 }\r
182 \r
183                 #endregion\r
184 \r
185         }\r
186 \r
187 \r
188 }