OSDN Git Service

12313
[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()\r
15                         {\r
16                                 val = Double.NaN;\r
17                                 op = OPERATOR.CLOSE;\r
18                         }*/\r
19                         public VAL(double v, OPERATOR o)\r
20                         {\r
21                                 val = v;\r
22                                 op = o;\r
23                         }\r
24                         public bool bounded()\r
25                         {\r
26                                 return !Double.IsNaN(val) && (!Double.IsInfinity(val) || op == OPERATOR.OPEN);\r
27                         }\r
28                 }\r
29                 public VAL begin, end;\r
30 \r
31                 \r
32                 /*public Interval()\r
33                 {\r
34                         begin = new VAL { val = Double.PositiveInfinity, op = OPERATOR.CLOSE };\r
35                         end = new VAL { val = Double.NegativeInfinity, op = OPERATOR.CLOSE };\r
36                 }*/\r
37                 public Interval(double floor_val, double ceil_val)\r
38                 {\r
39                         begin.val = floor_val;\r
40                         begin.op =  OPERATOR.CLOSE;\r
41                         end.val = ceil_val;\r
42                         end.op = OPERATOR.CLOSE;\r
43                 }\r
44                 public Interval(double floor_val, OPERATOR floor_op, double ceil_val, OPERATOR ceil_op)\r
45                 {\r
46                         begin.val = floor_val;\r
47                         begin.op = floor_op;\r
48                         end.val = ceil_val;\r
49                         end.op = ceil_op;\r
50                 }\r
51 \r
52                 /*\r
53                 public int int_floor();\r
54                 public int int_floor(int minval);\r
55                 public int int_ceil();\r
56                 public int int_ceil(int maxval);\r
57                 */\r
58                 bool includes(double val)\r
59                 {\r
60                         bool result = false;\r
61                         switch(begin.op) {\r
62                                 case OPERATOR.CLOSE:\r
63                                 result = begin.val<=val ? true : false;\r
64                                 break;\r
65                                 case OPERATOR.OPEN:\r
66                                 result = begin.val<val ? true : false;\r
67                                 break;\r
68                         }\r
69                         switch(end.op) {\r
70                                 case OPERATOR.CLOSE:\r
71                                 result = result && ( end.val>=val ? true : false );\r
72                                 break;\r
73                                 case OPERATOR.OPEN:\r
74                                 result = result && ( end.val>val ? true : false );\r
75                                 break;\r
76                         }\r
77                         return result;\r
78                 }\r
79 \r
80                 public bool bounded()\r
81                 {\r
82                         return begin.bounded() && end.bounded();\r
83                 }\r
84 \r
85                 System.Collections.Generic.IEnumerable<double> step(double steps)\r
86                 {\r
87                         if (steps > 0) throw new Exception("Interval: step must be a positive");\r
88                         //                      return new IntervalIEnumerable(this, steps);\r
89                         Interval it = this;\r
90                         long front_step = (it.begin.op == Interval.OPERATOR.CLOSE ? -1 : 0);\r
91                         long back_step = (long)System.Math.Floor((it.end.val - it.begin.val) / steps);\r
92                         if (it.end.op == Interval.OPERATOR.OPEN && 0 == System.Math.IEEERemainder(it.end.val - it.begin.val, steps))\r
93                         {\r
94                                 back_step -= 1;\r
95                         }\r
96                         while (front_step <= back_step)\r
97                                 yield return steps * front_step + it.begin.val;\r
98                 }\r
99 \r
100 \r
101                 #region accessor generation\r
102 \r
103                 public static IntervalAcc operator <(double val, Interval rng)\r
104                 {\r
105                         return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, 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(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\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.OPEN) };\r
114                 }\r
115                 public static IntervalAcc operator >=(double val, Interval rng)\r
116                 {\r
117                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };\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.OPEN) };\r
122                 }\r
123                 public static IntervalAcc operator <=(Interval rng, double val)\r
124                 {\r
125                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, 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.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
130                 }\r
131                 public static IntervalAcc operator >=(Interval rng, double val)\r
132                 {\r
133                         return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
134                 }\r
135 \r
136                 #endregion\r
137 \r
138         }\r
139 \r
140         namespace Internal\r
141         {\r
142                 #region accessor definition\r
143 \r
144                 public struct IntervalAcc\r
145                 {\r
146                         public Interval instance;\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.OPEN, 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(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) };\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.OPEN) };\r
159                         }\r
160                         public static IntervalAcc operator >=(double val, IntervalAcc rng)\r
161                         {\r
162                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\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.OPEN) };\r
167                         }\r
168                         public static IntervalAcc operator <=(IntervalAcc rng, double val)\r
169                         {\r
170                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\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.OPEN, rng.instance.end.val, rng.instance.end.op) };\r
175                         }\r
176                         public static IntervalAcc operator >=(IntervalAcc rng, double val)\r
177                         {\r
178                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) };\r
179                         }\r
180 \r
181                         public static implicit operator Interval(IntervalAcc rhs)\r
182                         {\r
183                                 return rhs.instance;\r
184                         }\r
185                 }\r
186 \r
187                 #endregion\r
188 \r
189         }\r
190 \r
191 \r
192 }