1 /*
   2  * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 // Checkstyle: stop
  24 
  25 package org.graalvm.compiler.jtt.hotpath;
  26 
  27 import org.junit.Ignore;
  28 import org.junit.Test;
  29 
  30 import org.graalvm.compiler.jtt.JTTTest;
  31 
  32 /*
  33  */
  34 public class HP_series extends JTTTest {
  35 
  36     public static double test(int count) {
  37         final int arrayRows = count;
  38         final double[][] testArray = new double[2][arrayRows];
  39         double omega; // Fundamental frequency.
  40         testArray[0][0] = TrapezoidIntegrate(0.0, // Lower bound.
  41                         2.0, // Upper bound.
  42                         1000, // # of steps.
  43                         0.0, // No omega*n needed.
  44                         0) / 2.0; // 0 = term A[0].
  45         omega = 3.1415926535897932;
  46         for (int i = 1; i < arrayRows; i++) {
  47             testArray[0][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 1); // 1 = cosine
  48             // term.
  49             testArray[1][i] = TrapezoidIntegrate(0.0, 2.0, 1000, omega * i, 2); // 2 = sine
  50             // term.
  51         }
  52         final double ref[][] = {{2.8729524964837996, 0.0}, {1.1161046676147888, -1.8819691893398025}, {0.34429060398168704, -1.1645642623320958}, {0.15238898702519288, -0.8143461113044298}};
  53         double error = 0.0;
  54         double sum = 0.0;
  55         for (int i = 0; i < 4; i++) {
  56             for (int j = 0; j < 2; j++) {
  57                 error += Math.abs(testArray[j][i] - ref[i][j]);
  58                 sum += testArray[j][i];
  59             }
  60         }
  61         return sum + error;
  62     }
  63 
  64     private static double TrapezoidIntegrate(double x0, // Lower bound.
  65                     double x1, // Upper bound.
  66                     int ns, // # of steps.
  67                     double omegan, // omega * n.
  68                     int select) // Term type.
  69     {
  70         int nsteps = ns;
  71         double x; // Independent variable.
  72         double dx; // Step size.
  73         double rvalue; // Return value.
  74 
  75         x = x0;
  76         dx = (x1 - x0) / nsteps;
  77         rvalue = thefunction(x0, omegan, select) / 2.0;
  78         if (nsteps != 1) {
  79             --nsteps; // Already done 1 step.
  80             while (--nsteps > 0) {
  81                 x += dx;
  82                 rvalue += thefunction(x, omegan, select);
  83             }
  84         }
  85         rvalue = (rvalue + thefunction(x1, omegan, select) / 2.0) * dx;
  86         return (rvalue);
  87     }
  88 
  89     private static double thefunction(double x, // Independent variable.
  90                     double omegan, // Omega * term.
  91                     int select) // Choose type.
  92     {
  93         switch (select) {
  94             case 0:
  95                 return (Math.pow(x + 1.0, x));
  96             case 1:
  97                 return (Math.pow(x + 1.0, x) * Math.cos(omegan * x));
  98             case 2:
  99                 return (Math.pow(x + 1.0, x) * Math.sin(omegan * x));
 100         }
 101         return (0.0);
 102     }
 103 
 104     /*
 105      * This test is sensible to the implementation of Math.pow, cos and sin. Since for these
 106      * functions, the specs says "The computed result must be within 1 ulp of the exact result",
 107      * different implementation may return different results. The 11 ulp delta allowed for test(100)
 108      * tries to account for that but is not guaranteed to work forever.
 109      */
 110     @Ignore("failure-prone because of the variabiliy of pow/cos/sin")
 111     @Test
 112     public void run0() throws Throwable {
 113         double expected = 0.6248571921291398d;
 114         runTestWithDelta(11 * Math.ulp(expected), "test", 100);
 115     }
 116 
 117 }