Skip to content

Commit

Permalink
Added field version of sinCos.
Browse files Browse the repository at this point in the history
Github: fixes #47.
  • Loading branch information
maisonobe committed Sep 19, 2018
1 parent bf4d27b commit a5405fc
Show file tree
Hide file tree
Showing 14 changed files with 330 additions and 18 deletions.
4 changes: 4 additions & 0 deletions hipparchus-core/src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ If the output is not quite correct, check for invisible trailing spaces!
</properties>
<body>
<release version="1.4" date="TBC" description="TBC">
<action dev="luc" type="add" issue="issues/47" >
Added field version of sinCos.
Github: fixes #47.
</action>
<action dev="luc" type="fix" issue="issues/44" >
Fixed wrong construction of an Illinois solver that really built a Pegasus solver.
Github: fixes #44.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package org.hipparchus;

import org.hipparchus.exception.MathIllegalArgumentException;
import org.hipparchus.util.FieldSinCos;

/**
* Interface representing a <a href="http://mathworld.wolfram.com/RealNumber.html">real</a>
Expand Down Expand Up @@ -224,6 +225,14 @@ T pow(T e)
*/
T sin();

/** Combined Sine and Cosine operation.
* @return [sin(this), cos(this)]
* @since 1.4
*/
default FieldSinCos<T> sinCos() {
return new FieldSinCos<>(sin(), cos());
}

/** Tangent operation.
* @return tan(this)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.util.CombinatoricsUtils;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.MathArrays;
import org.hipparchus.util.MathUtils;
import org.hipparchus.util.SinCos;
Expand Down Expand Up @@ -1794,9 +1795,10 @@ public void cos(final double[] operand, final int operandOffset,

// create the function value and derivatives
double[] function = new double[1 + order];
function[0] = FastMath.cos(operand[operandOffset]);
final SinCos sinCos = FastMath.sinCos(operand[operandOffset]);
function[0] = sinCos.cos();
if (order > 0) {
function[1] = -FastMath.sin(operand[operandOffset]);
function[1] = -sinCos.sin();
for (int i = 2; i <= order; ++i) {
function[i] = -function[i - 2];
}
Expand All @@ -1823,15 +1825,14 @@ public <T extends RealFieldElement<T>> void cos(final T[] operand, final int ope

// create the function value and derivatives
T[] function = MathArrays.buildArray(field, 1 + order);
final T cos = operand[operandOffset].cos();
function[0] = cos;
final FieldSinCos<T> sinCos = FastMath.sinCos(operand[operandOffset]);
function[0] = sinCos.cos();
if (order > 0) {
final T sin = operand[operandOffset].sin();
function[1] = sin.negate();
function[1] = sinCos.sin().negate();
if (order > 1) {
function[2] = cos.negate();
function[2] = sinCos.cos().negate();
if (order > 2) {
function[3] = sin;
function[3] = sinCos.sin();
for (int i = 4; i <= order; ++i) {
function[i] = function[i - 4];
}
Expand Down Expand Up @@ -1887,15 +1888,14 @@ public <T extends RealFieldElement<T>> void sin(final T[] operand, final int ope

// create the function value and derivatives
T[] function = MathArrays.buildArray(field, 1 + order);
final T sin = operand[operandOffset].sin();
function[0] = sin;
final FieldSinCos<T> sinCos = FastMath.sinCos(operand[operandOffset]);
function[0] = sinCos.sin();
if (order > 0) {
final T cos = operand[operandOffset].cos();
function[1] = cos;
function[1] = sinCos.cos();
if (order > 1) {
function[2] = sin.negate();
function[2] = sinCos.sin().negate();
if (order > 2) {
function[3] = cos.negate();
function[3] = sinCos.cos().negate();
for (int i = 4; i <= order; ++i) {
function[i] = function[i - 4];
}
Expand All @@ -1908,6 +1908,89 @@ public <T extends RealFieldElement<T>> void sin(final T[] operand, final int ope

}

/** Compute combined sine and cosine of a derivative structure.
* @param operand array holding the operand
* @param operandOffset offset of the operand in its array
* @param sin array where sine must be stored (for
* sine the result array <em>cannot</em> be the input
* array)
* @param sinOffset offset of the result in its array
* @param cos array where cosine must be stored (for
* cosine the result array <em>cannot</em> be the input
* array)
* @param cosOffset offset of the result in its array
* @since 1.4
*/
public void sinCos(final double[] operand, final int operandOffset,
final double[] sin, final int sinOffset,
final double[] cos, final int cosOffset) {

// create the function value and derivatives
double[] functionSin = new double[1 + order];
double[] functionCos = new double[1 + order];
final SinCos sinCos = FastMath.sinCos(operand[operandOffset]);
functionSin[0] = sinCos.sin();
functionCos[0] = sinCos.cos();
if (order > 0) {
functionSin[1] = sinCos.cos();
functionCos[1] = -sinCos.sin();
for (int i = 2; i <= order; ++i) {
functionSin[i] = -functionSin[i - 2];
functionCos[i] = -functionCos[i - 2];
}
}

// apply function composition
compose(operand, operandOffset, functionSin, sin, sinOffset);
compose(operand, operandOffset, functionCos, cos, cosOffset);

}

