Aptarimas:Matematika/Sinuso Integralas

popular example of Fourier integral keisti

Given function

f(x)=1, when |x|<1,
f(x)=1/2, when |x|=1,
f(x)=0, when |x|>1.
Need to write this function through Fourier integral.
Solution is for this example:
 
 
 
In particular case if x=0 (|x|<1), then
 
and we put 0 into x place and we get   And so we have:
 
 
As far as I understand about Fourier integral, this integral means:
 
But problem is, that I check it through Free Pascal program "Version 1.0.12 2011/04/23; Compiler Version 2.4.4; Debugger GDB 7.2" with this code:
  var
  a:longint;
  c:real;
  begin
        c:=0;
        a:=0;
          for a:=1 to 100000
          do
            c:=c+sin(a)/a;
  writeln(c);
  readln();
  end.
so I get result 1.07080565212341. Even not close to   — Preceding unsigned comment added by Versatranitsonlywaytofly (talkcontribs) 22:52, 22 December 2011 (UTC) BTW, you can use it like benchmark changing number in line "for a:=1 to 100000" to bigger than 100000. With number 1000000000 I got 1.07079632630307 and it take for CPU 52 seconds to compute result. You can use "a:integer" instead "a:longint", but then smaller number you will be able to choose. With number 100000000 it tooks only 5 seconds and result is 1.07079633477997.
It apears just simple mistake, I thought impossible that it mean that it mean, because   but it not, it equal to ~1. But interesting coincidence, that result is   it something must to do with Fourier series and coefficient  . So real code is:
  var
  b:real;
  a:longint;
  begin
        b:=0;
        a:=0;
          for a:=1 to 1000000000
          do
           b:=b+0.00001*sin(a/100000)/(a/100000);
  writeln(b);
  readln();
  end.
And result is 1.57088654523321 after 63 seconds.

Sine Taylor series benchmarking keisti

