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