Vec.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-6.3.0).
003  * Copyright (c) 2007-2021 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.ext.moea;
021 
022 import static io.jenetics.internal.math.Basics.clamp;
023 
024 import java.util.Comparator;
025 
026 /**
027  * The {@code Vec} interface represents the fitness result of a multi-objective
028  * fitness function. It also defines a set of static factory methods which
029  * allows you to create {@code Vec} instance from a given {@code int[]},
030  * {@code long[]} or {@code double[]} array.
031  *
032  <pre>{@code
033  * final Vec<double[]> point2D = Vec.of(0.1, 5.4);
034  * final Vec<int[]> point3D = Vec.of(1, 2, 3);
035  * }</pre>
036  *
037  * The underlying array is <em>just</em> wrapped and <em>not</em> copied. This
038  * means you can change the values of the {@code Vec} once it is created,
039  <em>Not copying the underlying array is done for performance reason. Changing
040  * the {@code Vec} data is, of course, never a good idea.</em>
041  *
042  * @implNote
043  * Although the {@code Vec} interface extends the {@link Comparable} interface,
044  * it violates its <em>general</em> contract. It <em>only</em>
045  * implements the pareto <em>dominance</em> relation, which defines a partial
046  * order. So, trying to sort a list of {@code Vec} objects, might lead
047  * to an exception (thrown by the sorting method) at runtime.
048  *
049  @param <T> the underlying array type, like {@code int[]} or {@code double[]}
050  *
051  @see VecFactory
052  @see <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
053  *     Pareto efficiency</a>
054  *
055  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
056  @version 4.1
057  @since 4.1
058  */
059 public interface Vec<T> extends Comparable<Vec<T>> {
060 
061     /**
062      * Return the underlying data structure.
063      *
064      @return the underlying data structure
065      */
066     T data();
067 
068     /**
069      * Return the number of vector elements.
070      *
071      @return the number of vector elements
072      */
073     int length();
074 
075     /**
076      * Return the comparator for comparing the elements of this MO vector.
077      *
078      @return the comparator for comparing the elements of this MO vector
079      */
080     ElementComparator<T> comparator();
081 
082     /**
083      * Return a function which calculates the element distance of a vector at a
084      * given element index.
085      *
086      @return a function which calculates the element distance of a vector at a
087      *         given element index
088      */
089     ElementDistance<T> distance();
090 
091     /**
092      * Return the comparator which defines the (Pareto) dominance measure.
093      *
094      @return the comparator which defines the (Pareto) dominance measure
095      */
096     Comparator<T> dominance();
097 
098 
099     /* *************************************************************************
100      * Default methods derived from the methods above.
101      * ************************************************************************/
102 
103     /**
104      * Compares the {@code this} vector with the {@code other} at the given
105      * component {@code index}.
106      *
107      @param other the other vector
108      @param index the component index
109      @return a negative integer, zero, or a positive integer as
110      *        {@code this[index]} is less than, equal to, or greater than
111      *        {@code other[index]}
112      @throws NullPointerException if the {@code other} object is {@code null}
113      @throws IllegalArgumentException if the {@code index} is out of the valid
114      *         range {@code [0, length())}
115      */
116     default int compare(final Vec<T> other, final int index) {
117         return comparator().compare(data(), other.data(), index);
118     }
119 
120     /**
121      * Calculates the distance between two vector elements at the given
122      * {@code index}.
123      *
124      @param other the second vector
125      @param index the vector element index
126      @return the distance between two vector elements
127      @throws NullPointerException if the {@code other} vector is {@code null}
128      @throws IllegalArgumentException if the {@code index} is out of the valid
129      *         range {@code [0, length())}
130      */
131     default double distance(final Vec<T> other, final int index) {
132         return distance().distance(data(), other.data(), index);
133     }
134 
135     /**
136      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
137      <b>Pareto Dominance</b></a> of vector {@code value()} and {@code other}.
138      *
139      @param other the other vector
140      @return {@code 1} if <b>value()</b> ≻ <b>other</b>, {@code -1} if
141      *         <b>other</b> ≻ <b>value()</b> and {@code 0} otherwise
142      @throws NullPointerException if the {@code other} vector is {@code null}
143      */
144     default int dominance(final Vec<T> other) {
145         return dominance().compare(data(), other.data());
146     }
147 
148     /**
149      * The default implementation uses the {@link #dominance(Vec)} function
150      * for defining a <b>partial</b> order of two vectors.
151      *
152      @param other the other vector
153      @return {@code 1} if <b>value()</b> ≻ <b>other</b>, {@code -1} if
154      *         <b>other</b> ≻ <b>value()</b> and {@code 0} otherwise
155      @throws NullPointerException if the {@code other} vector is {@code null}
156      */
157     @Override
158     default int compareTo(final Vec<T> other) {
159         return dominance(other);
160     }
161 
162 
163     /* *************************************************************************
164      * Common 'dominance' methods.
165      * ************************************************************************/
166 
167     /**
168      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
169      *     <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
170      *
171      @see Pareto#dominance(Comparable[], Comparable[])
172      *
173      @param u the first vector
174      @param v the second vector
175      @param <C> the element type of vector <b>u</b> and <b>v</b>
176      @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> 
177      *         <b>u</b> and {@code 0} otherwise
178      @throws NullPointerException if one of the arguments is {@code null}
179      @throws IllegalArgumentException if {@code u.length != v.length}
180      */
181     static <C extends Comparable<? super C>> int
182     dominance(final C[] u, final C[] v) {
183         return dominance(u, v, Comparator.naturalOrder());
184     }
185 
186     /**
187      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
188      *     <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
189      *
190      @see Pareto#dominance(Object[], Object[], Comparator)
191      *
192      @param u the first vector
193      @param v the second vector
194      @param comparator the element comparator which is used for calculating
195      *        the dominance
196      @param <T> the element type of vector <b>u</b> and <b>v</b>
197      @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> 
198      *         <b>u</b> and {@code 0} otherwise
199      @throws NullPointerException if one of the arguments is {@code null}
200      @throws IllegalArgumentException if {@code u.length != v.length}
201      */
202     static <T> int
203     dominance(final T[] u, final T[] v, final Comparator<? super T> comparator) {
204         return Pareto.dominance(u, v, comparator);
205     }
206 
207     /**
208      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
209      *     <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
210      *
211      @see Pareto#dominance(int[], int[])
212      *
213      @param u the first vector
214      @param v the second vector
215      @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> 
216      *         <b>u</b> and {@code 0} otherwise
217      @throws NullPointerException if one of the arguments is {@code null}
218      @throws IllegalArgumentException if {@code u.length != v.length}
219      */
220     static int dominance(final int[] u, final int[] v) {
221         return Pareto.dominance(u, v);
222     }
223 
224     /**
225      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
226      *     <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
227      *
228      @see Pareto#dominance(long[], long[])
229      *
230      @param u the first vector
231      @param v the second vector
232      @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> 
233      *         <b>u</b> and {@code 0} otherwise
234      @throws NullPointerException if one of the arguments is {@code null}
235      @throws IllegalArgumentException if {@code u.length != v.length}
236      */
237     static int dominance(final long[] u, final long[] v) {
238         return Pareto.dominance(u, v);
239     }
240 
241     /**
242      * Calculates the <a href="https://en.wikipedia.org/wiki/Pareto_efficiency">
243      *     <b>Pareto Dominance</b></a> of the two vectors <b>u</b> and <b>v</b>.
244      *
245      @see Pareto#dominance(double[], double[])
246      *
247      @param u the first vector
248      @param v the second vector
249      @return {@code 1} if <b>u</b> ≻ <b>v</b>, {@code -1} if <b>v</b> 
250      *         <b>u</b> and {@code 0} otherwise
251      @throws NullPointerException if one of the arguments is {@code null}
252      @throws IllegalArgumentException if {@code u.length != v.length}
253      */
254     static int dominance(final double[] u, final double[] v) {
255         return Pareto.dominance(u, v);
256     }
257 
258     /* *************************************************************************
259      * Static factory functions for wrapping ordinary arrays.
260      * ************************************************************************/
261 
262     /**
263      * Wraps the given array into a {@code Vec} object.
264      *
265      @param array the wrapped array
266      @param <C> the array element type
267      @return the given array wrapped into a {@code Vec} object.
268      @throws NullPointerException if one of the arguments is {@code null}
269      @throws IllegalArgumentException if the {@code array} length is zero
270      */
271     static <C extends Comparable<? super C>>
272     Vec<C[]> of(final C[] array) {
273         return of(
274             array,
275             (u, v, i-> clamp(u[i].compareTo(v[i]), -11)
276         );
277     }
278 
279     /**
280      * Wraps the given array into a {@code Vec} object.
281      *
282      @param array the wrapped array
283      @param distance the array element distance measure
284      @param <C> the array element type
285      @return the given array wrapped into a {@code Vec} object.
286      @throws NullPointerException if one of the arguments is {@code null}
287      @throws IllegalArgumentException if the {@code array} length is zero
288      */
289     static <C extends Comparable<? super C>> Vec<C[]> of(
290         final C[] array,
291         final ElementDistance<C[]> distance
292     ) {
293         return of(array, Comparator.naturalOrder(), distance);
294     }
295 
296     /**
297      * Wraps the given array into a {@code Vec} object.
298      *
299      @param array the wrapped array
300      @param comparator the (natural order) comparator of the array elements
301      @param distance the distance function between two vector elements
302      @param <T> the array element type
303      @return the given array wrapped into a {@code Vec} object.
304      @throws NullPointerException if one of the arguments is {@code null}
305      @throws IllegalArgumentException if the {@code array} length is zero
306      */
307     static <T> Vec<T[]> of(
308         final T[] array,
309         final Comparator<? super T> comparator,
310         final ElementDistance<T[]> distance
311     ) {
312         return new SimpleObjectVec<>(array, comparator, distance);
313     }
314 
315     /**
316      * Wraps the given array into a {@code Vec} object.
317      *
318      @param array the wrapped array
319      @return the given array wrapped into a {@code Vec} object.
320      @throws NullPointerException if the given {@code array} is {@code null}
321      @throws IllegalArgumentException if the {@code array} length is zero
322      */
323     static Vec<int[]> of(final int... array) {
324         return new SimpleIntVec(array);
325     }
326 
327     /**
328      * Wraps the given array into a {@code Vec} object.
329      *
330      @param array the wrapped array
331      @return the given array wrapped into a {@code Vec} object.
332      @throws NullPointerException if the given {@code array} is {@code null}
333      @throws IllegalArgumentException if the {@code array} length is zero
334      */
335     static Vec<long[]> of(final long... array) {
336         return new SimpleLongVec(array);
337     }
338 
339     /**
340      * Wraps the given array into a {@code Vec} object.
341      *
342      @param array the wrapped array
343      @return the given array wrapped into a {@code Vec} object.
344      @throws NullPointerException if the given {@code array} is {@code null}
345      @throws IllegalArgumentException if the {@code array} length is zero
346      */
347     static Vec<double[]> of(final double... array) {
348         return new SimpleDoubleVec(array);
349     }
350 
351 }