Sine function can be written as Taylor series. Here we have 14 numbers after point (15 total and one last for last number approximation, which isn't shows and is only in memory). If one decimal number is 4 bits, then it can be 16*4=64 bits precision.
Using windows calculator I check, that
 
particularly
  or  
 
 
  or  

Some stupid infinity furje integral problem (Furje Integral must be pseudoscience) keisti

         var
         b:real;
         a:longint;
         begin
         b:=0;
         a:=0;
         for a:=1 to 1000000000
         do
         b:=b+0.00001*cos(1.1*a/100000)*sin(a/100000)/(a/100000);
         writeln(b);
         readln();
It just gives always different result do not matter how close to infinity you choose to be for a.

Simplest benchmark keisti

   var
   a:longint;
   c:real;
   begin
         for a:=1 to 1000000000
         do
         c:=c+a;
   writeln(c);
   readln();
   end.


Result is   after 6 seconds on ~3 GHz processor. Notice, that in this case result is only twice faster than on 1.6 GHz Intel Atom processor, because it don't depends on number of cores, nor on instructions or amounts of cashes. Pentium III of 3GHz would calculate in same time.
There is integer numbers of 16 decimal places (one 16th number is for approximation in the end and it's not shown). One decimal number is 4 bits. So 64 bits precision in total. There is exactly one billion additions in 6 seconds. This is 166 millions additions per second. But if calculate how many bits addition is per second then we get 166*64=10624 millions/s or 10 billions additions per second. This is 10624/8=1328 Megabytes per second or 1.3 GB/s. For now seems like nothing, what can not handle (800MHz*64bits)/8=6400 MB/s RAM memory.


Interesting coincidence, that say at 3(GHz) done in 5(seconds), then at 1(GHz) done in 15(seconds). And we have 15 decimal places. So I suggest, that in one cycle (takt) CPU making one decimal number sum operation (like 4+7 or 8+6 or 4+5). I suggest, that in one cycle (3GHz CPU have 3 bilions cycles/s) can be done either one sum operation or one subtraction operation or multiplication or division (maybe subtraction operation takes 2 cycles and multiplication 3 cycles, but maybe no). From this can be conclusion, that Bill Gates don't using MMX(64bit), SSE(128bit) or AVX(256bit) instructions and they are just in some kinda BIOS or ROM memory, but have small influence in practice as all old programs like Visual C++ and Windows running on instructions [software codes] before introducing MMX, SSE, AVX. My drift is, that Intel various SSE instructions don't adding physical calculation units, but is just kinda smarter vector calculating codes, than kinda you can write and thus can be faster.

Simplest benchmark 2 keisti

Strange even this harder benchmark gives result   in 3-4 seconds.
  var
  a:longint;
  c,b,d,e,f,g:real;
  begin
        for a:=1 to 1000000000
        do
        b:=a;
        d:=a*b;    //a^2
        e:=d*d;    //a^4
        f:=e*e;    //a^8
        g:=f*f;    //a^16
      //    c:=c+sin(a)/a;
      c:=c+(a*g);
  writeln(c);
  readln();
  end.

Something wrong keisti

  var
  a:longint;
  c,b,d,e,f,g:real;
  begin
        for a:=1 to 1000000000
        do
        b:=a;
        d:=a*b;    //a^2
        e:=d*d;    //a^4
        f:=e*e;    //a^8
        g:=f*f;    //a^16
      //    c:=c+sin(a)/a;
      c:=c+(1-a*d/6+a*e/120-a*d*e/5040+a*f/362880-a*d*f/39916800+a*e*f/6227020800-(g/a)/1307674368000+a*g/355687428096000-a*d*g/121645100408832000)/a;
  writeln(c);
  readln();
  end.


Result should be  , but for some reason is   (this result is gotten after 3-4 seconds).


Something wrong 2 keisti

This also gives wrong result:
  var
  a:longint;
  c,b,d,e,f,g,h:real;
  begin
        for a:=1 to 1000000000
        do
        b:=a/100000;
        d:=a*b/100000;    //a^2
        e:=d*d;    //a^4
        f:=e*e;    //a^8
        g:=f*f;    //a^16
        h:=1-b*d/6+b*e/120-b*d*e/5040+b*f/362880-b*d*f/39916800+b*e*f/6227020800-(g/b)/1307674368000+b*g/355687428096000-b*d*g/121645100408832000;
      c:=c+0.00001*h/(a/100000);
  writeln(c);
  readln();
  end.
Result is   after 10 seconds. But result should be  


update: silly error (must be b instead 1),
  h:=b-b*d/6+b*e/120-b*d*e/5040+b*f/362880-b*d*f/39916800+b*e*f/6227020800-(g/b)/1307674368000+b*g/355687428096000-b*d*g/121645100408832000;
but still need much longer serie (like up to  ) to get something, which would give at least two first correct decimal places. It seems that there is some trick for last number to made series perhaps much much shorter.

Only sin(1) is quite precise with short series keisti

I check, that

 
and
 
While precise result is  


Update. With all small number (like from 0 to  ) need only calculate to   to get 10 decimal places precision. So smart choise is to divide big number by   or by   and remove fractional part and integer part multiply by   or by   and then gotten result subtract from initial big number. Then you have number from 0 to   (or to  ), which Taylor series calculation makes short and simple.
Update 2. Need divide by   then must do not be any errors. Then fractional part remove and integer part multiply by   and gotten result subtract from big number. This gives about 5 correct decimal places if you calculate to  , but it's still much shorter than very big numbers. For exampe,
 
which is quite close to  

simplest benchmark 2.1 keisti

    var
    a:longint;
    c,b,d,e,f,g,h:real;
    begin
        for a:=900000000 to 1000000000
        do
        c:=c+a; 
    writeln(c);
    readln();
Result is   in ~1 second. This is   addition operations.

simplest benchmark 3 keisti

    var
    a:longint;
    c,b,d,e,f,g,h:real;
    begin
        for a:=500000000 to 1000000000
        do
        c:=c+a; 
    writeln(c);
    readln();
Result is   in 2 or 3 seconds on ~3 GHz CPU. This is   addition operations. Notice, that on average done in precision   where number 16 is 16 decimal digits (15, but one for rounding, I think). Because, I think, CPU don't using 15-16 numbers precision until numbers are small like   or   Putting this to binary form, I have in mind, that   which is 16 decimal numbers from 52 binary numbers. So   and it is 8 decimal places of integer. So if CPU using addition by 1 bit, then here is   So need 5.2 GHz CPU to accomplish this task. My suggestion is that CPU 0's adding faster than 1's. Or cycle (all CPU do ~3*10^9 cycles/s) is determined by first CPU designers as one decimal number addition to over decimal number and if precision is 16 decimal numbers then there is 16 additions and thus it will be   Now you know what mean cycle, because cycle is one addition of one number (from 0 to 9) to another number (from 0 to 9). So, for example, 64 bits (double precision) 2*10^12 floating operations per second (2 TFLOPS) is   operations (additions, for example) per second of 16 decimal places digits numbers (of 64 bits numbers). For example, AMD claims, that Radeon HD 6970 have 683 GFLOPs Double Precision compute power (and 2.7 TFLOPs Single Precision compute power). So 683/16=42.6875 billions additions/s of 16 decimal places numbers. Also 2700/8=337.5 billions additions/s of 7-8 decimal places numbers (single precision (32 bits) have more like 7 decimal digits). Doubling computer power 2 times in two years, in 2016 there should be 4 times bigger number. But recently arived Radeon HD 7970 have 3.79 TFLOPs Single Precision compute power and 947 GFLOPs Double Precision compute power. This AMD "Radeon HD 7970" is at writing time most powerfull single chip graphics card. So in 2016 there should be 3.79*4=15.16 TFLOPS Single Precision and 0.947*4=3.788 TFLOPs double precision most powerful card (double precision amount of FLOPs is 4 times smaller than single precision on AMD Radeon HD cards). And in 2030 there should be   TFLOPs ~ 1000 PFLOPS ~1 ExaFLOPS (  FLOPS) Single Precision most powerful GPU card.
Another theory is, that CPU doing all job, and only CPU single core power increase, because of bigger frequency, which in 2016 should be 3.5 GHz not expensive as now 3 GHz. And in 2030 should be 10 GHz or 30 GHz (or the same 3 GHz in worst case). But games programming will be so professional, that you will not be able to say or it is done on 3GHz single core or on 10^18 FLOPS GPU. Anyway 10 GHz CPU will trick you with no problems with raytracing (reflection in reflection in small area and you are tricked) and approximated radiosity.

Natural logarithm benchmarking keisti

    var
    a:longint;
    c,b,d,e,f,g,h:real;
    begin
        for a:=500000000 to 1000000000
        do
        c:=c+ln(a);  //real
    //    b:=a/100000;
    //    d:=a*b/100000;    //a^2
    //    e:=d*d;    //a^4
    //    f:=e*e;    //a^8
    //    g:=f*f;    //a^16
      //    c:=c+sin(a)/a;
   //     h:=b-b*d/6+b*e/120-b*d*e/5040+b*f/362880-b*d*f/39916800+b*e*f/6227020800-(g/b)/1307674368000+b*g/355687428096000-b*d*g/121645100408832000;
   //     c:=c+0.00001*h/b;
    writeln(c);
    readln();
    end.
This benchmark gives result 1.02082065291082*10^10 after 25 seconds on ~3GHz CPU.


Natural logarithm benchmarking 2 keisti

    var
    a:longint;
    c:real;
    begin
        for a:=1 to 1000000000
        do
        c:=c+ln(a);  
    writeln(c);
    readln();
    end.
This benchmark gives result   after 50 seconds on ~3GHz CPU. Notice, that for sine function calculation ("c:=c+sin(a);") in exactly the same manner result was gotten also in ~50 seconds (47 seconds; result  ). It makes me think, that sine or natural logarithm is gotten from some kind big database table, rather than calculated. But I check few times and there really is 3-4 seconds difference between sine function and natural logarithm (natural logarithm calculated 3 seconds longer).

Natural logarithm benchmarking 3 keisti

    var
    a:longint;
    c:real;
    begin
        for a:=1 to 1000000000
        do
        c:=c+123456789012345*ln(a);  
    writeln(c);
    readln();
    end.
This benchmark gives result   after 52 seconds on ~3GHz CPU.
If there is only one multiplier unit, then either there is calculations in smaller precision or there is more than one multiplier unit. Because to multiply each number with another number then there is 15^2=225 or 16^2=256 multiplications and 225 or 256 addition operations for multiplying two 15 (or 16) decimal places numbers. So in total to multiply, for example, 123456789012345 with 123456789012345 need 15^2+225=450 operations. And if one operation (like addition operation) done in one cycle, then for such benchmark (if not counting calculation of natural logarithm) to do in 52 seconds need not ~3GHz CPU, but   CPU. So I pretty believe, that there is 15 or 16 decimal digits number multiplication with one decimal digit number in 1 or at most 3 cycles (but really not more than in 4-10 cycles).
Update: "Free Pascal" can reform this code into this (and result will be the same, but little bit different  ):
    var
    a:longint;
    c:real;
    begin
        for a:=1 to 1000000000
        do
        c:=c+ln(a);
        writeln(123456789012345*c);
    readln();
    end.
So multiplication must be hard, because you can't even use multiple times (like "for a:=1 to 1000000000 do") free pascal function "sqr()", which is power of 2. This function ("sqr()") you can use only once, so you need go around and use "exp()" and "ln()" functions combinations to rise power of 2 (like this: exp(2*ln(a))=a*a). So if there really all programing languages have problems with multiplication then there is hope, that GPU is not a fake. BTW, I read, that RISC processors programing also do not have multiplication or can't do multiplication, something like that, but can do division.

Natural logarithm benchmarking 4 keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+exp(2*ln(a));  //a^2=exp(2*ln(a))
   writeln(c);
   readln();
   end.
This benchmark gives result   after 96 seconds on ~3GHz CPU.

Natural logarithm benchmarking 5 keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+exp(ln(a)); 
   writeln(c);
   readln();
   end.
This benchmark gives result   after 92 seconds on ~3GHz CPU.

Power function benchmarking keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+a*exp(ln(a)); // a^2=a*exp(ln(a))
       writeln(c);
   readln();
   end.


This benchmark gives result   after 93 seconds on ~3GHz CPU.

Simple benchmark keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+1;  
       writeln(c);
   readln();
   end.
This benchmark gives result   after 4 seconds on ~3GHz CPU.

Simple benchmark 2 keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+2.7;  
       writeln(c);
   readln();
   end.
This benchmark gives result   after 5 seconds on ~3GHz CPU.

Simple benchmark 3 keisti

   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+2.789123456789012;  
       writeln(c);
   readln();
   end.
This benchmark gives result   after 5 seconds on ~3GHz CPU. Such code in "Free Pascal" can be reformed to this: "c:=c+1;=>result*2.789123456789012", so it does not prove anything. Like this:
   var
   a:longint;
   c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+1; 
       writeln(c*2.789123456789012);
   readln();
   end.
This time result is   after 4-5 seconds on ~3GHz CPU.


Or if you use this benchmark, then multiplication will be rounded:
   var
   a:longint;
   b,c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+1; 
       b:=c*2.789123456789012;
       writeln(b);
   readln();
   end.
And result is   after 4-5 seconds on ~3GHz CPU. If you get result faster it means, that ~3GHz=2.6GHz.

Square root benchmarking keisti

   var
   a:longint;
   b,c:real;
   begin
       for a:=1 to 1000000000
       do
       c:=c+sqrt(a);    // a^(1/2)=sqrt(a)
       writeln(c);
   readln();
   end.
This benchmark gives result   after 12 seconds on ~3GHz CPU (if this line "c:=c+sqrt(a);" replace with this line "c:=c+a*sqrt(a);", it still gives result   after 12 seconds on the same CPU). Calculations going on in 16 decimal digits precision. So two cycles waisted per each decimal digit in this [square root] calculation, because (12*2.6*10^9)/(16*10^9)=(31.2*10^9)/(16*10^9)=2. Or 2*16=32 cycles used for square root of one double precision (64 bits = 16 decimal digits) number.


Here example how square root is calculated.
To get  
Step 1: Guess G = 1;
Step 2: New Guess = (G + x/G)/2;
Repeat Step 2 arbitrary number of times, to get arbitrary precise result.
For example,  
G = 1;
G = (1+3/1)/2 = 4/2 = 2;
G = (2 + 3/2)/2 = 7/4 = 1.75;
G = (7/4 + 12/7)/2 = (49+48/28)/2 = (97/28)/2 = 97/56 = 1.732142857;
G = (97/56 + 168/97)/2 = ((97^2 + 168*56)/(97*56))/2 = ((9409 + 9408)/5432)/2 = 18817/10864 = 1.732050810.

Too fast multiplication (multiplication benchmark) keisti

   var
   a:longint;
   b,c:real;
   begin
   b:=0;
   c:=123456789012345;
       for a:=1 to 1000000000
       do
       b:=b+c*a;
       writeln(b);
   readln();
   end.
This benchmark gives result   after 5 seconds on ~3GHz CPU.
But this benchmark
   var
   a:longint;
   b,c:real;
   begin
   b:=0;
   c:=123456789012345;
       for a:=1 to 1000000000
       do
       b:=b+a;
       writeln(c*b);
   readln();
   end.
gives result   also after 5 seconds on ~3GHz CPU.
And this benchmark
   var
   a:longint;
   b,d,c:real;
   begin
   b:=0;
   c:=123456789012345;
       for a:=1 to 1000000000
       do
       b:=b+a;
       d:=c*b;
       writeln(d);
   readln();
   end.
gives result   also after 5 seconds on ~3GHz CPU.
Even this benchmark
   var
   a:longint;
   b,c:real;
   begin
   b:=0;
       for a:=1 to 1000000000
       do
       b:=b+a;
       writeln(b);
   readln();
   end.
gives result   after 5 seconds on ~3GHz CPU.

Free Pascal pagrindas norint sukūrti sinuso skaičiavimą keisti

 Uses math;
 begin
 Writeln(Ceil(-3.7)); // should be -3
 Writeln(floor(-3.7)); // should be -4
 Writeln(frac(3.7)); // should be 0.7
 Writeln(floor(3.7)); // should be 3
 Writeln(ceil(3.7)); // should be 4
 Writeln(Ceil(-4.0)); // should be -4
 Readln;
 End.
tai ir yra pilnas kodas Free Pascal'iui (Compiler version 2.6.0) su kuriuo jau veikia (paspaudžius "Run" arba klaviatūra "Ctrl+F9") ir parodomas monitoriuje skaičių stulpelis.


Bet koks skaičius x paverčiamas į radianus nuo 0 iki   pritaikius formulę:
 
Pavyzdžiui, x=10, tada:
sin(10)=-0.54402111088936981340474766185138;
ir
 
frac(1.5915494309189533576888376337251)=0.5915494309189533576888376337251,
 
sin(3.716814692820413523074713233441)=-0.54402111088936981340474766185138.

Sinuso Tailoro eilutės Free Pascal kodas keisti

var a:longint; c:real;
begin
for a:=0 to 3 do
c:=c+(a-0.16666666666666667*a*a*a+0.0083333333333333333*a*sqr(sqr(a*1.0))-
0.00019841269841269841*a*sqr(a*1.0)*sqr(sqr(a*1.0))+
0.0000027557319223985891*a*sqr(sqr(sqr(a*1.0)))-
0.000000025052108385441718775*a*sqr(a*1.0)*sqr(sqr(sqr(a*1.0)))+
0.000000000160590438368216146*a*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))-
0.00000000000076471637318198164759*a*sqr(a)*sqr(sqr(a))*sqr(sqr(sqr(a*1.0)))+
0.000000000000002811457254345520763*a*sqr(sqr(sqr(sqr(a*1.0))))); 
writeln(c);
writeln(sin(1)+sin(2)+sin(3));
Readln;
End.
duoda resultatus:
1.89188842905109;
1.8918884196934454.