/** Compute combined sine and cosine of a derivative structure.
* @param operand array holding the operand
* @param operandOffset offset of the operand in its array
* @param sin array where sine must be stored (for
* sine the result array <em>cannot</em> be the input
* array)
* @param sinOffset offset of the result in its array
* @param cos array where cosine must be stored (for
* cosine the result array <em>cannot</em> be the input
* array)
* @param cosOffset offset of the result in its array
* @since 1.4
*/
public <T extends RealFieldElement<T>> void sinCos(final T[] operand, final int operandOffset,
final T[] sin, final int sinOffset,
final T[] cos, final int cosOffset) {

final Field<T> field = operand[operandOffset].getField();

// create the function value and derivatives
T[] functionSin = MathArrays.buildArray(field, 1 + order);
T[] functionCos = MathArrays.buildArray(field, 1 + order);
final FieldSinCos<T> sinCos = FastMath.sinCos(operand[operandOffset]);
functionCos[0] = sinCos.cos();
if (order > 0) {
functionCos[1] = sinCos.sin().negate();
if (order > 1) {
functionCos[2] = sinCos.cos().negate();
if (order > 2) {
functionCos[3] = sinCos.sin();
for (int i = 4; i <= order; ++i) {
functionCos[i] = functionCos[i - 4];
}
}
}
}
functionSin[0] = sinCos.sin();
System.arraycopy(functionCos, 0, functionSin, 1, order);

// apply function composition
compose(operand, operandOffset, functionSin, sin, sinOffset);
compose(operand, operandOffset, functionCos, cos, cosOffset);

}

/** Compute tangent of a derivative structure.
* @param operand array holding the operand
* @param operandOffset offset of the operand in its array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.hipparchus.exception.MathIllegalArgumentException;
import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.MathArrays;
import org.hipparchus.util.MathUtils;

Expand Down Expand Up @@ -732,6 +733,16 @@ public DerivativeStructure sin() {
return result;
}

/** {@inheritDoc}
*/
@Override
public FieldSinCos<DerivativeStructure> sinCos() {
final DerivativeStructure sin = factory.build();
final DerivativeStructure cos = factory.build();
factory.getCompiler().sinCos(data, 0, sin.data, 0, cos.data, 0);
return new FieldSinCos<>(sin, cos);
}

/** {@inheritDoc}
*/
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.hipparchus.exception.MathIllegalArgumentException;
import org.hipparchus.exception.MathRuntimeException;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.MathArrays;
import org.hipparchus.util.MathUtils;

Expand Down Expand Up @@ -656,6 +657,16 @@ public FieldDerivativeStructure<T> sin() {
return result;
}

/** {@inheritDoc}
*/
@Override
public FieldSinCos<FieldDerivativeStructure<T>> sinCos() {
final FieldDerivativeStructure<T> sin = factory.build();
final FieldDerivativeStructure<T> cos = factory.build();
factory.getCompiler().sinCos(data, 0, sin.data, 0, cos.data, 0);
return new FieldSinCos<>(sin, cos);
}

