LearningFactorFunctionFactory.java

  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.math4.neuralnet.sofm;

  18. import org.apache.commons.math4.neuralnet.internal.NeuralNetException;
  19. import org.apache.commons.math4.neuralnet.sofm.util.ExponentialDecayFunction;
  20. import org.apache.commons.math4.neuralnet.sofm.util.QuasiSigmoidDecayFunction;

  21. /**
  22.  * Factory for creating instances of {@link LearningFactorFunction}.
  23.  *
  24.  * @since 3.3
  25.  */
  26. public final class LearningFactorFunctionFactory {
  27.     /** Class contains only static methods. */
  28.     private LearningFactorFunctionFactory() {}

  29.     /**
  30.      * Creates an exponential decay {@link LearningFactorFunction function}.
  31.      * It will compute <code>a e<sup>-x / b</sup></code>,
  32.      * where {@code x} is the (integer) independent variable and
  33.      * <ul>
  34.      *  <li><code>a = initValue</code>
  35.      *  <li><code>b = -numCall / ln(valueAtNumCall / initValue)</code>
  36.      * </ul>
  37.      *
  38.      * @param initValue Initial value, i.e.
  39.      * {@link LearningFactorFunction#value(long) value(0)}.
  40.      * @param valueAtNumCall Value of the function at {@code numCall}.
  41.      * @param numCall Argument for which the function returns
  42.      * {@code valueAtNumCall}.
  43.      * @return the learning factor function.
  44.      * @throws IllegalArgumentException if {@code initValue <= 0},
  45.      * {@code initValue > 1} {@code valueAtNumCall <= 0},
  46.      * {@code valueAtNumCall >= initValue} or {@code numCall <= 0}.
  47.      */
  48.     public static LearningFactorFunction exponentialDecay(final double initValue,
  49.                                                           final double valueAtNumCall,
  50.                                                           final long numCall) {
  51.         if (initValue <= 0 ||
  52.             initValue > 1) {
  53.             throw new NeuralNetException(NeuralNetException.OUT_OF_RANGE, initValue, 0, 1);
  54.         }

  55.         return new LearningFactorFunction() {
  56.             /** DecayFunction. */
  57.             private final ExponentialDecayFunction decay
  58.                 = new ExponentialDecayFunction(initValue, valueAtNumCall, numCall);

  59.             /** {@inheritDoc} */
  60.             @Override
  61.             public double value(long n) {
  62.                 return decay.applyAsDouble(n);
  63.             }
  64.         };
  65.     }

  66.     /**
  67.      * Creates an sigmoid-like {@code LearningFactorFunction function}.
  68.      * The function {@code f} will have the following properties:
  69.      * <ul>
  70.      *  <li>{@code f(0) = initValue}</li>
  71.      *  <li>{@code numCall} is the inflexion point</li>
  72.      *  <li>{@code slope = f'(numCall)}</li>
  73.      * </ul>
  74.      *
  75.      * @param initValue Initial value, i.e.
  76.      * {@link LearningFactorFunction#value(long) value(0)}.
  77.      * @param slope Value of the function derivative at {@code numCall}.
  78.      * @param numCall Inflexion point.
  79.      * @return the learning factor function.
  80.      * @throws IllegalArgumentException if {@code initValue <= 0},
  81.      * {@code initValue > 1}, {@code slope >= 0} or {@code numCall <= 0}.
  82.      */
  83.     public static LearningFactorFunction quasiSigmoidDecay(final double initValue,
  84.                                                            final double slope,
  85.                                                            final long numCall) {
  86.         if (initValue <= 0 ||
  87.             initValue > 1) {
  88.             throw new NeuralNetException(NeuralNetException.OUT_OF_RANGE, initValue, 0, 1);
  89.         }

  90.         return new LearningFactorFunction() {
  91.             /** DecayFunction. */
  92.             private final QuasiSigmoidDecayFunction decay
  93.                 = new QuasiSigmoidDecayFunction(initValue, slope, numCall);

  94.             /** {@inheritDoc} */
  95.             @Override
  96.             public double value(long n) {
  97.                 return decay.applyAsDouble(n);
  98.             }
  99.         };
  100.     }
  101. }