Sinuso Free Pascal kodas bet kokiems skaičiams keisti

 Uses math;
 var a:longint; c:real;
 begin
 for a:=0 to 100000000 do
 c:=c+6.283185307179586477*frac(a*0.159154943091895336)-
 0.16666666666666667*sqr(6.283185307179586477*frac(a*0.159154943091895336))*6.283185307179586477*frac(a*0.159154943091895336)+
 0.0083333333333333333*6.283185307179586477*frac(a*0.159154943091895336)*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))-
 0.00019841269841269841*6.283185307179586477*frac(a*0.159154943091895336)*sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))+
 0.0000027557319223985891*6.283185307179586477*frac(a*0.159154943091895336)*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))-
 0.000000025052108385441718775*6.283185307179586477*frac(a*0.159154943091895336)*sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))+
 0.000000000160590438368216146*6.283185307179586477*frac(a*0.159154943091895336)*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))-
 0.00000000000076471637318198164759*6.283185307179586477*frac(a*0.159154943091895336)*
 sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))*
 sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))+
 0.000000000000002811457254345520763*6.283185307179586477*frac(a*0.159154943091895336)*sqr(sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))); // 1/(2*3.14)=0.159
 writeln(c);
 Readln;
 End.
kuris duoda atsakymą 55365,3072928836 po 71 sekundės su 2,6 GHz procesorium. Šitas kodas duoda sin(x) tą patį ką ir originali Free Pascal sinuso funkcija tik, kai 0<x<1.09, o su vis didesniais 1.09<x<6.283185307179586477 atsakymas gaunasi vis netikslesnis. Nes ko gero Free Pascal skaičiuoja sinusą ekonomiškai iki 45 laipsnių, o ne naudoja labai ilgą Teiloro eilutę.
Truputi optimizuotas šio kodo variantas:
 Uses math;
 var a:longint; c:real;
 begin
 for a:=1 to 100000000 do
 c:=c+frac(a*0.159154943091895336)-
 0.16666666666666667*sqr(6.283185307179586477*frac(a*0.159154943091895336))*frac(a*0.159154943091895336)+
 0.0083333333333333333*frac(a*0.159154943091895336)*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))-
 0.00019841269841269841*frac(a*0.159154943091895336)*sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))+
 0.0000027557319223985891*frac(a*0.159154943091895336)*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))-
 0.000000025052108385441718775*frac(a*0.159154943091895336)*sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))+
 0.000000000160590438368216146*frac(a*0.159154943091895336)*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))*sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))-
 0.00000000000076471637318198164759*frac(a*0.159154943091895336)*
 sqr(6.283185307179586477*frac(a*0.159154943091895336))*sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336)))*
 sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))+
 0.000000000000002811457254345520763*frac(a*0.159154943091895336)*sqr(sqr(sqr(sqr(6.283185307179586477*frac(a*0.159154943091895336))))); // 1/(2*3.14)=0.159
 writeln(6.283185307179586477*c);
 Readln;
 End.
