001/*
002 * Java Genetic Algorithm Library (jenetics-7.2.0).
003 * Copyright (c) 2007-2023 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.prog.regression;
021
022/**
023 * Represents a sample point used for the symbolic regression task. It consists
024 * of an argument array and a result value. The sample point is comparable
025 * according its {@link #result()} value.
026 *
027 * @implSpec
028 * The dimensionality of the sample point must be at least one, which means
029 * {@code arity() >= 1}.
030 *
031 * @param <T> the sample type
032 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
033 * @version 5.0
034 * @since 5.0
035 */
036public interface Sample<T> {
037
038        /**
039         * Return the dimensionality of the sample point arguments.
040         *
041         * @return the arity of the sample point
042         */
043        int arity();
044
045        /**
046         * Return the argument value with the given {@code index}.
047         *
048         * @see #arity()
049         *
050         * @param index the argument index
051         * @return the argument value with the given {@code index}
052         * @throws ArrayIndexOutOfBoundsException if the given {@code index} is not
053         *         within the given range {@code [0, arity)}
054         */
055        T argAt(final int index);
056
057        /**
058         * Return the result of the sample point.
059         *
060         * @return the result of the sample point
061         */
062        T result();
063
064
065        /* *************************************************************************
066         * Static factory methods.
067         * ************************************************************************/
068
069        /**
070         * Create a new sample point from the given argument and sample result. It
071         * represents the function arguments with the function value:
072         * {@code f: sample[0:sample.length-1] -> sample[sample.length-1]}. The last
073         * array element contains the result, and the first n-1 elements are function
074         * arguments.
075         *
076         * @param <T> the sample type
077         * @param sample the sample point result
078         * @return a new sample point
079         * @throws IllegalArgumentException if the argument array is empty
080         * @throws NullPointerException if the argument array is {@code null}
081         */
082        static <T> Sample<T> of(final T[] sample) {
083                return new ObjectSample<>(sample.clone());
084        }
085
086        /**
087         * Create a new sample point from the given argument and sample result. It
088         * represents the function arguments with the function value:
089         * {@code f: x -> y}
090         *
091         * @param x the argument
092         * @param y the sample point result
093         * @return a new sample point
094         */
095        static Sample<Double> ofDouble(final double x, final double y) {
096                return new DoubleSample(x, y);
097        }
098
099        /**
100         * Create a new sample point from the given argument and sample result. It
101         * represents the function arguments with the function value:
102         * {@code f: (x1, x2) -> y}
103         *
104         * @param x1 the first argument
105         * @param x2 the second argument
106         * @param y the sample point result
107         * @return a new sample point
108         */
109        static Sample<Double> ofDouble(
110                final double x1,
111                final double x2,
112                final double y
113        ) {
114                return new DoubleSample(x1, x2, y);
115        }
116
117        /**
118         * Create a new sample point from the given argument and sample result. It
119         * represents the function arguments with the function value:
120         * {@code f: (x1, x2, x3) -> y}
121         *
122         * @param x1 the first argument
123         * @param x2 the second argument
124         * @param x3 the second argument
125         * @param y the sample point result
126         * @return a new sample point
127         */
128        static Sample<Double> ofDouble(
129                final double x1,
130                final double x2,
131                final double x3,
132                final double y
133        ) {
134                return new DoubleSample(x1, x2, x3, y);
135        }
136
137}