Changeset 17963


Ignore:
Timestamp:
04/23/21 18:26:45 (2 weeks ago)
Author:
gkronber
Message:

#3121: support integer powers in interval arithmetic (and two simplification rules)

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs

    r17820 r17963  
    784784      } else if (IsExp(node)) {
    785785        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x)
     786      } else if (IsSquare(node)) {
     787        return MakePower(node.GetSubtree(0), MakeConstant(4));
    786788      } else if (IsCube(node)) {
    787789        return MakePower(node.GetSubtree(0), MakeConstant(6));
     
    809811      } else if (IsSquare(node)) {
    810812        return MakePower(node.GetSubtree(0), MakeConstant(6));
     813      } else if (IsCube(node)) {
     814        return MakePower(node.GetSubtree(0), MakeConstant(9));
    811815      } else {
    812816        var cubeNode = cubeSymbol.CreateTreeNode();
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17911 r17963  
    283283            break;
    284284          }
     285        case OpCodes.Power: {
     286            var a = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     287            var b = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     288            // support only integer powers
     289            if(b.LowerBound == b.UpperBound && Math.Truncate(b.LowerBound) == b.LowerBound) {
     290              result = Interval.Power(a, (int)b.LowerBound);
     291            } else {
     292              throw new NotSupportedException("Interval is only supported for integer powers");
     293            }
     294            break;
     295          }
     296
    285297        case OpCodes.Absolute: {
    286298            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     
    329341          !(n.Symbol is Cube) &&
    330342          !(n.Symbol is CubeRoot) &&
     343          !(n.Symbol is Power) &&
    331344          !(n.Symbol is Absolute) &&
    332345          !(n.Symbol is AnalyticQuotient)
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs

    r17180 r17963  
    144144      { typeof(Cosine), OpCodes.Cos },
    145145      { typeof(Tangent), OpCodes.Tan },
    146       { typeof (HyperbolicTangent), OpCodes.Tanh},
     146      { typeof(HyperbolicTangent), OpCodes.Tanh},
    147147      { typeof(Logarithm), OpCodes.Log },
    148148      { typeof(Exponential), OpCodes.Exp },
  • trunk/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval/Interval.cs

    r17911 r17963  
    7878      if (double.IsNegativeInfinity(LowerBound) && double.IsPositiveInfinity(UpperBound)) return true;
    7979      if (other.LowerBound >= LowerBound && other.UpperBound <= UpperBound) return true;
    80  
     80
    8181      return false;
    8282    }
     
    9797    /// </summary>
    9898    public bool IsPositive {
    99       get => LowerBound > 0.0; 
     99      get => LowerBound > 0.0;
    100100    }
    101101
     
    130130        return false;
    131131
    132       return (UpperBound==other.UpperBound || (double.IsNaN(UpperBound) && double.IsNaN(other.UpperBound)))
    133         && (LowerBound==other.LowerBound || (double.IsNaN(LowerBound) && double.IsNaN(other.LowerBound)));
     132      return (UpperBound == other.UpperBound || (double.IsNaN(UpperBound) && double.IsNaN(other.UpperBound)))
     133        && (LowerBound == other.LowerBound || (double.IsNaN(LowerBound) && double.IsNaN(other.LowerBound)));
    134134    }
    135135
     
    238238    public static Interval Cube(Interval a) {
    239239      return new Interval(Math.Pow(a.LowerBound, 3), Math.Pow(a.UpperBound, 3));
     240    }
     241
     242    public static Interval Power(Interval a, int b) {
     243      if (b < 0) return Power(1.0 / a, -b); // a^(-b) = 1/(a^b)
     244      if (b == 0 && (a.Contains(0.0) || a.IsInfiniteOrUndefined)) return new Interval(double.NaN, double.NaN);  // 0^0, +/-inf^0 are undefined
     245      if (b == 0) return new Interval(1.0, 1.0); // x^0 = 1
     246      if (b == 1) return a;
     247      if (b % 2 == 0) {
     248        // even powers (see x²)
     249        if (a.UpperBound <= 0) return new Interval(Math.Pow(a.UpperBound, b), Math.Pow(a.LowerBound, b));     // interval is negative
     250        if (a.LowerBound >= 0) return new Interval(Math.Pow(a.LowerBound, b), Math.Pow(a.UpperBound, b)); // interval is positive
     251        return new Interval(0, Math.Max(Math.Pow(a.LowerBound, b), Math.Pow(a.UpperBound, b))); // interval goes over zero
     252      } else {
     253        // odd powers (see x³)
     254        return new Interval(Math.Pow(a.LowerBound, b), Math.Pow(a.UpperBound, b));
     255      }
    240256    }
    241257
Note: See TracChangeset for help on using the changeset viewer.