OSDN Git Service

323
[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 value;\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                                 value = v;\r
22                                 op = o;\r
23                         }\r
24                         public bool bounded()\r
25                         {\r
26                                 return !Double.IsNaN(value) && (!Double.IsInfinity(value) || 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.value = floor_val;\r
40                         begin.op =  OPERATOR.CLOSE;\r
41                         end.value = 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.value = floor_val;\r
47                         begin.op = floor_op;\r
48                         end.value = ceil_val;\r
49                         end.op = ceil_op;\r
50                 }\r
51 \r
52 \r
53                 public int int_floor()\r
54                 {\r
55                         double v = Math.ceil(begin.value);\r
56                         if (begin.op == OPEN && v == begin.value) { return (int)v + 1; }\r
57                         else return (int)v;\r
58                 }\r
59                 public int int_floor(int minval)\r
60                 {\r
61                         if(begin.value<minval) return minval;\r
62                         double v = Math.ceil(begin.value);\r
63                         if (begin.op == OPEN && v == begin.value) { return (int)v + 1; }\r
64                         else return (int)v;\r
65                 }\r
66                 public int int_ceil()\r
67                 {\r
68                         double v = Math.floor(end.value);\r
69                         if (end.op == OPEN && v == end.value) { return (int)v - 1; }\r
70                         else return (int)v;\r
71                 }\r
72                 public int int_ceil(int maxval)\r
73                 {\r
74                         if(end.value>maxval) return maxval;\r
75                         double v = Math.floor(end.value);\r
76                         if (end.op == OPEN && v == end.value) { return (int)v - 1; }\r
77                         else return (int)v;\r
78                 }\r
79                 \r
80                 bool includes(double val)\r
81                 {\r
82                         bool result = false;\r
83                         switch(begin.op) {\r
84                                 case OPERATOR.CLOSE:\r
85                                         result = begin.value <= val ? true : false;\r
86                                         break;\r
87                                 case OPERATOR.OPEN:\r
88                                         result = begin.value < val ? true : false;\r
89                                         break;\r
90                         }\r
91                         switch(end.op) {\r
92                                 case OPERATOR.CLOSE:\r
93                                         result = result && (end.value >= val ? true : false);\r
94                                         break;\r
95                                 case OPERATOR.OPEN:\r
96                                         result = result && (end.value > val ? true : false);\r
97                                         break;\r
98                         }\r
99                         return result;\r
100                 }\r
101 \r
102                 public bool bounded()\r
103                 {\r
104                         return begin.bounded() && end.bounded();\r
105                 }\r
106 \r
107                 System.Collections.Generic.IEnumerable<double> step(double steps)\r
108                 {\r
109                         if (steps > 0) throw new Exception("Interval: step must be a positive");\r
110                         //                      return new IntervalIEnumerable(this, steps);\r
111                         Interval it = this;\r
112                         long front_step = (it.begin.op == Interval.OPERATOR.CLOSE ? -1 : 0);\r
113                         long back_step = (long)System.Math.Floor((it.end.value - it.begin.value) / steps);\r
114                         if (it.end.op == Interval.OPERATOR.OPEN && 0 == System.Math.IEEERemainder(it.end.value - it.begin.value, steps))\r
115                         {\r
116                                 back_step -= 1;\r
117                         }\r
118                         while (front_step <= back_step)\r
119                                 yield return steps * front_step + it.begin.value;\r
120                 }\r
121 \r
122 \r
123                 #region accessor generation\r
124 \r
125                 public static IntervalAcc operator <(double val, Interval rng)\r
126                 {\r
127                         return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
128                 }\r
129                 public static IntervalAcc operator <=(double val, Interval rng)\r
130                 {\r
131                         return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
132                 }\r
133                 public static IntervalAcc operator >(double val, Interval rng)\r
134                 {\r
135                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };\r
136                 }\r
137                 public static IntervalAcc operator >=(double val, Interval rng)\r
138                 {\r
139                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };\r
140                 }\r
141                 public static IntervalAcc operator <(Interval rng, double val)\r
142                 {\r
143                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };\r
144                 }\r
145                 public static IntervalAcc operator <=(Interval rng, double val)\r
146                 {\r
147                         return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };\r
148                 }\r
149                 public static IntervalAcc operator >(Interval rng, double val)\r
150                 {\r
151                         return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
152                 }\r
153                 public static IntervalAcc operator >=(Interval rng, double val)\r
154                 {\r
155                         return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };\r
156                 }\r
157 \r
158                 #endregion\r
159 \r
160         }\r
161 \r
162         namespace Internal\r
163         {\r
164                 #region accessor definition\r
165 \r
166                 public struct IntervalAcc\r
167                 {\r
168                         public Interval instance;\r
169 \r
170                         public static IntervalAcc operator <(double val, IntervalAcc rng)\r
171                         {\r
172                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.value, rng.instance.end.op) };\r
173                         }\r
174                         public static IntervalAcc operator <=(double val, IntervalAcc rng)\r
175                         {\r
176                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.value, rng.instance.end.op) };\r
177                         }\r
178                         public static IntervalAcc operator >(double val, IntervalAcc rng)\r
179                         {\r
180                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };\r
181                         }\r
182                         public static IntervalAcc operator >=(double val, IntervalAcc rng)\r
183                         {\r
184                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\r
185                         }\r
186                         public static IntervalAcc operator <(IntervalAcc rng, double val)\r
187                         {\r
188                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };\r
189                         }\r
190                         public static IntervalAcc operator <=(IntervalAcc rng, double val)\r
191                         {\r
192                                 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };\r
193                         }\r
194                         public static IntervalAcc operator >(IntervalAcc rng, double val)\r
195                         {\r
196                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.value, rng.instance.end.op) };\r
197                         }\r
198                         public static IntervalAcc operator >=(IntervalAcc rng, double val)\r
199                         {\r
200                                 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.value, rng.instance.end.op) };\r
201                         }\r
202 \r
203                         public static implicit operator Interval(IntervalAcc rhs)\r
204                         {\r
205                                 return rhs.instance;\r
206                         }\r
207                 }\r
208 \r
209                 #endregion\r
210 \r
211         }\r
212 \r
213 \r
214 }