2 using Psychlops.Internal;
\r
8 public struct Interval {
\r
9 public enum OPERATOR { CLOSE, OPEN };
\r
10 public const OPERATOR CLOSE = OPERATOR.CLOSE, OPEN = OPERATOR.OPEN;
\r
12 public double value;
\r
17 op = OPERATOR.CLOSE;
\r
19 public VAL(double v, OPERATOR o)
\r
24 public bool bounded()
\r
26 return !Double.IsNaN(value) && (!Double.IsInfinity(value) || op == OPERATOR.OPEN);
\r
29 public VAL begin, end;
\r
34 begin = new VAL { val = Double.PositiveInfinity, op = OPERATOR.CLOSE };
\r
35 end = new VAL { val = Double.NegativeInfinity, op = OPERATOR.CLOSE };
\r
37 public Interval(double floor_val, double ceil_val)
\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
44 public Interval(double floor_val, OPERATOR floor_op, double ceil_val, OPERATOR ceil_op)
\r
46 begin.value = floor_val;
\r
47 begin.op = floor_op;
\r
48 end.value = ceil_val;
\r
53 public int int_floor()
\r
55 double v = Math.ceil(begin.value);
\r
56 if (begin.op == OPEN && v == begin.value) { return (int)v + 1; }
\r
59 public int int_floor(int minval)
\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
66 public int int_ceil()
\r
68 double v = Math.floor(end.value);
\r
69 if (end.op == OPEN && v == end.value) { return (int)v - 1; }
\r
72 public int int_ceil(int maxval)
\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
80 bool includes(double val)
\r
82 bool result = false;
\r
84 case OPERATOR.CLOSE:
\r
85 result = begin.value <= val ? true : false;
\r
88 result = begin.value < val ? true : false;
\r
92 case OPERATOR.CLOSE:
\r
93 result = result && (end.value >= val ? true : false);
\r
96 result = result && (end.value > val ? true : false);
\r
102 public bool bounded()
\r
104 return begin.bounded() && end.bounded();
\r
107 System.Collections.Generic.IEnumerable<double> step(double steps)
\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
118 while (front_step <= back_step)
\r
119 yield return steps * front_step + it.begin.value;
\r
123 #region accessor generation
\r
125 public static IntervalAcc operator <(double val, Interval rng)
\r
127 return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };
\r
129 public static IntervalAcc operator <=(double val, Interval rng)
\r
131 return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };
\r
133 public static IntervalAcc operator >(double val, Interval rng)
\r
135 return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };
\r
137 public static IntervalAcc operator >=(double val, Interval rng)
\r
139 return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };
\r
141 public static IntervalAcc operator <(Interval rng, double val)
\r
143 return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) };
\r
145 public static IntervalAcc operator <=(Interval rng, double val)
\r
147 return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) };
\r
149 public static IntervalAcc operator >(Interval rng, double val)
\r
151 return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) };
\r
153 public static IntervalAcc operator >=(Interval rng, double val)
\r
155 return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) };
\r
164 #region accessor definition
\r
166 public struct IntervalAcc
\r
168 public Interval instance;
\r
170 public static IntervalAcc operator <(double val, IntervalAcc rng)
\r
172 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.value, rng.instance.end.op) };
\r
174 public static IntervalAcc operator <=(double val, IntervalAcc rng)
\r
176 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.value, rng.instance.end.op) };
\r
178 public static IntervalAcc operator >(double val, IntervalAcc rng)
\r
180 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };
\r
182 public static IntervalAcc operator >=(double val, IntervalAcc rng)
\r
184 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };
\r
186 public static IntervalAcc operator <(IntervalAcc rng, double val)
\r
188 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) };
\r
190 public static IntervalAcc operator <=(IntervalAcc rng, double val)
\r
192 return new IntervalAcc { instance = new Interval(rng.instance.begin.value, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) };
\r
194 public static IntervalAcc operator >(IntervalAcc rng, double val)
\r
196 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.value, rng.instance.end.op) };
\r
198 public static IntervalAcc operator >=(IntervalAcc rng, double val)
\r
200 return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.value, rng.instance.end.op) };
\r
203 public static implicit operator Interval(IntervalAcc rhs)
\r
205 return rhs.instance;
\r