blob: 15625a49e3c62baa268b95c9dec60a45569c8a69 [file] [log] [blame]
/*
* 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.math3.analysis.differentiation;
import org.junit.Assert;
import org.apache.commons.math3.TestUtils;
import org.apache.commons.math3.util.FastMath;
import org.junit.Test;
/**
* Test for class {@link JacobianFunction}.
*/
public class JacobianFunctionTest {
@Test
public void testSphere() {
SphereMapping f = new SphereMapping(10.0);
JacobianFunction j = new JacobianFunction(f);
for (double latitude = -1.5; latitude < 1.5; latitude += 0.1) {
for (double longitude = -3.1; longitude < 3.1; longitude += 0.1) {
double[] point = new double[] { latitude, longitude };
double[][] referenceJacobian = f.jacobian(point);
double[][] testJacobian = j.value(point);
Assert.assertEquals(referenceJacobian.length, testJacobian.length);
for (int i = 0; i < 3; ++i) {
TestUtils.assertEquals(referenceJacobian[i], testJacobian[i], 2.0e-15);
}
}
}
}
/* Maps (latitude, longitude) to (x, y, z) */
private static class SphereMapping implements MultivariateDifferentiableVectorFunction {
private final double radius;
public SphereMapping(final double radius) {
this.radius = radius;
}
public double[] value(double[] point) {
final double cLat = FastMath.cos(point[0]);
final double sLat = FastMath.sin(point[0]);
final double cLon = FastMath.cos(point[1]);
final double sLon = FastMath.sin(point[1]);
return new double[] {
radius * cLon * cLat,
radius * sLon * cLat,
radius * sLat
};
}
public DerivativeStructure[] value(DerivativeStructure[] point) {
final DerivativeStructure cLat = point[0].cos();
final DerivativeStructure sLat = point[0].sin();
final DerivativeStructure cLon = point[1].cos();
final DerivativeStructure sLon = point[1].sin();
return new DerivativeStructure[] {
cLon.multiply(cLat).multiply(radius),
sLon.multiply(cLat).multiply(radius),
sLat.multiply(radius)
};
}
public double[][] jacobian(double[] point) {
final double cLat = FastMath.cos(point[0]);
final double sLat = FastMath.sin(point[0]);
final double cLon = FastMath.cos(point[1]);
final double sLon = FastMath.sin(point[1]);
return new double[][] {
{ -radius * cLon * sLat, -radius * sLon * cLat },
{ -radius * sLon * sLat, radius * cLon * cLat },
{ radius * cLat, 0 }
};
}
}
}