View Javadoc
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  
19  import java.util.concurrent.atomic.AtomicReference;
20  
21  import org.hipparchus.Field;
22  import org.hipparchus.util.FastMath;
23  
24  /** Field for {@link Gradient} instances.
25   * @since 1.7
26   */
27  public class GradientField implements Field<Gradient> {
28  
29      /** Array of all fields created so far. */
30      private static AtomicReference<GradientField[]> fields = new AtomicReference<>(null);
31  
32      /** Zero constant. */
33      private final Gradient zero;
34  
35      /** One constant. */
36      private final Gradient one;
37  
38      /** Associated factory for conversions to {@link DerivativeStructure}. */
39      private final DSFactory factory;
40  
41      /** Private constructor.
42       * @param parameters number of free parameters
43       */
44      private GradientField(final int parameters) {
45          zero    = new Gradient(0.0, new double[parameters]);
46          one     = new Gradient(1.0, new double[parameters]);
47          factory = new DSFactory(parameters, 1);
48      }
49  
50      /** Get the field for number of free parameters.
51       * @param parameters number of free parameters
52       * @return cached field
53       */
54      public static GradientField getField(int parameters) {
55  
56          // get the cached fields
57          final GradientField[] cache = fields.get();
58          if (cache != null && cache.length > parameters && cache[parameters] != null) {
59              // the field has already been created
60              return cache[parameters];
61          }
62  
63          // we need to create a new field
64          final int maxParameters = FastMath.max(parameters, cache == null ? 0 : cache.length);
65          final GradientField[] newCache = new GradientField[maxParameters + 1];
66  
67          if (cache != null) {
68              // preserve the already created fields
69              System.arraycopy(cache, 0, newCache, 0, cache.length);
70          }
71  
72          // create the new field
73          newCache[parameters] = new GradientField(parameters);
74  
75          // atomically reset the cached fileds array
76          fields.compareAndSet(cache, newCache);
77  
78          return newCache[parameters];
79  
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public Gradient getOne() {
85          return one;
86      }
87  
88      /** {@inheritDoc} */
89      @Override
90      public Gradient getZero() {
91          return zero;
92      }
93  
94      /** {@inheritDoc} */
95      @Override
96      public Class<Gradient> getRuntimeClass() {
97          return Gradient.class;
98      }
99  
100     /** Get the factory for converting to {@link DerivativeStructure}.
101      * <p>
102      * This factory is used only for conversions. {@code Gradient} by
103      * itself does not rely at all on {@link DSFactory}, {@link DSCompiler}
104      * or {@link DerivativeStructure} for its computation. For this reason,
105      * the factory here is hidden and this method is package private, so
106      * only {@link Gradient#toDerivativeStructure()} can call it on an
107      * existing {@link Gradient} instance
108      * </p>
109      * @return factory for conversions
110      */
111     DSFactory getConversionFactory() {
112         return factory;
113     }
114 
115     /** {@inheritDoc} */
116     @Override
117     public boolean equals(final Object other) {
118         return this == other;
119     }
120 
121     /** {@inheritDoc} */
122     @Override
123     public int hashCode() {
124         return 0x26ca1af0;
125     }
126 
127 }