GradientField.java

  1. /*
  2.  * Licensed to the Hipparchus project 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 Hipparchus project 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.  *      https://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.hipparchus.analysis.differentiation;

  18. import java.util.concurrent.atomic.AtomicReference;

  19. import org.hipparchus.Field;
  20. import org.hipparchus.util.FastMath;

  21. /** Field for {@link Gradient} instances.
  22.  * @since 1.7
  23.  */
  24. public class GradientField implements Field<Gradient> {

  25.     /** Array of all fields created so far. */
  26.     private static AtomicReference<GradientField[]> fields = new AtomicReference<>(null);

  27.     /** Zero constant. */
  28.     private final Gradient zero;

  29.     /** One constant. */
  30.     private final Gradient one;

  31.     /** Associated factory for conversions to {@link DerivativeStructure}. */
  32.     private final DSFactory factory;

  33.     /** Private constructor.
  34.      * @param parameters number of free parameters
  35.      */
  36.     private GradientField(final int parameters) {
  37.         zero    = new Gradient(0.0, new double[parameters]);
  38.         one     = new Gradient(1.0, new double[parameters]);
  39.         factory = new DSFactory(parameters, 1);
  40.     }

  41.     /** Get the field for number of free parameters.
  42.      * @param parameters number of free parameters
  43.      * @return cached field
  44.      */
  45.     public static GradientField getField(int parameters) {

  46.         // get the cached fields
  47.         final GradientField[] cache = fields.get();
  48.         if (cache != null && cache.length > parameters && cache[parameters] != null) {
  49.             // the field has already been created
  50.             return cache[parameters];
  51.         }

  52.         // we need to create a new field
  53.         final int maxParameters = FastMath.max(parameters, cache == null ? 0 : cache.length);
  54.         final GradientField[] newCache = new GradientField[maxParameters + 1];

  55.         if (cache != null) {
  56.             // preserve the already created fields
  57.             System.arraycopy(cache, 0, newCache, 0, cache.length);
  58.         }

  59.         // create the new field
  60.         newCache[parameters] = new GradientField(parameters);

  61.         // atomically reset the cached fileds array
  62.         fields.compareAndSet(cache, newCache);

  63.         return newCache[parameters];

  64.     }

  65.     /** {@inheritDoc} */
  66.     @Override
  67.     public Gradient getOne() {
  68.         return one;
  69.     }

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public Gradient getZero() {
  73.         return zero;
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public Class<Gradient> getRuntimeClass() {
  78.         return Gradient.class;
  79.     }

  80.     /** Get the factory for converting to {@link DerivativeStructure}.
  81.      * <p>
  82.      * This factory is used only for conversions. {@code Gradient} by
  83.      * itself does not rely at all on {@link DSFactory}, {@link DSCompiler}
  84.      * or {@link DerivativeStructure} for its computation. For this reason,
  85.      * the factory here is hidden and this method is package private, so
  86.      * only {@link Gradient#toDerivativeStructure()} can call it on an
  87.      * existing {@link Gradient} instance
  88.      * </p>
  89.      * @return factory for conversions
  90.      */
  91.     DSFactory getConversionFactory() {
  92.         return factory;
  93.     }

  94.     /** {@inheritDoc} */
  95.     @Override
  96.     public boolean equals(final Object other) {
  97.         return this == other;
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public int hashCode() {
  102.         return 0x26ca1af0;
  103.     }

  104. }