duoda atsakymą 55365,307292856515 vis tiek po 71 sekundės su 2,6 GHz procesorium.

Sinuso benchmark'as keisti

Šitas sinuso kodas:
 Uses math;
 var a:longint; c:real;
 begin
 for a:=0 to 100000000 do
 c:=c+sin(a); 
 writeln(c);
 Readln;
 End.
yra 71/5=14 karų greitesnis už savadarbį, nes duoda atsakymą 1,71364934657128 po 5 sekundžių su 2,6 GHz procesorium.


Sinuso benchmark'as 2 keisti

Šitas sinuso kodas:
 Uses math;
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+sin(a); 
 writeln(c);
 Readln;
 End.
duoda atsakymą 0,421294486750096 po 47 sekundžių su 2,6 GHz procesorium. Vadinasi, iš tiesų Free pascal funkciją frac() skaičiuoja tik vieną kartą ir greičiausiai iki   kad Teiloro eilutė būtų kuo trumpesnė suderindamas minuso ženklus ir panašiai (gal dar kvadratu pakeltas reikšmes panaudoja vėl, o ne skaičiuoja iš naujo), nes 71/4,7=15,1 karto greičiau.

Free Pascal funkcijos frac() benchmark'as keisti

 Uses math;
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+frac(a*0.15915494309189533576888); // 1/(2*3.14)=0.159
 writeln(c);
 Readln;
 End.
