Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2956_apriori_knowledge/HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration/3.4/IntervalArithmetic/Interval.cs @ 16460

Last change on this file since 16460 was 16303, checked in by chaider, 6 years ago

#2956: Added intermediate of a-priori knowledge

File size: 7.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using HeuristicLab.Common;
7
8namespace HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration.IntervalArithmetic {
9  public class Interval : IEquatable<Interval> {
10    private double lowerBound;
11    public double LowerBound {
12      get { return lowerBound; }
13      set { lowerBound = value; }
14    }
15    private double upperBound;
16    public double UpperBound {
17      get { return upperBound; }
18      set { lowerBound = value; }
19    }
20
21    public Interval() { }
22
23    public Interval(double lowerBound, double upperBound) {
24      if (lowerBound > upperBound)
25        throw new ArgumentException("LowerBound must be smaller than UpperBound.");
26
27      this.lowerBound = lowerBound;
28      this.upperBound = upperBound;
29    }
30
31    public bool Contains(double value) {
32      return lowerBound <= value && value <= upperBound;
33    }
34
35    public override string ToString() {
36      return "Interval: [" + lowerBound + ", " + upperBound + "]";
37    }
38
39    public bool IsInfiniteOrUndefined {
40      get {
41        return double.IsInfinity(LowerBound) || double.IsInfinity(UpperBound) ||
42                double.IsNaN(LowerBound) || double.IsNaN(UpperBound);
43      }
44    }
45
46    #region Equals, GetHashCode, == , !=
47    public bool Equals(Interval other) {
48      if (other == null)
49        return false;
50
51      return this.upperBound.IsAlmost(other.upperBound) && this.lowerBound.IsAlmost(other.lowerBound);
52    }
53
54    public override bool Equals(object obj) {
55      return Equals(obj as Interval);
56    }
57
58    public override int GetHashCode() {
59      return lowerBound.GetHashCode() ^ upperBound.GetHashCode();
60    }
61
62    public static bool operator ==(Interval interval1, Interval interval2) {
63      if (ReferenceEquals(interval1, null)) return ReferenceEquals(interval2, null);
64      return interval1.Equals(interval2);
65    }
66    public static bool operator !=(Interval interval1, Interval interval2) {
67      return !(interval1 == interval2);
68    }
69    #endregion
70
71    #region operations
72
73    // [x1,x2] + [y1,y2] = [x1 + y1,x2 + y2]
74    public static Interval Add(Interval a, Interval b) {
75      return new Interval(a.lowerBound + b.lowerBound, a.upperBound + b.upperBound);
76    }
77
78    // [x1,x2] − [y1,y2] = [x1 − y2,x2 − y1]
79    public static Interval Subtract(Interval a, Interval b) {
80      return new Interval(a.lowerBound - b.upperBound, a.upperBound - b.lowerBound);
81    }
82
83    // [x1,x2] * [y1,y2] = [min(x1*y1,x1*y2,x2*y1,x2*y2),max(x1*y1,x1*y2,x2*y1,x2*y2)]
84    public static Interval Multiply(Interval a, Interval b) {
85      double v1 = a.lowerBound * b.lowerBound;
86      double v2 = a.lowerBound * b.upperBound;
87      double v3 = a.upperBound * b.lowerBound;
88      double v4 = a.upperBound * b.upperBound;
89
90      double min = Math.Min(Math.Min(v1, v2), Math.Min(v3, v4));
91      double max = Math.Max(Math.Min(v1, v2), Math.Max(v3, v4));
92      return new Interval(min, max);
93    }
94
95    //mkommend: Divisiont by intervals containing 0 is implemented as defined in
96    //http://en.wikipedia.org/wiki/Interval_arithmetic
97    public static Interval Divide(Interval a, Interval b) {
98      if (b.Contains(0.0)) {
99        if (b.lowerBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(1.0 / b.upperBound, double.PositiveInfinity));
100        else if (b.upperBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(double.NegativeInfinity, 1.0 / b.lowerBound));
101        else return new Interval(double.NegativeInfinity, double.PositiveInfinity);
102      }
103      return Interval.Multiply(a, new Interval(1.0 / b.upperBound, 1.0 / b.lowerBound));
104    }
105
106    public static Interval Sine(Interval a) {
107      if (Math.Abs(a.upperBound - a.lowerBound) >= Math.PI * 2) return new Interval(-1, 1);
108
109      //divide the interval by PI/2 so that the optima lie at x element of N (0,1,2,3,4,...)
110      double Pihalf = Math.PI / 2;
111      Interval scaled = Interval.Divide(a, new Interval(Pihalf, Pihalf));
112      //move to positive scale
113      if (scaled.lowerBound < 0) {
114        int periodsToMove = Math.Abs((int)scaled.lowerBound / 4) + 1;
115        scaled = Interval.Add(scaled, new Interval(periodsToMove * 4, periodsToMove * 4));
116      }
117
118      double scaledLowerBound = scaled.lowerBound % 4.0;
119      double scaledUpperBound = scaled.upperBound % 4.0;
120      if (scaledUpperBound < scaledLowerBound) scaledUpperBound += 4.0;
121      List<double> sinValues = new List<double>();
122      sinValues.Add(Math.Sin(scaledLowerBound * Pihalf));
123      sinValues.Add(Math.Sin(scaledUpperBound * Pihalf));
124
125      int startValue = (int)Math.Ceiling(scaledLowerBound);
126      while (startValue < scaledUpperBound) {
127        sinValues.Add(Math.Sin(startValue * Pihalf));
128        startValue += 1;
129      }
130
131      return new Interval(sinValues.Min(), sinValues.Max());
132    }
133    public static Interval Cosine(Interval a) {
134      return Interval.Sine(Interval.Subtract(a, new Interval(Math.PI / 2, Math.PI / 2)));
135    }
136    public static Interval Tangens(Interval a) {
137      return Interval.Divide(Interval.Sine(a), Interval.Cosine(a));
138    }
139
140    public static Interval Logarithm(Interval a) {
141      return new Interval(Math.Log(a.lowerBound), Math.Log(a.upperBound));
142    }
143    public static Interval Exponential(Interval a) {
144      return new Interval(Math.Exp(a.lowerBound), Math.Exp(a.upperBound));
145    }
146
147    public static Interval Power(Interval a, Interval b) {
148      if (a.Contains(0.0) && b.lowerBound < 0) return new Interval(double.NaN, double.NaN);
149
150      int bLower = (int)Math.Round(b.lowerBound);
151      int bUpper = (int)Math.Round(b.upperBound);
152
153      List<double> powerValues = new List<double>();
154      powerValues.Add(Math.Pow(a.upperBound, bUpper));
155      powerValues.Add(Math.Pow(a.upperBound, bUpper - 1));
156      powerValues.Add(Math.Pow(a.upperBound, bLower));
157      powerValues.Add(Math.Pow(a.upperBound, bLower + 1));
158
159      powerValues.Add(Math.Pow(a.lowerBound, bUpper));
160      powerValues.Add(Math.Pow(a.lowerBound, bUpper - 1));
161      powerValues.Add(Math.Pow(a.lowerBound, bLower));
162      powerValues.Add(Math.Pow(a.lowerBound, bLower + 1));
163
164      return new Interval(powerValues.Min(), powerValues.Max());
165    }
166
167
168    public static Interval Root(Interval a, Interval b) {
169      int lower = (int)Math.Round(b.lowerBound);
170      int higher = (int)Math.Round(b.upperBound);
171
172      return new Interval(Math.Pow(a.lowerBound, 1.0 / higher), Math.Pow(a.upperBound, 1.0 / lower));
173    }
174
175    public static Interval Average(IEnumerable<Interval> intervals) {
176      if (intervals == null || !intervals.Any()) throw new ArgumentException();
177
178      int count = intervals.Count();
179      Interval result = intervals.First();
180      foreach (Interval i in intervals.Skip(1))
181        result = Interval.Add(result, i);
182
183      return new Interval(result.lowerBound / count, result.upperBound / count);
184    }
185    #endregion
186  }
187}
Note: See TracBrowser for help on using the repository browser.