View Javadoc
1   package org.djutils.math.functions;
2   
3   import java.util.Objects;
4   import java.util.SortedSet;
5   
6   import org.djutils.exceptions.Throw;
7   
8   /**
9    * Quotient.java.
10   * <p>
11   * Copyright (c) 2024-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
12   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
13   * distributed under a three-clause BSD-style license, which can be found at
14   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
15   * </p>
16   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
18   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
19   */
20  public class Quotient implements MathFunction
21  {
22      /** The numerator of this Quotient. */
23      private final MathFunction numerator;
24  
25      /** The denominator of this Quotient. */
26      private final MathFunction denominator;
27  
28      /**
29       * Construct a new Quotient; division of two <code>MathFunction</code>s, generally <code>numerator / denominator</code>.
30       * @param numerator the numerator part of the division (the part above the division line)
31       * @param denominator the denominator of the division (the part below the division line)
32       * @throws NullPointerException when <code>numerator</code>, or <code>denominator</code> is <code>null</code>
33       */
34      public Quotient(final MathFunction numerator, final MathFunction denominator)
35      {
36          Throw.whenNull(numerator, "numerator");
37          Throw.whenNull(denominator, "denominator");
38          this.numerator = numerator;
39          this.denominator = denominator;
40      }
41  
42      @Override
43      public double get(final double x)
44      {
45          return this.numerator.get(x) / this.denominator.get(x);
46      }
47  
48      @Override
49      public MathFunction getDerivative()
50      {
51          Quotient result = new Quotient(
52                  new Sum(new Product(this.numerator.getDerivative(), this.denominator),
53                          new Product(this.numerator.scaleBy(-1), this.denominator.getDerivative())),
54                  new Product(this.denominator, this.denominator));
55          return result.simplify();
56      }
57  
58      @Override
59      public MathFunction simplify()
60      {
61          if (this.denominator instanceof Constant)
62          {
63              return this.numerator.scaleBy(1.0 / this.denominator.get(0));
64          }
65          MathFunction divideResult = this.numerator.mergeDivide(this.denominator);
66          return divideResult != null ? divideResult : this;
67      }
68  
69      @Override
70      public MathFunction scaleBy(final double factor)
71      {
72          return new Quotient(this.numerator.scaleBy(factor), this.denominator);
73      }
74  
75      @Override
76      public int sortPriority()
77      {
78          return 102;
79      }
80  
81      @Override
82      public int compareWithinSubType(final MathFunction other)
83      {
84          Throw.when(!(other instanceof Quotient), IllegalArgumentException.class, "other is of wrong type");
85          Quotient otherQuotient = (Quotient) other;
86          int result = this.denominator.compareTo(otherQuotient.denominator);
87          if (result != 0)
88          {
89              return result;
90          }
91          return this.numerator.compareTo(otherQuotient.numerator);
92      }
93  
94      @Override
95      public KnotReport getKnotReport(final Interval<?> interval)
96      {
97          return KnotReport.UNKNOWN;
98      }
99  
100     @Override
101     public SortedSet<Double> getKnots(final Interval<?> interval)
102     {
103         throw new UnsupportedOperationException(
104                 "Cannot report knots in because I do not know where the numerator function is negative or zero");
105     }
106 
107     @Override
108     public String toString()
109     {
110         StringBuilder result = new StringBuilder();
111         result.append("(");
112         result.append(this.numerator.toString());
113         result.append(")/(");
114         result.append(this.denominator.toString());
115         result.append(")");
116         return result.toString();
117     }
118 
119     @Override
120     public int hashCode()
121     {
122         return Objects.hash(this.denominator, this.numerator);
123     }
124 
125     @SuppressWarnings("checkstyle:needbraces")
126     @Override
127     public boolean equals(final Object obj)
128     {
129         if (this == obj)
130             return true;
131         if (obj == null)
132             return false;
133         if (getClass() != obj.getClass())
134             return false;
135         Quotient other = (Quotient) obj;
136         return Objects.equals(this.denominator, other.denominator) && Objects.equals(this.numerator, other.numerator);
137     }
138 
139 }