Calculation sin(x)

index.htm - Russian text 

Focus.zip - archived directory. 

 

Let's consider the following program of calculation sin (x) through a usual expansion in a series     sin(x) = x - x3/3! + x5/5! - x7/7! + ...

/**
 *  Supercompilation of calculation of sin(x) 
 */
public class Sn{
//    public static final int iters = 3;
//    public static final int iters = 100;
    public static final int iters = 1000;
    public static double x = 3.141592653589793D / 6;

    public static void main (String[] args) {
        double x2n = x;
        double res = x;
        double step = 2.0;
        double znam = -1.0 / 6.0;

        for (int i=0; i<iters; i++) {
            x2n = x2n * x * x ;
            res = res + (x2n * znam);
            step = step + 2.0;
            znam = -znam / (step * (step+1.0));
        }
        System.out.println("x      = " + x);
        System.out.println("sin(x) = " + res);
    }
}

The program calculates the sum of addends of a number in an amount iters. The variable iters is captured, and on her there will be a specialization. The variable x for the supercompiler is not known (x = 3.141592653589793D / 6 only for check start-up to account, should be received 0.5).

At iters = 3 the very good residual program is received

//--------------------------------------   0 sec - method Sn.main(java.lang.String[])
//--------------------------------------   0 sec - postprocessing...
	public static void main (final java.lang.String[] args_2)
	{
	  final double sn_x_3 = Sn.x;
	  final double sn_x_4 = Sn.x;
	  final double x2n_9 = sn_x_3 * Sn.x * Sn.x;
	  final double x2n_23 = x2n_9 * Sn.x * Sn.x;
	  final double res_39 = sn_x_4 + 
	                        x2n_9 * -0.16666666666666666D + 
	                        x2n_23 * 0.008333333333333333D +
	                        x2n_23 * Sn.x * Sn.x * -1.984126984126984e-4D;
	  java.lang.System.out.println("x      = " + Sn.x) /*virtual*/;
	  java.lang.System.out.println("sin(x) = " + res_39) /*virtual*/;
	  return;
	}
//--------------------------------------   0 sec - JScp version 0.0.77 

Now I change iters = 100, I gain in 30 seconds the program sn1000.js.

I look an amount of addends and I see, that them it is obvious less than 100.

With the purpose to see, that will happen I figure sequentially iters = 200, iters = 400, iters = 1000 further.

The time of supercompilation is enlarged unsignificantly, the residual program does not vary at all!

Here we observed knowledge of the supercompiler that A + 0 = A.

All circumscribed can be seen in the directory focus of the application Focus.zip.

Let's proceed to the second example posed in the directory focus2 of the application Focus.zip.

Here we organize summation of a number for sin (x) from the return extremity.

Let's use recursion, hoping, that in the residual program of recursion will not be, and consequently the good coefficients of acceleration will be received.

The source program

/**
 *  Supercompilation of calculation of sin(x)
 *  Calculation sin(x) through decomposition
 *  sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
 *  The return order of addition.
 */
public class Sn {
//    public static final int iters = 200; /* 2*Quantity of addition*/
    public static final int iters = 2000; /* 2*Quantity of addition*/


    public static void main (String[] args) {
        int iprint1 = 5;
        int iprint = 100000;

        for (int ip = 0; ip < iprint1; ip++) {
            long start = System.currentTimeMillis();

            double x = 3.141592653589793D / 6;
            double res = 0.0;

            for (int i = 0; i < iprint; i++) {
                res = sin(x);
            }

            System.out.println("x      = " + x);
            System.out.println("sin(x) = " + res);
       
            long end = System.currentTimeMillis();
            System.out.println("Total time = "+ (end-start)*0.001);
        }
    }

    public static double sin(double x) {
        return sin1(x, x, 2, 1.0);
    }


    /** One step of calculation sin(x)
      * @param double x    - argument sin(x)
      * @param double x2n  - x^(2*n+1)
      * @param int step    - 2*n
      * @param double znam - +-1/(2*n+1)! 
      */
    public static double sin1(double x, double x2n, int step, double znam) {
        if (step==iters) return 0.0;
          else return sin1(x, x2n*x*x, step+2, -znam/(step*(step+1)))
                      + x2n*znam;
    }
}

Residual programs sn.js identical for iters=100 and for iters=1000.

If iters=100, execution time of the source program 1.95 seconds, residual program - 0.70 seconds, acceleration - 2.8 times.

Now we change iters = 1000, therefore the residual program does not vary, and initial will be executed in 10 times longer.

Execution time of the source program 16.25 seconds, residual program - 0.70 seconds, acceleration - 23.2 times.

In this example there are a lot of suppositions and lacks, but idea of usage thus supercompilations - good idea.