X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=dev4%2Fpsychlops%2Fcore%2Fmath%2Finterval.cs;fp=dev4%2Fpsychlops%2Fcore%2Fmath%2Finterval.cs;h=64260469451c67101cfba3d1299fc277f283b732;hb=cb8916a7a5cd929f57b3f9edd99209680db90546;hp=0000000000000000000000000000000000000000;hpb=e05ab8e68d381f8f5c9a2ddb7c63b89a7bb6371a;p=psychlops%2Fsilverlight.git diff --git a/dev4/psychlops/core/math/interval.cs b/dev4/psychlops/core/math/interval.cs new file mode 100644 index 0000000..6426046 --- /dev/null +++ b/dev4/psychlops/core/math/interval.cs @@ -0,0 +1,188 @@ +using System; +using Psychlops.Internal; + + +namespace Psychlops +{ + + public struct Interval { + public enum OPERATOR { CLOSE, OPEN }; + public const OPERATOR CLOSE = OPERATOR.CLOSE, OPEN = OPERATOR.OPEN; + public struct VAL { + public double val; + public OPERATOR op; + public VAL(double v, OPERATOR o) + { + val = v; + op = o; + } + public bool bounded() + { + return !Double.IsNaN(val) && (!Double.IsInfinity(val) || op == OPERATOR.OPEN); + } + } + public VAL begin, end; + + /* + public Interval() + { + begin = new VAL { val = Double.PositiveInfinity, op = OPERATOR.CLOSE }; + end = new VAL { val = Double.NegativeInfinity, op = OPERATOR.CLOSE }; + } + */ + public Interval(double floor_val, double ceil_val) + { + begin.val = floor_val; + begin.op = OPERATOR.CLOSE; + end.val = ceil_val; + end.op = OPERATOR.CLOSE; + } + public Interval(double floor_val, OPERATOR floor_op, double ceil_val, OPERATOR ceil_op) + { + begin.val = floor_val; + begin.op = floor_op; + end.val = ceil_val; + end.op = ceil_op; + } + + /* + public int int_floor(); + public int int_floor(int minval); + public int int_ceil(); + public int int_ceil(int maxval); + */ + bool includes(double val) + { + bool result = false; + switch(begin.op) { + case OPERATOR.CLOSE: + result = begin.val<=val ? true : false; + break; + case OPERATOR.OPEN: + result = begin.val=val ? true : false ); + break; + case OPERATOR.OPEN: + result = result && ( end.val>val ? true : false ); + break; + } + return result; + } + + public bool bounded() + { + return begin.bounded() && end.bounded(); + } + + System.Collections.Generic.IEnumerable step(double steps) + { + if (steps > 0) throw new Exception("Interval: step must be a positive"); + // return new IntervalIEnumerable(this, steps); + Interval it = this; + long front_step = (it.begin.op == Interval.OPERATOR.CLOSE ? -1 : 0); + long back_step = (long)System.Math.Floor((it.end.val - it.begin.val) / steps); + if (it.end.op == Interval.OPERATOR.OPEN && 0 == System.Math.IEEERemainder(it.end.val - it.begin.val, steps)) + { + back_step -= 1; + } + while (front_step <= back_step) + yield return steps * front_step + it.begin.val; + } + + + #region accessor generation + + public static IntervalAcc operator <(double val, Interval rng) + { + return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) }; + } + public static IntervalAcc operator <=(double val, Interval rng) + { + return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) }; + } + public static IntervalAcc operator >(double val, Interval rng) + { + return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) }; + } + public static IntervalAcc operator >=(double val, Interval rng) + { + return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) }; + } + public static IntervalAcc operator <(Interval rng, double val) + { + return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.OPEN) }; + } + public static IntervalAcc operator <=(Interval rng, double val) + { + return new IntervalAcc { instance = new Interval(Double.NegativeInfinity, OPERATOR.CLOSE, val, OPERATOR.CLOSE) }; + } + public static IntervalAcc operator >(Interval rng, double val) + { + return new IntervalAcc { instance = new Interval(val, OPERATOR.OPEN, Double.PositiveInfinity, OPERATOR.CLOSE) }; + } + public static IntervalAcc operator >=(Interval rng, double val) + { + return new IntervalAcc { instance = new Interval(val, OPERATOR.CLOSE, Double.PositiveInfinity, OPERATOR.CLOSE) }; + } + + #endregion + + } + + namespace Internal + { + #region accessor definition + + public struct IntervalAcc + { + public Interval instance; + + public static IntervalAcc operator <(double val, IntervalAcc rng) + { + return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.val, rng.instance.end.op) }; + } + public static IntervalAcc operator <=(double val, IntervalAcc rng) + { + return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) }; + } + public static IntervalAcc operator >(double val, IntervalAcc rng) + { + return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) }; + } + public static IntervalAcc operator >=(double val, IntervalAcc rng) + { + return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) }; + } + public static IntervalAcc operator <(IntervalAcc rng, double val) + { + return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.OPEN) }; + } + public static IntervalAcc operator <=(IntervalAcc rng, double val) + { + return new IntervalAcc { instance = new Interval(rng.instance.begin.val, rng.instance.begin.op, val, Interval.OPERATOR.CLOSE) }; + } + public static IntervalAcc operator >(IntervalAcc rng, double val) + { + return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.OPEN, rng.instance.end.val, rng.instance.end.op) }; + } + public static IntervalAcc operator >=(IntervalAcc rng, double val) + { + return new IntervalAcc { instance = new Interval(val, Interval.OPERATOR.CLOSE, rng.instance.end.val, rng.instance.end.op) }; + } + + public static implicit operator Interval(IntervalAcc rhs) + { + return rhs.instance; + } + } + + #endregion + + } + + +} \ No newline at end of file