View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math4.legacy.fitting.leastsquares;
19  
20  import java.awt.geom.Point2D;
21  
22  import org.apache.commons.statistics.distribution.NormalDistribution;
23  import org.apache.commons.statistics.distribution.ContinuousDistribution;
24  import org.apache.commons.statistics.distribution.UniformContinuousDistribution;
25  import org.apache.commons.rng.UniformRandomProvider;
26  import org.apache.commons.rng.simple.RandomSource;
27  
28  /**
29   * Factory for generating a cloud of points that approximate a straight line.
30   */
31  public class RandomStraightLinePointGenerator {
32      /** Slope. */
33      private final double slope;
34      /** Intercept. */
35      private final double intercept;
36      /** RNG for the x-coordinate. */
37      private final ContinuousDistribution.Sampler x;
38      /** RNG for the error on the y-coordinate. */
39      private final ContinuousDistribution.Sampler error;
40  
41      /**
42       * The generator will create a cloud of points whose x-coordinates
43       * will be randomly sampled between {@code xLo} and {@code xHi}, and
44       * the corresponding y-coordinates will be computed as
45       * <pre><code>
46       *  y = a x + b + N(0, error)
47       * </code></pre>
48       * where {@code N(mean, sigma)} is a Gaussian distribution with the
49       * given mean and standard deviation.
50       *
51       * @param a Slope.
52       * @param b Intercept.
53       * @param sigma Standard deviation on the y-coordinate of the point.
54       * @param lo Lowest value of the x-coordinate.
55       * @param hi Highest value of the x-coordinate.
56       * @param seed RNG seed.
57       */
58      public RandomStraightLinePointGenerator(double a,
59                                              double b,
60                                              double sigma,
61                                              double lo,
62                                              double hi,
63                                              long seed) {
64          final UniformRandomProvider rng = RandomSource.WELL_44497_B.create(seed);
65          slope = a;
66          intercept = b;
67          error = NormalDistribution.of(0, sigma).createSampler(rng);
68          x = UniformContinuousDistribution.of(lo, hi).createSampler(rng);
69      }
70  
71      /**
72       * Point generator.
73       *
74       * @param n Number of points to create.
75       * @return the cloud of {@code n} points.
76       */
77      public Point2D.Double[] generate(int n) {
78          final Point2D.Double[] cloud = new Point2D.Double[n];
79          for (int i = 0; i < n; i++) {
80              cloud[i] = create();
81          }
82          return cloud;
83      }
84  
85      /**
86       * Create one point.
87       *
88       * @return a point.
89       */
90      private Point2D.Double create() {
91          final double abscissa = x.sample();
92          final double yModel = slope * abscissa + intercept;
93          final double ordinate = yModel + error.sample();
94  
95          return new Point2D.Double(abscissa, ordinate);
96      }
97  }