duoda rezultatą 499999986.434272 po 25 sekundžių su 2.6 GHz procesorium.

Teoretinis sinuso benchmark'as keisti

Šis Free Pascal kodas skaičiuoja teisingai visus skaitmenis tik skaičiamas nuo 0 iki 1.09, o skaičiams didesniems nei 1.09 tikslumas mažėja, o labai dideliems tikslumas iš vis prarandamas. Kodas yra toks (tikrinamas teorinis sinuso greitis mažiems skaičiams):
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+(a-0.16666666666666667*a*a*a+0.0083333333333333333*a*sqr(sqr(a*1.0))-
 0.00019841269841269841*a*sqr(a*1.0)*sqr(sqr(a*1.0))+
 0.0000027557319223985891*a*sqr(sqr(sqr(a*1.0)))-
 0.000000025052108385441718775*a*sqr(a*1.0)*sqr(sqr(sqr(a*1.0)))+
 0.000000000160590438368216146*a*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))-
 0.00000000000076471637318198164759*a*sqr(a)*sqr(sqr(a))*sqr(sqr(sqr(a*1.0)))+
 0.000000000000002811457254345520763*a*sqr(sqr(sqr(sqr(a*1.0)))));
 writeln(c);
 Readln;
 End.
kuris duoda rezultatą   po 43 sekundžių su 2.6 GHz procesorium.


