/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math4.legacy.optim.nonlinear.scalar;

import java.util.function.Function;
import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.core.jdkmath.AccurateMath;

/**
 * Multivariate scalar functions for testing an optimizer.
 */
public enum TestFunction {
    // https://www.sfu.ca/~ssurjano/spheref.html
    SPHERE(dim -> {
            return x -> {
                double f = 0;
                for (int i = 0; i < dim; i++) {
                    f += x[i] * x[i];
                }
                return f;
            };
        }),
    CIGAR(dim -> {
            return x -> {
                double f = x[0] * x[0];
                for (int i = 1; i < dim; i++) {
                    f += 1e3 * x[i] * x[i];
                }
                return f;
            };
        }),
    TABLET(dim -> {
            return x -> {
                double f = 1e3 * x[0] * x[0];
                for (int i = 1; i < dim; i++) {
                    f += x[i] * x[i];
                }
                return f;
            };
        }),
    CIG_TAB(dim -> {
            final double factor = 1e4;
            final int last = dim - 1;
            return x -> {
                double f = x[0] * x[0] / factor + factor * x[last] * x[last];
                for (int i = 1; i < last; i++) {
                    f += x[i] * x[i];
                }
                return f;
            };
        }),
    TWO_AXES(dim -> {
            return x -> {
                double f = 0;
                for (int i = 0; i < dim; i++) {
                    f += (i < dim / 2 ? 1e6 : 1) * x[i] * x[i];
                }
                return f;
            };
        }),
    ELLI(dim -> {
            final double last = dim - 1;
            return x -> {
                double f = 0;
                for (int i = 0; i < dim; i++) {
                    f += Math.pow(1e3, i / last) * x[i] * x[i];
                }
                return f;
            };
        }),
    MINUS_ELLI(dim -> {
            final MultivariateFunction elli = ELLI.withDimension(dim);
            return x -> {
                return 1 - elli.value(x);
            };
        }),
    // https://www.sfu.ca/~ssurjano/sumpow.html
    DIFF_POW(dim -> {
            return x -> {
                double f = 0;
                for (int i = 0; i < dim; i++) {
                    f += AccurateMath.pow(Math.abs(x[i]), i + 2);
                }
                return f;
            };
        }),
    SS_DIFF_POW(dim -> {
            final MultivariateFunction diffPow = DIFF_POW.withDimension(dim);
            return x -> {
                double f = Math.pow(diffPow.value(x), 0.25);
                return f;
            };
        }),
    // https://www.sfu.ca/~ssurjano/ackley.html
    ACKLEY(dim -> {
            final double A = 20;
            final double B = 0.2;
            final double C = 2 * Math.PI;
            return x -> {
                double acc1 = 0;
                double acc2 = 0;
                for (int i = 0; i < dim; i++) {
                    final double v = x[i];
                    acc1 += v * v;
                    acc2 += Math.cos(C * v);
                }
                acc1 = -B * Math.sqrt(acc1 / dim);
                acc2 /= dim;

                return -A * Math.exp(acc1) - Math.exp(acc2) + A + Math.E;
            };
        }),
    // https://www.sfu.ca/~ssurjano/rastr.html
    RASTRIGIN(dim -> {
            final double A = 10;
            return x -> {
                double sum = 0;
                for (int i = 0; i < dim; i++) {
                    final double xi = x[i];
                    sum += xi * xi - A * Math.cos(2 * Math.PI * xi);
                }
                return A * dim + sum;
            };
        }),
    // https://www.sfu.ca/~ssurjano/powell.html
    POWELL(dim -> {
            final int last = dim / 4;
            return x -> {
                double f = 0;
                for (int i = 0; i < last; i++) {
                    final int fourI = 4 * i;
                    final double x4i = x[fourI];
                    final double x4iP1 = x[fourI + 1];
                    final double x4iP2 = x[fourI + 2];
                    final double x4iP3 = x[fourI + 3];
                    final double a = x4i + 10 * x4iP1;
                    final double b = x4iP2 - x4iP3;
                    final double c = x4iP1 - 2 * x4iP2;
                    final double d = x4i - x4iP3;
                    f += a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
                }
                return f;
            };
        }),
    ROSENBROCK(dim -> {
            final int last = dim - 1;
            return x -> {
                double f = 0;
                for (int i = 0; i < last; i++) {
                    final double xi = x[i];
                    final double xiP1 = x[i + 1];
                    final double a = xiP1 - xi * xi;
                    final double b = xi - 1;
                    f += 1e2 * a * a + b * b;
                }
                return f;
            };
        }),
    PARABOLA(dim -> {
            return x -> {
                double f = 0;
                for (int i = 0; i < dim; i++) {
                    final double xi = x[i];
                    f += xi * xi;
                }
                return f;
            };
        });

    /** Template for variable dimension. */
    private final Function<Integer, MultivariateFunction> generator;

    /**
     * @param gen Template for variable dimension.
     */
    TestFunction(Function<Integer, MultivariateFunction> gen) {
        generator = gen;
    }

    /**
     * @param dim Dimension.
     * @return the function for the given dimension.
     */
    public MultivariateFunction withDimension(final int dim) {
        return new MultivariateFunction() {
            /** Delegate. */
            private final MultivariateFunction f = generator.apply(dim);

            @Override
            public double value(double[] x) {
                if (x.length != dim) {
                    throw new IllegalArgumentException("Dimension mismatch: " + x.length +
                                                       "(expected: " + dim + ")");
                }
                return f.value(x);
            };

            @Override
            public String toString() {
                final StringBuilder sb = new StringBuilder();
                sb.append("[")
                    .append(TestFunction.this.toString())
                    .append(" dim=")
                    .append(dim)
                    .append("]");
                return sb.toString();
            }
        };
    }
}
