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  package org.apache.commons.statistics.examples.distribution;
18  
19  import java.util.List;
20  import java.util.concurrent.Callable;
21  import org.apache.commons.statistics.distribution.DiscreteDistribution;
22  import picocli.CommandLine.Mixin;
23  
24  /**
25   * Base command for a discrete distribution.
26   *
27   * <p>Sub-classes are assumed to have a name that corresponds to the command to action.
28   * Typically this is a function value in the {@link DistributionFunction} enum. The
29   * distribution will be evaluated for this function using the points defined by the
30   * {@link DistributionOptions}.
31   *
32   * <p>Alternatively the sub-class name may indicate a special command to execute.
33   *
34   * <p>Sub-classes must provide the list of distributions to evaluate and options for the
35   * evaluation.
36   */
37  abstract class AbstractDiscreteDistributionCommand implements Callable<Void> {
38      /** The standard options. */
39      @Mixin
40      private StandardOptions standardOptions;
41  
42      @Override
43      public Void call() {
44          final List<Distribution<DiscreteDistribution>> distributions = getDistributions();
45          final DistributionOptions distributionOptions = getDistributionOptions();
46          // Set the function based on the class name
47          final String name = getClass().getSimpleName();
48  
49          // Special handling of sub-classes which do not evaluate a function of the distribution.
50          // This is done here to avoid duplicating an overridden 'call()' method for each instance.
51          // Currently this applies to a hidden 'check' command that performs verification checks
52          // on the distribution.
53          if ("Check".equals(name)) {
54              // This is not an evaluation of a single function.
55              DistributionUtils.check(distributions,
56                  (DiscreteDistributionOptions) distributionOptions);
57              return null;
58          }
59  
60          // Assume an evaluation of a distribution function
61          distributionOptions.distributionFunction = DistributionFunction.valueOf(name);
62          // Assume there are only two types of options:
63          // Forward functions: x (int) -> p-value
64          // Inverse functions: p-value -> x (int)
65          if (distributionOptions instanceof InverseDiscreteDistributionOptions) {
66              DistributionUtils.evaluate(distributions,
67                  (InverseDiscreteDistributionOptions) distributionOptions);
68          } else {
69              DistributionUtils.evaluate(distributions,
70                  (DiscreteDistributionOptions) distributionOptions);
71          }
72          return null;
73      }
74  
75      /**
76       * Gets the distributions to evaluate.
77       *
78       * @return the distributions
79       */
80      protected abstract List<Distribution<DiscreteDistribution>> getDistributions();
81  
82      /**
83       * Gets the distribution options.
84       * This will define the points to evaluate, and the output options.
85       *
86       * @return the distribution options
87       */
88      protected abstract DistributionOptions getDistributionOptions();
89  }