/** {@inheritDoc}
*/
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
import org.hipparchus.RealFieldElement;
import org.hipparchus.exception.MathIllegalArgumentException;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.MathArrays;
import org.hipparchus.util.MathUtils;
import org.hipparchus.util.Precision;
import org.hipparchus.util.SinCos;

/**
* First derivative computation with large number of variables.
Expand Down Expand Up @@ -636,13 +638,23 @@ public SparseGradient log1p() {
/** {@inheritDoc} */
@Override
public SparseGradient cos() {
return new SparseGradient(FastMath.cos(value), -FastMath.sin(value), derivatives);
final SinCos sc = FastMath.sinCos(value);
return new SparseGradient(sc.cos(), -sc.sin(), derivatives);
}

/** {@inheritDoc} */
@Override
public SparseGradient sin() {
return new SparseGradient(FastMath.sin(value), FastMath.cos(value), derivatives);
final SinCos sc = FastMath.sinCos(value);
return new SparseGradient(sc.sin(), sc.cos(), derivatives);
}

/** {@inheritDoc} */
@Override
public FieldSinCos<SparseGradient> sinCos() {
final SinCos sc = FastMath.sinCos(value);
return new FieldSinCos<>(new SparseGradient(sc.sin(), sc.cos(), derivatives),
new SparseGradient(sc.cos(), -sc.sin(), derivatives));
}

/** {@inheritDoc} */
Expand Down
12 changes: 12 additions & 0 deletions hipparchus-core/src/main/java/org/hipparchus/util/FastMath.java
Original file line number Diff line number Diff line change
Expand Up @@ -2490,6 +2490,18 @@ public static SinCos sinCos(double x) {
}
}

/**
* Combined Sine and Cosine function.
*
* @param x Argument.
* @param <T> the type of the field element
* @return [sin(x), cos(x)]
* @since 1.4
*/
public static <T extends RealFieldElement<T>> FieldSinCos<T> sinCos(T x) {
return x.sinCos();
}

/**
* Tangent function.
*
Expand Down
60 changes: 60 additions & 0 deletions hipparchus-core/src/main/java/org/hipparchus/util/FieldSinCos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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
*
* 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.hipparchus.util;

import org.hipparchus.RealFieldElement;

/** Holder for both sin and cosine values.
* <p>
* This class is a simple container, it does not provide any computational method.
* </p>
* @see FastMath#sinCos(RealFieldElement)
* @param <T> the type of the field elements
* @since 1.4
*/
public class FieldSinCos<T> {

/** Value of the sine. */
private final T sin;

/** Value of the cosine. */
private final T cos;

/** Simple constructor.
* @param sin value of the sine
* @param cos value of the cosine
*/
public FieldSinCos(final T sin, final T cos) {
this.sin = sin;
this.cos = cos;
}

/** Get the value of the sine.
* @return value of the sine
*/
public T sin() {
return sin;
}

/** Get the value of the cosine.
* @return value of the cosine
*/
public T cos() {
return cos;
}

}
13 changes: 13 additions & 0 deletions hipparchus-core/src/main/java/org/hipparchus/util/FieldTuple.java
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,19 @@ public FieldTuple<T> sin() {
return result;
}

/** {@inheritDoc} */
@Override
public FieldSinCos<FieldTuple<T>> sinCos() {
final FieldTuple<T> sin = new FieldTuple<>(field, MathArrays.buildArray(values[0].getField(), values.length));
final FieldTuple<T> cos = new FieldTuple<>(field, MathArrays.buildArray(values[0].getField(), values.length));
for (int i = 0; i < values.length; ++i) {
final FieldSinCos<T> sc = FastMath.sinCos(values[i]);
sin.values[i] = sc.sin();
cos.values[i] = sc.cos();
}
return new FieldSinCos<>(sin, cos);
}

/** {@inheritDoc} */
@Override
public FieldTuple<T> tan() {
Expand Down
13 changes: 13 additions & 0 deletions hipparchus-core/src/main/java/org/hipparchus/util/Tuple.java
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,19 @@ public Tuple sin() {
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() {
Expand Down
Loading

0 comments on commit a5405fc

Please sign in to comment.