FieldGradientField.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.lang.reflect.Array;
  19. import java.util.HashMap;
  20. import java.util.Map;

  21. import org.hipparchus.CalculusFieldElement;
  22. import org.hipparchus.Field;
  23. import org.hipparchus.util.MathArrays;

  24. /** Field for {@link Gradient} instances.
  25.  * @param <T> the type of the function parameters and value
  26.  * @since 1.7
  27.  */
  28. public class FieldGradientField<T extends CalculusFieldElement<T>> implements Field<FieldGradient<T>> {

  29.     /** Cached fields. */
  30.     private static final Map<Field<?>, FieldGradientField<?>[]> CACHE = new HashMap<>();

  31.     /** Zero constant. */
  32.     private final FieldGradient<T> zero;

  33.     /** One constant. */
  34.     private final FieldGradient<T> one;

  35.     /** Associated factory for conversions to {@link DerivativeStructure}. */
  36.     private final FDSFactory<T> factory;

  37.     /** Private constructor.
  38.      * @param valueField field for the function parameters and value
  39.      * @param parameters number of free parameters
  40.      */
  41.     private FieldGradientField(final Field<T> valueField, final int parameters) {
  42.         zero    = new FieldGradient<>(valueField.getZero(), MathArrays.buildArray(valueField, parameters));
  43.         one     = new FieldGradient<>(valueField.getOne(), MathArrays.buildArray(valueField, parameters));
  44.         factory = new FDSFactory<>(valueField, parameters, 1);
  45.     }

  46.     /** Get the field for number of free parameters.
  47.      * @param valueField field for the function parameters and value
  48.      * @param parameters number of free parameters
  49.      * @param <T> the type of the function parameters and value
  50.      * @return cached field
  51.      */
  52.     public static <T extends CalculusFieldElement<T>> FieldGradientField<T> getField(final Field<T> valueField, final int parameters) {

  53.         FieldGradientField<?>[] cachedFields;
  54.         synchronized (CACHE) {
  55.             cachedFields = CACHE.get(valueField);
  56.             if (cachedFields == null || cachedFields.length <= parameters) {
  57.                 FieldGradientField<?>[] newCachedFields =
  58.                                 (FieldGradientField<?>[]) Array.newInstance(FieldGradientField.class, parameters + 1);
  59.                 if (cachedFields != null) {
  60.                     // preserve the already created fields
  61.                     System.arraycopy(cachedFields, 0, newCachedFields, 0, cachedFields.length);
  62.                 }
  63.                 cachedFields = newCachedFields;
  64.                 CACHE.put(valueField, cachedFields);
  65.             }
  66.         }

  67.         if (cachedFields[parameters] == null) {
  68.             // we need to create a new field
  69.             cachedFields[parameters] = new FieldGradientField<>(valueField, parameters);
  70.         }

  71.         @SuppressWarnings("unchecked")
  72.         final FieldGradientField<T> tCached = (FieldGradientField<T>) cachedFields[parameters];
  73.         return tCached;

  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public FieldGradient<T>  getOne() {
  78.         return one;
  79.     }

  80.     /** {@inheritDoc} */
  81.     @Override
  82.     public FieldGradient<T>  getZero() {
  83.         return zero;
  84.     }

  85.     /** {@inheritDoc} */
  86.     @SuppressWarnings("unchecked")
  87.     @Override
  88.     public Class<FieldGradient<T>> getRuntimeClass() {
  89.         return (Class<FieldGradient<T>>) getZero().getClass();
  90.     }

  91.     /** Get the factory for converting to {@link DerivativeStructure}.
  92.      * <p>
  93.      * This factory is used only for conversions. {@code Gradient} by
  94.      * itself does not rely at all on {@link DSFactory}, {@link DSCompiler}
  95.      * or {@link DerivativeStructure} for its computation. For this reason,
  96.      * the factory here is hidden and this method is package private, so
  97.      * only {@link Gradient#toDerivativeStructure()} can call it on an
  98.      * existing {@link Gradient} instance
  99.      * </p>
  100.      * @return factory for conversions
  101.      */
  102.     FDSFactory<T> getConversionFactory() {
  103.         return factory;
  104.     }

  105.     /** {@inheritDoc} */
  106.     @Override
  107.     public boolean equals(final Object other) {
  108.         return this == other;
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public int hashCode() {
  113.         return 0xcd3e92ee;
  114.     }

  115. }