blob: b3d341d8031d6bed27667f798526084bad4ef9fc [file] [log] [blame]
/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// Checkstyle: stop
package org.graalvm.compiler.jtt.hotpath;
import org.junit.Ignore;
import org.junit.Test;
import org.graalvm.compiler.jtt.JTTTest;
/*
*/
public class HP_series extends JTTTest {
public static double test(int count) {
final int arrayRows = count;
final double[][] testArray = new double[2][arrayRows];
double omega; // Fundamental frequency.
testArray[0][0] = TrapezoidIntegrate(0.0, // Lower bound.
2.0, // Upper bound.
1000, // # of steps.
0.0, // No omega*n needed.
0) / 2.0; // 0 = term A[0].
omega = 3.1415926535897932;
for (int i = 1; i < arrayRows; i++) {
testArray[0][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 1); // 1 = cosine
// term.
testArray[1][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 2); // 2 = sine
// term.
}
final double ref[][] = {{2.8729524964837996, 0.0}, {1.1161046676147888, -1.8819691893398025}, {0.34429060398168704, -1.1645642623320958}, {0.15238898702519288, -0.8143461113044298}};
double error = 0.0;
double sum = 0.0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 2; j++) {
error += Math.abs(testArray[j][i] - ref[i][j]);
sum += testArray[j][i];
}
}
return sum + error;
}
private static double TrapezoidIntegrate(double x0, // Lower bound.
double x1, // Upper bound.
int ns, // # of steps.
double omegan, // omega * n.
int select) // Term type.
{
int nsteps = ns;
double x; // Independent variable.
double dx; // Step size.
double rvalue; // Return value.
x = x0;
dx = (x1 - x0) / nsteps;
rvalue = thefunction(x0, omegan, select) / 2.0;
if (nsteps != 1) {
--nsteps; // Already done 1 step.
while (--nsteps > 0) {
x += dx;
rvalue += thefunction(x, omegan, select);
}
}
rvalue = (rvalue + thefunction(x1, omegan, select) / 2.0) * dx;
return (rvalue);
}
private static double thefunction(double x, // Independent variable.
double omegan, // Omega * term.
int select) // Choose type.
{
switch (select) {
case 0:
return (Math.pow(x + 1.0, x));
case 1:
return (Math.pow(x + 1.0, x) * Math.cos(omegan * x));
case 2:
return (Math.pow(x + 1.0, x) * Math.sin(omegan * x));
}
return (0.0);
}
/*
* This test is sensible to the implementation of Math.pow, cos and sin. Since for these
* functions, the specs says "The computed result must be within 1 ulp of the exact result",
* different implementation may return different results. The 11 ulp delta allowed for test(100)
* tries to account for that but is not guaranteed to work forever.
*/
@Ignore("failure-prone because of the variabiliy of pow/cos/sin")
@Test
public void run0() throws Throwable {
double expected = 0.6248571921291398d;
runTestWithDelta(11 * Math.ulp(expected), "test", 100);
}
}