001/*
002 * Java Genetic Algorithm Library (jenetics-8.1.0).
003 * Copyright (c) 2007-2024 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 */
020package io.jenetics.util;
021
022import static java.util.Objects.requireNonNull;
023
024import java.util.function.DoubleToIntFunction;
025import java.util.function.DoubleToLongFunction;
026import java.util.function.Function;
027import java.util.function.IntToDoubleFunction;
028import java.util.function.IntToLongFunction;
029import java.util.function.LongToDoubleFunction;
030import java.util.function.LongToIntFunction;
031
032/**
033 * This class contains methods for converting from and to the primitive arrays
034 * {@code int[]}, {@code long[]} and {@code double[]}. Its main usage is to
035 * unify numerical gene codecs, e.g.:
036 * {@snippet lang = java:
037 * final Codec<int[], DoubleGene> codec = Codecs
038 *     .ofVector(DoubleRange.of(0, 100), 100)
039 *     .map(Conversions::doubleToIntArray);
040 *}
041 *
042 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
043 * @version 8.1
044 * @since 8.1
045 */
046public class Conversions {
047
048        private Conversions() {
049        }
050
051        /**
052         * Converts the given {@code int[]} {@code array} to a {@code long[]} array.
053         *
054         * @param array the array to convert
055         * @param mapper the mapper function applied to each {@code array} element
056         * @return the converted array
057         */
058        public static long[] intToLongArray(
059                final int[] array,
060                final IntToLongFunction mapper
061        ) {
062                requireNonNull(array);
063                requireNonNull(mapper);
064
065                final long[] result = new long[array.length];
066                for (int i = 0; i < array.length; ++i) {
067                        result[i] = mapper.applyAsLong(array[i]);
068                }
069                return result;
070        }
071
072        /**
073         * Return an array mapper function which applies the given {@code mapper} to
074         * every array element.
075         *
076         * @param mapper the array element mapper
077         * @return an array mapper function
078         */
079        public static Function<int[], long[]>
080        intToLongFunction(final IntToLongFunction mapper) {
081                requireNonNull(mapper);
082                return array -> intToLongArray(array, mapper);
083        }
084
085        /**
086         * Converts the given {@code int[]} {@code array} to a {@code long[]} array.
087         *
088         * @param array the array to convert
089         * @return the converted array
090         */
091        public static long[] intToLongArray(final int[] array) {
092                return intToLongArray(array, i -> i);
093        }
094
095        /**
096         * Converts the given {@code int[]} {@code array} to a {@code double[]} array.
097         *
098         * @param array the array to convert
099         * @param mapper the mapper function applied to each {@code array} element
100         * @return the converted array
101         */
102        public static double[] intToDoubleArray(
103                final int[] array,
104                final IntToDoubleFunction mapper
105        ) {
106                requireNonNull(array);
107                requireNonNull(mapper);
108
109                final double[] result = new double[array.length];
110                for (int i = 0; i < array.length; ++i) {
111                        result[i] = mapper.applyAsDouble(array[i]);
112                }
113                return result;
114        }
115
116        /**
117         * Return an array mapper function which applies the given {@code mapper} to
118         * every array element.
119         *
120         * @param mapper the array element mapper
121         * @return an array mapper function
122         */
123        public static Function<int[], double[]>
124        intToDoubleArray(final IntToDoubleFunction mapper) {
125                requireNonNull(mapper);
126                return array -> intToDoubleArray(array, mapper);
127        }
128
129        /**
130         * Converts the given {@code int[]} {@code array} to a {@code double[]} array.
131         *
132         * @param array the array to convert
133         * @return the converted array
134         */
135        public static double[] intToDoubleArray(final int[] array) {
136                return intToDoubleArray(array, i -> i);
137        }
138
139        /**
140         * Converts the given {@code long[]} {@code array} to a {@code int[]} array.
141         *
142         * @param array the array to convert
143         * @param mapper the mapper function applied to each {@code array} element
144         * @return the converted array
145         */
146        public static int[] longToIntArray(
147                final long[] array,
148                final LongToIntFunction mapper
149        ) {
150                requireNonNull(array);
151                requireNonNull(mapper);
152
153                final int[] result = new int[array.length];
154                for (int i = 0; i < array.length; ++i) {
155                        result[i] = mapper.applyAsInt(array[i]);
156                }
157                return result;
158        }
159
160        /**
161         * Return an array mapper function which applies the given {@code mapper} to
162         * every array element.
163         *
164         * @param mapper the array element mapper
165         * @return an array mapper function
166         */
167        public static Function<long[], int[]>
168        longToIntArray(final LongToIntFunction mapper) {
169                requireNonNull(mapper);
170                return array -> longToIntArray(array, mapper);
171        }
172
173        /**
174         * Converts the given {@code long[]} {@code array} to a {@code int[]} array.
175         * The {@code int[]} is filled with the {@code long} values cast to
176         * {@code int} values.
177         *
178         * @param array the array to convert
179         * @return the converted array
180         */
181        public static int[] longToIntArray(final long[] array) {
182                return longToIntArray(array, l -> (int)l);
183        }
184
185        /**
186         * Converts the given {@code long[]} {@code array} to a {@code double[]} array.
187         *
188         * @param array the array to convert
189         * @param mapper the mapper function applied to each {@code array} element
190         * @return the converted array
191         */
192        public static double[] longToDoubleArray(
193                final long[] array,
194                final LongToDoubleFunction mapper
195        ) {
196                requireNonNull(array);
197                requireNonNull(mapper);
198
199                final double[] result = new double[array.length];
200                for (int i = 0; i < array.length; ++i) {
201                        result[i] = mapper.applyAsDouble(array[i]);
202                }
203                return result;
204        }
205
206        /**
207         * Return an array mapper function which applies the given {@code mapper} to
208         * every array element.
209         *
210         * @param mapper the array element mapper
211         * @return an array mapper function
212         */
213        public static Function<long[], double[]>
214        longToDoubleArray(final LongToDoubleFunction mapper) {
215                requireNonNull(mapper);
216                return array -> longToDoubleArray(array, mapper);
217        }
218
219        /**
220         * Converts the given {@code long[]} {@code array} to a {@code double[]} array.
221         *
222         * @param array the array to convert
223         * @return the converted array
224         */
225        public static double[] longToDoubleArray(final long[] array) {
226                return longToDoubleArray(array, l -> l);
227        }
228
229        /**
230         * Converts the given {@code double[]} {@code array} to a {@code int[]} array.
231         *
232         * @param array the array to convert
233         * @param mapper the mapper function applied to each {@code array} element
234         * @return the converted array
235         */
236        public static int[] doubleToIntArray(
237                final double[] array,
238                final DoubleToIntFunction mapper
239        ) {
240                requireNonNull(array);
241                requireNonNull(mapper);
242
243                final int[] result = new int[array.length];
244                for (int i = 0; i < array.length; ++i) {
245                        result[i] = mapper.applyAsInt(array[i]);
246                }
247                return result;
248        }
249
250        /**
251         * Return an array mapper function which applies the given {@code mapper} to
252         * every array element.
253         * {@snippet lang = java:
254         * final Codec<int[], DoubleGene> codec = Codecs
255         *     .ofVector(DoubleRange.of(0, 100), 100)
256         *     .map(Conversions.doubleToIntArray(v -> (int)Math.round(v)));
257         *}
258         *
259         * @param mapper the array element mapper
260         * @return an array mapper function
261         */
262        public static Function<double[], int[]>
263        doubleToIntArray(final DoubleToIntFunction mapper) {
264                requireNonNull(mapper);
265                return array -> doubleToIntArray(array, mapper);
266        }
267
268        /**
269         * Converts the given {@code long[]} {@code array} to a {@code double[]} array.
270         * The {@code int[]} is filled with the {@code double} values cast to
271         * {@code int} values.
272         *
273         * @param array the array to convert
274         * @return the converted array
275         */
276        public static int[] doubleToIntArray(final double[] array) {
277                return doubleToIntArray(array, l -> (int)l);
278        }
279
280        /**
281         * Converts the given {@code double[]} {@code array} to a {@code long[]} array.
282         *
283         * @param array the array to convert
284         * @param mapper the mapper function applied to each {@code array} element
285         * @return the converted array
286         */
287        public static long[] doubleToLongArray(
288                final double[] array,
289                final DoubleToLongFunction mapper
290        ) {
291                requireNonNull(array);
292                requireNonNull(mapper);
293
294                final long[] result = new long[array.length];
295                for (int i = 0; i < array.length; ++i) {
296                        result[i] = mapper.applyAsLong(array[i]);
297                }
298                return result;
299        }
300
301        /**
302         * Return an array mapper function which applies the given {@code mapper} to
303         * every array element.
304         *
305         * @param mapper the array element mapper
306         * @return an array mapper function
307         */
308        public static Function<double[], long[]>
309        doubleToLongArray(final DoubleToLongFunction mapper) {
310                requireNonNull(mapper);
311                return array -> doubleToLongArray(array, mapper);
312        }
313
314        /**
315         * Converts the given {@code long[]} {@code array} to a {@code double[]} array.
316         * The {@code long[]} is filled with the {@code double} values cast to
317         * {@code long} values.
318         *
319         * @param array the array to convert
320         * @return the converted array
321         */
322        public static long[] doubleToLongArray(final double[] array) {
323                return doubleToLongArray(array, d -> (long)d);
324        }
325
326}