NeighbourhoodSizeFunctionFactory.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.sofm.util.ExponentialDecayFunction;
  19. import org.apache.commons.math4.neuralnet.sofm.util.QuasiSigmoidDecayFunction;

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

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

  54.             /** {@inheritDoc} */
  55.             @Override
  56.             public int value(long n) {
  57.                 return (int) Math.rint(decay.applyAsDouble(n));
  58.             }
  59.         };
  60.     }

  61.     /**
  62.      * Creates an sigmoid-like {@code NeighbourhoodSizeFunction function}.
  63.      * The function {@code f} will have the following properties:
  64.      * <ul>
  65.      *  <li>{@code f(0) = initValue}</li>
  66.      *  <li>{@code numCall} is the inflexion point</li>
  67.      *  <li>{@code slope = f'(numCall)}</li>
  68.      * </ul>
  69.      *
  70.      * @param initValue Initial value, i.e.
  71.      * {@link NeighbourhoodSizeFunction#value(long) value(0)}.
  72.      * @param slope Value of the function derivative at {@code numCall}.
  73.      * @param numCall Inflexion point.
  74.      * @return the neighbourhood size function.
  75.      * @throws IllegalArgumentException if {@code initValue <= 0},
  76.      * {@code slope >= 0} or {@code numCall <= 0}.
  77.      */
  78.     public static NeighbourhoodSizeFunction quasiSigmoidDecay(final double initValue,
  79.                                                               final double slope,
  80.                                                               final long numCall) {
  81.         return new NeighbourhoodSizeFunction() {
  82.             /** DecayFunction. */
  83.             private final QuasiSigmoidDecayFunction decay
  84.                 = new QuasiSigmoidDecayFunction(initValue, slope, numCall);

  85.             /** {@inheritDoc} */
  86.             @Override
  87.             public int value(long n) {
  88.                 return (int) Math.rint(decay.applyAsDouble(n));
  89.             }
  90.         };
  91.     }
  92. }