Tuple.java
- /*
- * Licensed to the Hipparchus project under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The Hipparchus project 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
- *
- * https://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.hipparchus.util;
- import java.util.Arrays;
- import org.hipparchus.CalculusFieldElement;
- import org.hipparchus.Field;
- import org.hipparchus.exception.MathIllegalArgumentException;
- /**
- * This class allows to perform the same computation of all components of a Tuple at once.
- * @since 1.2
- */
- public class Tuple implements CalculusFieldElement<Tuple> {
- /** Components of the tuple. */
- private final double[] values;
- /** Field the instance belongs to. */
- private final transient TupleField field;
- /** Creates a new instance from its components.
- * @param x components of the tuple
- */
- public Tuple(final double... x) {
- this(new TupleField(x.length), x.clone());
- }
- /** Creates a new instance from its components.
- * @param field field the instance belongs to
- * @param x components of the tuple (beware, it is <em>not</em> copied, it is shared with caller)
- */
- private Tuple(final TupleField field, final double[] x) {// NOPMD - storing user-supplied array is intentional and documented here
- this.values = x;
- this.field = field;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple newInstance(final double value) {
- final Tuple t = new Tuple(field, new double[values.length]);
- Arrays.fill(t.values, value);
- return t;
- }
- /** Get the dimension of the tuple.
- * @return dimension of the tuple
- */
- public int getDimension() {
- return values.length;
- }
- /** Get one component of the tuple.
- * @param index index of the component, between 0 and {@link #getDimension() getDimension()} - 1
- * @return value of the component
- */
- public double getComponent(final int index) {
- return values[index];
- }
- /** Get all components of the tuple.
- * @return all components
- */
- public double[] getComponents() {
- return values.clone();
- }
- /** {@inheritDoc} */
- @Override
- public Field<Tuple> getField() {
- return field;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple add(final Tuple a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] + a.values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple subtract(final Tuple a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] - a.values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple negate() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = -values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple multiply(final Tuple a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] * a.values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple multiply(final int n) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] * n;
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple square() {
- return multiply(this);
- }
- /** {@inheritDoc} */
- @Override
- public Tuple divide(final Tuple a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] / a.values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple reciprocal() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = 1.0 / values[i];
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public boolean equals(final Object obj) {
- if (obj instanceof Tuple) {
- final Tuple that = (Tuple) obj;
- if (getDimension() == that.getDimension()) {
- boolean equals = true;
- for (int i = 0; i < values.length; ++i) {
- equals &= Double.doubleToRawLongBits(values[i]) == Double.doubleToRawLongBits(that.values[i]);
- }
- return equals;
- }
- }
- return false;
- }
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return 0x34b1a444 + Arrays.hashCode(values);
- }
- /** {@inheritDoc} */
- @Override
- public double getReal() {
- return values[0];
- }
- /** {@inheritDoc} */
- @Override
- public Tuple getAddendum() {
- final double[] addendum = values.clone();
- addendum[0] = 0;
- for (int i = 1; i < addendum.length; ++i) {
- addendum[i] -= values[0];
- }
- return new Tuple(field, addendum);
- }
- /** {@inheritDoc} */
- @Override
- public Tuple add(final double a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] + a;
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple subtract(final double a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] - a;
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple multiply(final double a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] * a;
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple divide(final double a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = values[i] / a;
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple remainder(final double a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.IEEEremainder(values[i], a);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple remainder(final Tuple a) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.IEEEremainder(values[i], a.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple abs() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.abs(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple ceil() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.ceil(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple floor() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.floor(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple rint() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.rint(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple sign() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.signum(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple copySign(final Tuple sign) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.copySign(values[i], sign.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple copySign(final double sign) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.copySign(values[i], sign);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple scalb(final int n) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.scalb(values[i], n);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple ulp() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.ulp(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple hypot(final Tuple y) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.hypot(values[i], y.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple sqrt() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.sqrt(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple cbrt() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.cbrt(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple rootN(final int n) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- if (values[i] < 0) {
- result.values[i] = -FastMath.pow(-values[i], 1.0 / n);
- } else {
- result.values[i] = FastMath.pow(values[i], 1.0 / n);
- }
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple pow(final double p) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.pow(values[i], p);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple pow(final int n) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.pow(values[i], n);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple pow(final Tuple e) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.pow(values[i], e.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple exp() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.exp(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple expm1() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.expm1(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple log() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.log(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple log1p() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.log1p(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple log10() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.log10(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple cos() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.cos(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple sin() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.sin(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public FieldSinCos<Tuple> sinCos() {
- final Tuple sin = new Tuple(field, new double[values.length]);
- final Tuple cos = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- final SinCos sc = FastMath.sinCos(values[i]);
- sin.values[i] = sc.sin();
- cos.values[i] = sc.cos();
- }
- return new FieldSinCos<>(sin, cos);
- }
- /** {@inheritDoc} */
- @Override
- public Tuple tan() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.tan(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple acos() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.acos(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple asin() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.asin(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple atan() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.atan(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple atan2(final Tuple x) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.atan2(values[i], x.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple cosh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.cosh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple sinh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.sinh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public FieldSinhCosh<Tuple> sinhCosh() {
- final Tuple sinh = new Tuple(field, new double[values.length]);
- final Tuple cosh = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- final SinhCosh sch = FastMath.sinhCosh(values[i]);
- sinh.values[i] = sch.sinh();
- cosh.values[i] = sch.cosh();
- }
- return new FieldSinhCosh<>(sinh, cosh);
- }
- /** {@inheritDoc} */
- @Override
- public Tuple tanh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.tanh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple acosh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.acosh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple asinh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.asinh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple atanh() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.atanh(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple toDegrees() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.toDegrees(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple toRadians() {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = FastMath.toRadians(values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final Tuple[] a, final Tuple[] b)
- throws MathIllegalArgumentException {
- final Tuple result = new Tuple(field, new double[values.length]);
- MathUtils.checkDimension(a.length, b.length);
- final double[] aDouble = new double[a.length];
- final double[] bDouble = new double[b.length];
- for (int i = 0; i < values.length; ++i) {
- for (int j = 0; j < a.length; ++j) {
- aDouble[j] = a[j].values[i];
- bDouble[j] = b[j].values[i];
- }
- result.values[i] = MathArrays.linearCombination(aDouble, bDouble);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final double[] a, final Tuple[] b)
- throws MathIllegalArgumentException {
- final Tuple result = new Tuple(field, new double[values.length]);
- MathUtils.checkDimension(a.length, b.length);
- final double[] bDouble = new double[b.length];
- for (int i = 0; i < values.length; ++i) {
- for (int j = 0; j < a.length; ++j) {
- bDouble[j] = b[j].values[i];
- }
- result.values[i] = MathArrays.linearCombination(a, bDouble);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final Tuple a1, final Tuple b1,
- final Tuple a2, final Tuple b2) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
- a2.values[i], b2.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final double a1, final Tuple b1,
- final double a2, final Tuple b2) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
- a2, b2.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final Tuple a1, final Tuple b1,
- final Tuple a2, final Tuple b2,
- final Tuple a3, final Tuple b3) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
- a2.values[i], b2.values[i],
- a3.values[i], b3.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final double a1, final Tuple b1,
- final double a2, final Tuple b2,
- final double a3, final Tuple b3) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
- a2, b2.values[i],
- a3, b3.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final Tuple a1, final Tuple b1,
- final Tuple a2, final Tuple b2,
- final Tuple a3, final Tuple b3,
- final Tuple a4, final Tuple b4) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
- a2.values[i], b2.values[i],
- a3.values[i], b3.values[i],
- a4.values[i], b4.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple linearCombination(final double a1, final Tuple b1,
- final double a2, final Tuple b2,
- final double a3, final Tuple b3,
- final double a4, final Tuple b4) {
- final Tuple result = new Tuple(field, new double[values.length]);
- for (int i = 0; i < values.length; ++i) {
- result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
- a2, b2.values[i],
- a3, b3.values[i],
- a4, b4.values[i]);
- }
- return result;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple getPi() {
- final Tuple result = new Tuple(field, new double[values.length]);
- Arrays.fill(result.values, FastMath.PI);
- return result;
- }
- /** Field for {link Tuple} instances.
- */
- private static class TupleField implements Field<Tuple> {
- /** Constant function evaluating to 0.0. */
- private final Tuple zero;
- /** Constant function evaluating to 1.0. */
- private final Tuple one;
- /** Simple constructor.
- * @param dimension dimension of the tuple
- */
- TupleField(final int dimension) {
- final double[] zeroData = new double[dimension];
- final double[] oneData = new double[dimension];
- Arrays.fill(oneData, 1.0);
- this.zero = new Tuple(this, zeroData);
- this.one = new Tuple(this, oneData);
- }
- /** {@inheritDoc} */
- @Override
- public Tuple getZero() {
- return zero;
- }
- /** {@inheritDoc} */
- @Override
- public Tuple getOne() {
- return one;
- }
- /** {@inheritDoc} */
- @Override
- public Class<Tuple> getRuntimeClass() {
- return Tuple.class;
- }
- /** {@inheritDoc} */
- @Override
- public boolean equals(final Object other) {
- if (other instanceof TupleField) {
- return zero.getDimension() == ((TupleField) other).zero.getDimension();
- } else {
- return false;
- }
- }
- /** {@inheritDoc} */
- @Override
- public int hashCode() {
- return 0x6672493d ^ zero.getDimension();
- }
- }
- }