Va toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+(a-0.16666666666666667*a*a*a+0.0083333333333333333*a*sqr(sqr(a))-
 0.00019841269841269841*a*sqr(a)*sqr(sqr(a))+
 0.0000027557319223985891*a*sqr(sqr(sqr(a)))-
 0.000000025052108385441718775*a*sqr(a)*sqr(sqr(sqr(a)))+
 0.000000000160590438368216146*a*sqr(sqr(a))*sqr(sqr(sqr(a)))-
 0.00000000000076471637318198164759*a*sqr(a)*sqr(sqr(a))*sqr(sqr(sqr(a)))+
 0.000000000000002811457254345520763*a*sqr(sqr(sqr(sqr(a*1.0)))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po 54 sekundžių su 2.6 GHz procesorium.


Štai toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1-0.16666666666666667*sqr(a*1.0)+0.0083333333333333333*sqr(sqr(a*1.0))-
 0.00019841269841269841*sqr(a*1.0)*sqr(sqr(a*1.0))+
 0.0000027557319223985891*sqr(sqr(sqr(a*1.0)))-
 0.000000025052108385441718775*sqr(a*1.0)*sqr(sqr(sqr(a*1.0)))+
 0.000000000160590438368216146*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))-
 0.00000000000076471637318198164759*sqr(a*1.0)*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))+
 0.000000000000002811457254345520763*sqr(sqr(sqr(sqr(a*1.0)))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po 41 sekundės su 2.6 GHz procesorium.


Toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1-sqr(a*1.0)*(0.16666666666666667+0.0083333333333333333*sqr(a*1.0)-
 0.00019841269841269841*sqr(sqr(a*1.0)))+
 0.0000027557319223985891*sqr(sqr(sqr(a*1.0)))-
 0.000000025052108385441718775*sqr(a*1.0)*sqr(sqr(sqr(a*1.0)))+
 0.000000000160590438368216146*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))-
 0.00000000000076471637318198164759*sqr(a*1.0)*sqr(sqr(a*1.0))*sqr(sqr(sqr(a*1.0)))+
 0.000000000000002811457254345520763*sqr(sqr(sqr(sqr(a*1.0)))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po 39 sekundžių su 2.6 GHz procesorium.


Toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1-
 sqr(a*1.0)*(0.16666666666666667+
 sqr(a*1.0)*(0.0083333333333333333-
 sqr(a*1.0)*(0.00019841269841269841+
 sqr(a*1.0)*(0.0000027557319223985891-
 sqr(a*1.0)*(0.000000025052108385441718775+
 sqr(a*1.0)*(0.000000000160590438368216146-
 sqr(a*1.0)*(0.00000000000076471637318198164759+
 sqr(a*1.0)*0.000000000000002811457254345520763))))))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po 27 sekundžių su 2.6 GHz procesorium.


Toks teisingas Free Pascal kodas:
 var a:longint; c:real;
 begin
 //for a:=0 to 1000000000 do
 a:=2;
 c:=c+a*(1+
 sqr(a*1.0)*(-0.16666666666666667+
 sqr(a*1.0)*(0.0083333333333333333+
 sqr(a*1.0)*(-0.00019841269841269841+
 sqr(a*1.0)*(0.0000027557319223985891+
 sqr(a*1.0)*(-0.000000025052108385441718775+
 sqr(a*1.0)*(0.000000000160590438368216146+
 sqr(a*1.0)*(-0.00000000000076471637318198164759+
 sqr(a*1.0)*(0.000000000000002811457254345520763-
 sqr(a*1.0)*0.000000000000000008220635246624329717)))))))));
 writeln(c);
 writeln(sin(2));
 Readln;
 End.
duoda rezultatą (neteisingai tik du paskutinius skaitmenis):
0.909297426825641 ir
0.90929742682568170.


Toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 //for a:=0 to 1000000000 do
 a:=6;
 c:=c+a*(1+
 sqr(a*1.0)*(-0.16666666666666667+
 sqr(a*1.0)*(0.0083333333333333333+
 sqr(a*1.0)*(-0.00019841269841269841+
 sqr(a*1.0)*(0.0000027557319223985891+
 sqr(a*1.0)*(-0.000000025052108385441718775+
 sqr(a*1.0)*(0.000000000160590438368216146+
 sqr(a*1.0)*(-0.00000000000076471637318198164759+
 sqr(a*1.0)*(0.000000000000002811457254345520763+
 sqr(a*1.0)*(-0.000000000000000008220635246624329717+
 sqr(a*1.0)*(0.00000000000000000001957294106339126123-
 sqr(a*1.0)*0.000000000000000000000038681701706306840377)))))))))));
 writeln(c);
 writeln(sin(6));
 Readln;
 End.
duoda rezultatą:
-0.279417241102534 ir
-0.27941549819892587.


Toks Free Pascal kodas (iki dalint iš 29 faktoriale):
 var a:longint; c:real;
 begin
 //for a:=0 to 1000000000 do
 a:=6;
 c:=c+a*(1+
 sqr(a*1.0)*(-0.16666666666666667+
 sqr(a*1.0)*(0.0083333333333333333+
 sqr(a*1.0)*(-0.00019841269841269841+
 sqr(a*1.0)*(0.0000027557319223985891+
 sqr(a*1.0)*(-0.000000025052108385441718775+
 sqr(a*1.0)*(0.000000000160590438368216146+
 sqr(a*1.0)*(-0.00000000000076471637318198164759+
 sqr(a*1.0)*(0.000000000000002811457254345520763+
 sqr(a*1.0)*(-0.000000000000000008220635246624329717+
 sqr(a*1.0)*(0.00000000000000000001957294106339126123+
 sqr(a*1.0)*(-0.000000000000000000000038681701706306840377+
 sqr(a*1.0)*(0.00000000000000000000000006446950284384473396+
 sqr(a*1.0)*(-0.000000000000000000000000000091836898637955461484+
 sqr(a*1.0)*0.0000000000000000000000000000001130996288644771693))))))))))))));
 writeln(c);
 writeln(sin(6));
duoda rezultatą:
-0.279415498042951 ir
-0.27941549819892587.


Toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1+
 sqr(a*1.0)*(-0.16666666666666667+
 sqr(a*1.0)*(0.0083333333333333333+
 sqr(a*1.0)*(-0.00019841269841269841+
 sqr(a*1.0)*(0.0000027557319223985891+
 sqr(a*1.0)*(-0.000000025052108385441718775+
 sqr(a*1.0)*(0.000000000160590438368216146+
 sqr(a*1.0)*(-0.00000000000076471637318198164759+
 sqr(a*1.0)*(0.000000000000002811457254345520763+
 sqr(a*1.0)*(-0.000000000000000008220635246624329717+
 sqr(a*1.0)*(0.00000000000000000001957294106339126123+
 sqr(a*1.0)*(-0.000000000000000000000038681701706306840377+
 sqr(a*1.0)*(0.00000000000000000000000006446950284384473396+
 sqr(a*1.0)*(-0.000000000000000000000000000091836898637955461484+
 sqr(a*1.0)*0.0000000000000000000000000000001130996288644771693))))))))))))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po 47 sekundžių su 2.6 GHz procesorium. Tokiu atveju jei skaičiuoti, kad padaroma 14 daugybų per 1 iteraciją, tada padaroma 47*2.6/14=8.73 taktų vienai daugybai. O jei skaičiuoti, kad padaromos 28 daugybos, tada padaromi 47*2.6/28=4 taktai per vieną daugybą. Jei skaičiuoti, kad dar padaroma 14 sudeties operacijų, tada iš viso su daugybomis padaromi 47*2.6/42=2.9 ciklai vienai operacijai. Jei skaičiuoti, kad padaroma 14*3=42 daugybos ir 14 sudėties operacijų, tada iš viso padaromos 56 operacijos, o vienai operacijai tenka 47*2.6/56=2.18 procesoriaus ciklo.


Skaičiuojant sinusą be iteracijų užtektų a pakelti kvadratu tik vieną kartą, todėl testuojamas toks Free Pascal kodas:
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1+
 sqr(a*1.0)*(-0.16666666666666667+
 a*(0.0083333333333333333+
 a*(-0.00019841269841269841+
 a*(0.0000027557319223985891+
 a*(-0.000000025052108385441718775+
 a*(0.000000000160590438368216146+
 a*(-0.00000000000076471637318198164759+
 a*(0.000000000000002811457254345520763+
 a*(-0.000000000000000008220635246624329717+
 a*(0.00000000000000000001957294106339126123+
 a*(-0.000000000000000000000038681701706306840377+
 a*(0.00000000000000000000000006446950284384473396+
 a*(-0.000000000000000000000000000091836898637955461484+
 a*0.0000000000000000000000000000001130996288644771693))))))))))))));
 writeln(c);
 Readln;
 End.
kuris duoda rezultatą   po 41 sekundės su 2.6 GHz procesorium.


Toks Free Pascal kodas (neturintis nieko bendro su sinusu):
 var a:longint; c:real;
 begin
 for a:=0 to 1000000000 do
 c:=c+a*(1+
 a*(0.16666666666666667+
 a*(0.0083333333333333333+
 a*(0.00019841269841269841+
 a*(0.0000027557319223985891+
 a*(0.000000025052108385441718775+
 a*(0.000000000160590438368216146+
 a*(0.00000000000076471637318198164759+
 a*(0.000000000000002811457254345520763+
 a*(0.000000000000000008220635246624329717+
 a*(0.00000000000000000001957294106339126123+
 a*(0.000000000000000000000038681701706306840377+
 a*(0.00000000000000000000000006446950284384473396+
 a*(0.000000000000000000000000000091836898637955461484+
 a*0.0000000000000000000000000000001130996288644771693))))))))))))));
 writeln(c);
 Readln;
 End.
duoda rezultatą   po lygiai 40 sekundžių su 2.6 GHz procesorium. Iš viso padaroma 15 daugybų ir 15 sudėčių per vieną iteraciją. Taigi, padaroma 30 operacijų per 1 iteraciją. Vienai operacijai reikia 40*2.6/30=3.4(6) ciklų. Apytiksliai reikia 3,5 ciklo vienai operacijai.
Grįžti į "Matematika/Sinuso Integralas" puslapį.