**Indian math Bhaskara sine formula and extensions, History math ** ---- This page is under development. Comments are welcome, but please load any comments in the comments section at the bottom of the page. Please include your wiki MONIKER in your comment with the same courtesy that I will give you. Its very hard to reply intelligibly without some background of the correspondent. Thanks,[gold] ---- <> ---- **Introduction** [gold] Here is some TCL starter code for Indian math Bhaskara sine formula and extensions. The Bhaskara sine formula is of historical interest, but has not been used since the era of the great Indian astronomers. ***Bhaskara sine function of historical interest*** The Bhaskara sine function or formula was the basis of sine tables edited by the Indian mathematician Bhaskara 1 in the seventh century. The Bhaskara sine function was possibly derived from the parabolic curve, from article in Mathematics Magazine by Dr . Shailesh A. Shirali. The Bhaskara sine formula and extended formulas are mostly for positive x < pi/2. Bhaskara used integers in the formula from the seventh century. Given the normal trig relations, the Bhaskara sine function can be extended to sind, cosd, tand in equivalence to the accuracy of 2nd order taylor series. As Dr . Shailesh A. Shirali demonstrated, the similarity of Bhaskara sine function to the Taylor and Pade formulas is worth some study. Often wondered whether the parabolic curve could be fudged into a sine or cosine curve. *** Bhaskara function and extensions into TCL code*** Details for loading TCL procedures. The Bhaskara sine function was extended into a set of TCL expressions into a catch-all TCL proc using degree measures. The original Bhaskara sine function used angle measurement in jotas, transformed into radians, and then transformed into cordics, according to the Shirali article. Here the formulas used the degree measures, although adaptations to radian measure are available. The Bhaskara sind was expr { (4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) }, for positive pi and 0>$xpi/2. Continuing in a similar manner, the derived Bhaskara tand was expr { $bhaskara_sindx/$bhaskara_cosdx } and the derived Bhaskara tand was expr {$bhaskara_cosdx/$bhaskara_sindx }. The derived bhaskara_secdx was expr { ( 32400.+$x*$x)/(4.*(90.-$x))*(90.+$x) } and bhaskara_cscdx was expr { ( 40500.-$x*(180.-$x))/(4.*$x*(180.-$x)) } . The Bhaskara step quadratic formulas and set up can be used to develop a crude tangent formula. These axioms were developed in the papers by Dr. Shirali , Stroethoff ,and Gupta. Some conditions are found in other Indian sutras: the sine tables were developed on a standard circle of 21600 minutes with a radius of 3438 minutes (for astronomy). The sind is sind(x) = x*(180-x)/8100. In polynomial P, the sind(P) = (4*P)/(5-P). The cosd is cosd(x) (90-x)+(180-(90-x)/8100. The tand is sind/cosd which expands to tand = (x*(180-x)/8100)/((90-x)+(180-(90-x)/8100). Reduction, tand = (x*(180-x)) /((90-x)*(90+x)). So far, these step equations have about an 8 percent error. Substituting P= x*(180-x)/8100 into sind = (4*P)/(5-P) gives the Bhaskara sine formula with 0.37 percent error. Boiling down pages of algebra, the Bhaskara sine formula is a quadratic equation of sind(x) = x*(180-x)/8100 that is evaluated in (4*P)/(5-P) at sind(30) = 1/2. A quadratic equation with solutions at 0 and 180 is transformed into an equation with solutions at 0,180,and 30 degrees. < The trial step equations in polynomial P are sin = (4*P)/(5-P);side ~ (5-P) - (4*P*4*P) / 4, cos ~ ((5-P) -(4*P*4*P)/4)/(5-P); tan ~ ((5-P) - (4*P*4*P) / 4)/((4*P)/(5-P)) > In the Grahalaghava manuscript of 1520 CE, the Indian mathematician Ganesa Daivajna published the Bhaskara formula with a different constant of 40320 versus the original Bhaskara constant of 40500. The error curve derived from the true sine minus formula(cc=40320) is largely negative, meaning the values of formula(cc=40320) are mostly above the true sine curve. As an inequality, true sine. <= formula(cc=40320) . Now compare the error curve derived from true sine minus formula(cc=40500), which does pass several times through the zero level representing the true sine. But the formula(cc=40500) is mostly positive and below true sine over the interval from 45 degrees (pi/4) to 135 degrees (3*pi/4). Thus in the region of greatest interest, the true sine lies between formula(cc=40500) and formula(cc=40350 )!! With conditions, the inequality exists that formula(cc=40500) <= true sine <= formula(cc=40350), over interval of (pi/4) to (3*pi/4). There are several ways to estimate an optimal constant in the Blaskara sine formula. Roughly the optimal constant is in a band between 40400 and 40500, based on trial and error at setting input angle aa at 45 degrees or pi/4. The error curve of cc = 40500 has maximum of +.0013 and minimum of -0.0016, average ABS extremes would be (0.0013+0.0016)/2 or 0.00145. Setting extremes to average 0.00145, cc = 40500 * (0.70710678-0.00145)/0.70710678,40416.95. The formula(cc=40417) had relative error of 0.068 percent versus the relative error of 0.173 percent on the original formula(cc=40500). The formula(cc=40417) gave roughly about 0.173/0.068 or 2.5 times improvement in relative error. But will continue to study the error bounds. A least squares method was fit to the sine curve with some known initial points from the small sine table. The 5 points were (0,0),(30,.5),(90,1),(150,.5), and(180,0). The quadratic curve fit to the sine was quad_sine = -0.00012094*x^2 +0.02176871*x -0.01360544, condition that 0<+A1<180 degrees. Another least squares fit was tried with points (0,0)(30,.5)(45,0.7071067811865476) and (90,1). The quadratic curve fit to the sine was = -9.84020089e-05*x^2 +2.00021484e-02*x -2.09138902e-03, condition that 0<+x<90 degrees. The quadratic formula for +x<90 was loaded into a TCL procedure and returned an error of 2 percent from the sine. Lets develop and model an error curve by spreadsheet sine minus quadratic formula. The error curve was modeled by another quadratic as error = 1.39361485e-05*x^2 -6.99389504e-04*x -1.15936030e-02. The sum of the quadratic fit and error fit curves was slightly better in tracking the spreadsheet sine, up to the limit or turning point of 90 degrees. Taking a clue from Bhaskara, other fits to the sine curve can be tried from an online curve fitter, using the least squares method. The cubic equation was sind = 1.077526*e^(-(x - 90)^2/(2*44.85532^2)), condition 0 90 | 100 | 0.98480775301221 | | | | |& &| 14 | 110 | 0.93969262078591 | | | | |& &| 15 | 120 | 0.86602540378444 | | | | |& &| 16 | 130 | 0.76604444311898 | | | | |& &| 17 | 140 | 0.64278760968654 | | | | |& &| 18 | 150 | 0.5 | | | | |& &| 19 | 160 | 0.34202014332567 | | | | |& &| 20 | 170 | 0.17364817766693 | | | | |& &| 21 | 180 | 0 | | | | |& ---- ***Screenshots Section*** ****figure 1. Original Bhaskara Sine with 40500 constant **** [Indian Math Bhaskara (1) Sine formula and extensions original bhaskara curve png] ****figure 2. Error of Bhaskara Sine with 40500 constant **** [Indian Math Bhaskara (1) Sine formula and extensions original bhaskara error] ****figure 3. Bhaskar_Stroethoff Sine with corrective poly **** [Indian math Bhaskara sine formula and extensions, bhaskara st plus poly png] ****figure 4. Error of Bhaskar_Stroethoff Sine with corrective poly **** [Indian Math Bhaskara (1) Sine formula and extensions ERROR CURVE PNG] ****figure 5. Error of Bhaskara Sine with 40320 constant **** [Indian math Bhaskara sine formula 40320 constant png errors] ****figure 6. Bhaskara_Stroethoff Cosine **** [Indian math Bhaskara sine formula and extensions b s cosine png] ****figure 7. Bhaskara_Stroethoff Cosine Error **** [Indian math Bhaskara sine formula and extensions COSINE ERROR PNG] ****figure 8. Spreadsheet tangent**** [Indian math Bhaskara sine formula and extensions spreadsheet tangent] ****figure 9. Curve fits to spreadsheet tangent**** [Indian Math Bhaskara (1) Sine formula and extensions tangent curve fits png] ****figure 10. Quadratic Curve fits to spreadsheet sine**** [Indian math Bhaskara sine formula quadratic sine fit] ****figure 11. Quadratic Curve fits to spreadsheet cosine**** [Indian Math Bhaskara (1) Sine formula quadratic fit to cosine png] ****figure 12. Quadratic Curve fit plus error curve, slightly better fit**** [Indian Math Bhaskara (1) Sine formula quadratic fit plus error pn] ****figure 13. Richards growth function converged to sine**** [Indian math Bhaskara sine formula richards growth function] ****figure 14. Richards growth function, plotted residuals**** [Indian math Bhaskara sine formula residuals ] ****figure 15. Gompertz growth function fitted to sine**** [Indian math Bhaskara sine formula gompertz growth function fitted to sine good fit] ****figure 16. Weibull growth function fitted to sine**** [Indian math Bhaskara sine formula weibull fitted] ****figure 17. Gaussian growth function fitted to sine**** [Indian Math Bhaskara (1) Sine formula gaussian sine fit] ---- In planning any software, it is advisable to gather a number of testcases to check the results of the program. The math for the testcases can be checked by pasting statements in the TCL console. **** Testcase 1 **** %|table 1|printed in| tcl wiki format|% &| quantity| value| comment, if any|& &| 1:|testcase_number | |& &| 765 original_angle_side1 :|degrees | original angle reduced for computation |& &| 45.0 :|degrees | entry angle after reduction |& &| 0.017453292519943 :|answers : conv. to radians | |& &| 0.7058823529411765 :|cosd function | math.h derived cosd 0.7071067811865569 |& &| 1.0 :|tand function| math.h derived tand 0.9999999999999735 |& &| 1.0 :|cotd function | |& &| 1.4166666666666667 :|secd function | |& &| 1.4166666666666667 :|cscd function | |& &| 0.7058823529411765 :|sind function | math.h derived cosd 0.7071067811865569 |& **** Testcase 2 **** %|table 2|printed in| tcl wiki format|% &| quantity| value| comment, if any|& &| 1:|testcase_number | |& &| 60 original_angle_side1 :|degrees | original angle reduced for computation |& &| 60 :|degrees | entry angle after reduction |& &| 0.017453292519943 :|answers : conv. radians, used in arc functions | |& &| 0.5 :|cosd function|comparison math.h derived cosd 0.5000000000000153 |& &| 1.7297297297297298 :|tand function|comparison math.h derived 1.7320508075688066 |& &| 0.578125 :|cotd function | |& &| 2.0 :|secd function | |& &| 1.15625 :|cscd function | |& &| 0.8648648648648649 :|sind function | comparison math.h sind 0.8660254037844298 |& ---- **** Testcase 3 **** %|table 3|printed in| tcl wiki format|% &| quantity| value| comment, if any|& &| 3:|testcase_number | |& &| 20 original_angle_side1 :|degrees | original angle reduced for computation |& &| 20 :|degrees | entry angle after reduction |& &| 0.017453292519943 :|answers : conv. radians, used in arc functions | |& &| 0.9390243902439024 :|cosd function| comparison math.h derived cosd 0.9396926207859104 |& &| 0.3654468855541242 :|tand function|comparison math.h derived tand 0.3639702342661957 |& &| 2.736375762195122 :|cotd function | |& &| 1.0649350649350648 :|secd function | |& &| 2.9140625 :|cscd function | |& &| 0.34316353887399464 :|sind function |comparison math.h derived sind 0.34202014332566316 |& ---- **** Testcase 4 **** %|table 4|printed in| tcl wiki format|% &| quantity| value| comment, if any|& &| 4:|testcase_number | |& &| 179. original_angle_side1 :|degrees | original angle reduced for computation |& &| 179. :|degrees | entry angle after reduction |& &| 0.017453292519943 :|answers : conv. to radians | |& &| -1.4860725314628884 :|cosd function| |& &| -0.011949279539112682 :|tand function| |& &| -83.68705382837308 :|cotd function | |& &| -0.6729146652186625 :|secd function | |& &| 56.314245810055866 :|cscd function | |& &| 0.01775749609384688 :|sind function | |& bhaskara_sinx 179. 0.01775749609384688 179 deg comparison tcl derived cosd -0.9998476951563903 sind 0.017452406437336275 tand -0.01745506492827037 atan 1.261013419037191 ---- ***References:*** * search keywords for "faster" trig approximations. * sin cos tan trig series efficient approximation "nested polynomial" multiplication * "Horner's method" "Horner's form" recursive telescoping * The Bhaskara-Aryabhata Approximation to the Sine Function, * Author(s): Dr. Shailesh A. Shirali, Source: Mathematics Magazine, * Vol. 84, No. 2 (April 2011), pp. 98-107 * Payne, Mary H.; Hanek, Robert N., Radian reduction for Large Angles, * implemented on Sparc 3, probably C++ code and bit instructions * Argument reduction for huge arguments: Good to the Last Bit, * K. C. Ng, SunPro Works , March 24, 1992 * High Precision Calculation of Arcsin x, Arceos x, and Arctan * By I. E. Perlin and J. R. Garrett, ie. polynomial approximation * A Fast-Start Method for Computing the Inverse Tangent, * Peter Markstein, Hewlett-Packard Laboratories * Faster Math Functions, Robin Green , Sony Computer Entertainment America * Bhaskara 1's approximation to sine, R.C. Gupta,1967 * very detailed on multiple versions of Bhaskara sine formula * Wikipedia, Bhaskara I's sine approximation formula * Bhaskara’s approximation for the Sine, Karel Stroethoff ---- **Appendix Code** ***appendix TCL programs and scripts *** ***console TCL script for Bhaskara sine formulas *** ====== # Indian math Bhaskara sine formula and extensions, History math # pretty print from autoindent and ased editor # Bhaskara sine formula and extensions into TCL # written on Windows XP on TCL # working under TCL version 8.5.6 # gold on TCL WIKI , 20dec2017 package require Tk package require math::numtheory package require math::geometry package require math::constants package require math::bigfloat namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants math::bigfloat} #namespace import ::math::bigfloat::* set tclprecision 17 wm title . "Bhaskara sine formula and extensions into TCL" console show proc degree_reduction {aa} { if { $aa > 360. } { while {$aa > 360.} { set aa [- $aa 360.] } return $aa } if { $aa < -360. } { while {$aa < -360.} { set aa [+ $aa 360.] } return $aa } return $aa } proc reportx {} { global bhaskara_sindx bhaskara_cosdx bhaskara_tandx x angle_keeper global bhaskara_secdx bhaskara_cscdx bhaskara_cotandx reduced_angle set testcase_number 1 puts "%|table $testcase_number|printed in| tcl wiki format|% " puts "&| quantity| value| comment, if any|& " puts "&| $testcase_number:|testcase_number | |&" puts "&| $angle_keeper original_angle_side1 :|degrees | original angle reduced for computation |&" puts "&| $reduced_angle :|degrees | entry angle after reduction |&" puts "&| $math::constants::degtorad :|answers : conv. to radians | |& " puts "&| $bhaskara_cosdx :|cosd function| |& " proc bhaskara_tandx {x} { # probably use globals to fill out wiki table global bhaskara_sindx bhaskara_cosdx bhaskara_tandx angle_keeper global bhaskara_secdx bhaskara_cscdx bhaskara_cotandx reduced_angle set angle_keeper $x set reduced_angle [ degree_reduction $x ] set x [ degree_reduction $x ] # uncomment below to return to radian measure #set x [* $x $math::constants::degtorad ]; # sind was -pi< x >pi, # but other trig funcs were mostly positive x < pi/2 set pi $math::constants::pi set bhaskara_sindx [ expr { (4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] set bhaskara_cosdx [ expr { ((4.*(90.-$x))*(90.+$x))/( 32400.+$x*$x) } ] set bhaskara_tandx [ expr { $bhaskara_sindx/$bhaskara_cosdx } ] set bhaskara_cotandx [ expr {$bhaskara_cosdx/$bhaskara_sindx } ] set bhaskara_secdx [ expr { ( 32400.+$x*$x)/((4.*(90.-$x))*(90.+$x)) } ] set bhaskara_cscdx [ expr { ( 40500.-$x*(180.-$x))/(4.*$x*(180.-$x)) } ] set result $bhaskara_tandx return $result } puts "&| $bhaskara_tandx :|tand function| |&" puts "&| $bhaskara_cotandx :|cotd function | |&" puts "&| $bhaskara_secdx :|secd function | |&" puts "&| $bhaskara_cscdx :|cscd function | |&" puts "&| $bhaskara_sindx :|sind function | |&" } puts " bhaskara_tandx 765 [ bhaskara_tandx 360045.0000000000001 ] " reportx # output # bhaskara_tandx 45 1.0 ====== ---- ====== # folding statements for Bhaskara sine #Extending the Bhaskara sine into other N*180 regions #is possible with fold and multiply -1. statements ( slang fold and flip) . # for 180 < $x < 360, fold to 0-180 degrees and multiply -1. set bhaskara_sindx [ expr { (4.*$x*(180.-$x))/( 40461.287-$x*(180.-$x)) } ] if { $x > 179.9999999 && $x < 359.9999999 } { set x [- $x 180. ]; set bhaskara_sindx [ expr { -1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } if { $x > -360 && $x < -180.0000001 } { set x [+ $x 360. ]; set bhaskara_sindx [ expr { +1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } if { $x > -180 && $x < -0.0000001} { set x [+ $x 180. ]; set bhaskara_sindx [ expr { -1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } ====== **** Extending the Bhaskara sine formula **** ====== # bhaskara_stroethoff_sine, corrected bhaskara sine with polynomial # sine limits are 0 aa<180 proc bhaskara_stroethoff_sine_c_40417 {aa} set bhaskara_sind_ext [ expr { (4.*$x*(180.-$x))/( 40417.-$x*(180.-$x)) } ] set result $bhaskara_sind_ext return $result } ====== ---- *** Bhaskara quadrant switch *** ====== # Bhaskara quadrant switch # pretty print from autoindent and ased editor # Bhaskara sine formula and extensions into TCL # written on Windows XP on TCL # working under TCL version 8.5.6 # gold on TCL WIKI , 20dec2017 package require Tk package require math::numtheory package require math::geometry package require math::constants package require math::bigfloat namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants math::bigfloat} #namespace import ::math::bigfloat::* set tclprecision 17 wm title . "Bhaskara quadrant switch " console show if {0} { set pi $math::constants::pi set bhaskara_sindx [ expr { (4.*$x*(180.-$x))/( 40320.-$x*(180.-$x)) } ] if { $x > 179.9999999 && $x < 359.9999999 } { set x [- $x 180. ]; set bhaskara_sindx [ expr { -1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } if { $x > -360 && $x < -180.0000001 } { set x [+ $x 360. ]; set bhaskara_sindx [ expr { +1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } if { $x > -180 && $x < -0.0000001} { set x [+ $x 180. ]; set bhaskara_sindx [ expr { -1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ] } } #proc errorx always returns a positive error. #Normally assume $aa is human estimate, #assume $bb is divinely exact. proc errorx {aa bb} {expr { $aa > $bb ? (($aa*1.)/$bb -1.)*100. : (($bb*1.)/$aa -1.)*100.}} # proc sinl { aa } { # switch for -360 < aa < 360 # 4 cases of 180 degrees each set quadrant 1 set quadrant [+ [int [/ $aa 180.] ] 1] # puts dropped for timing checks # puts " $aa $quadrant " if { $aa < 0 } { set quadrant [+ [int [/ $aa 180.] ] 4 ]} # puts dropped for timing checks # puts " $aa $quadrant " set quadrant 0x$quadrant set x $aa set sinl 1 set number 0x5 #switch -- [format %d $quadrant] switch -exact [format %d $quadrant] { 1 {set sinl [ expr { +1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ]} 2 {set x [- $x 180. ]; set sinl [ expr { -1.*(4.*$x*(180.-$x))/( 40320.-$x*(180.-$x)) } ]} 3 {set x [+ $x 360. ];set sinl [ expr { +1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ]} 4 {set x [+ $x 180. ];set sinl [ expr { -1.*(4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) } ]} default {return "default = unknown error out of bins"} } return $sinl} set count -350 set aa -350 while {$aa < 340.} { set aa $count set x [* $aa $math::constants::degtorad ] puts " homebrew sinl $aa [ sinl $aa ] comparison tcl derived sind [sin $x ] error [ errorx [ sinl $aa ] [sin $x ] ] "; incr count 30 } # testing switch TCL switch proc set $aa 45. set x [* $aa $math::constants::degtorad ] puts " homebrew sinl 45 [ sinl $aa ] comparison tcl derived sind [sin $x ] " puts " timing quadrant 1 time is [ time { sinl $aa } 10 ] " puts " timing TCL_sin time is [ time { sin $x } 10 ] " puts " timing quadrant 1 time is [ time { sinl $aa } 10 ] " puts " timing TCL_sin time is [ time { sin $x } 10 ] " proc time_tester {tt} { set result "" set number 0x5 switch -- [format %d $number] { 5 {set result "switch works " } default {set result " switch unknown, default = unknown error out of bins"} } return $result} puts " [ time_tester 1 ] " puts " timing time_tester 1 [ time_tester 1 ] time is [ time { time_tester 1 } 100 ] " # The Bhaskara trig functions have optimum accuracy between origin and pi/4. # The Bhaskara trig functions continue to degrade after pi/4. The folding into # quadrants of 90 degrees or sectors of 180 degrees help correct the # functions, but do not eliminate the trend past pi/4. ====== ---- output ====== homebrew sinl -350 0.17525773195876287 comparison tcl derived sind 0.17364817766703186 error 0.9269053746232325 homebrew sinl -320 0.6418338108882522 comparison tcl derived sind 0.6427876096866116 error 0.1486052592086784 homebrew sinl -290 0.9390243902439024 comparison tcl derived sind 0.9396926207859377 error 0.07116221356739949 homebrew sinl -260 0.9846153846153847 comparison tcl derived sind 0.9848077530121948 error 0.019537415301029704 homebrew sinl -230 0.7647058823529411 comparison tcl derived sind 0.7660444431189345 error 0.17504256170681742 homebrew sinl -200 0.34316353887399464 comparison tcl derived sind 0.34202014332561315 error 0.3343064935485307 homebrew sinl -170 -0.17525773195876287 comparison tcl derived sind -0.17364817766697968 error -0.9183927429586514 homebrew sinl -140 -0.6418338108882522 comparison tcl derived sind -0.6427876096865711 error -0.14838475165754872 homebrew sinl -110 -0.9390243902439024 comparison tcl derived sind -0.9396926207859195 error -0.07111160897042001 homebrew sinl -80 -0.9846153846153847 comparison tcl derived sind -0.9848077530122039 error -0.019533598941601227 homebrew sinl -50 -0.7647058823529411 comparison tcl derived sind -0.7660444431189686 error -0.17473669811864934 homebrew sinl -20 -0.34316353887399464 comparison tcl derived sind -0.34202014332566316 error -0.33319260900597225 homebrew sinl 10 0.17525773195876287 comparison tcl derived sind 0.17364817766692744 error 0.9269053746839173 homebrew sinl 40 0.6418338108882522 comparison tcl derived sind 0.6427876096865303 error 0.14860525919599965 homebrew sinl 70 0.9390243902439024 comparison tcl derived sind 0.9396926207859013 error 0.07116221356351371 homebrew sinl 100 0.9846153846153847 comparison tcl derived sind 0.9848077530122132 error 0.01953741530289488 homebrew sinl 130 0.7647058823529411 comparison tcl derived sind 0.7660444431190025 error 0.1750425617157214 homebrew sinl 160 0.34316353887399464 comparison tcl derived sind 0.3420201433257131 error 0.3343064935191986 homebrew sinl 190 -0.17607457276022787 comparison tcl derived sind -0.17364817766687493 error -1.3780496839013279 homebrew sinl 220 -0.6451612903225806 comparison tcl derived sind -0.6427876096864896 error -0.3679204985941098 homebrew sinl 250 -0.944206008583691 comparison tcl derived sind -0.9396926207858832 error -0.47800879858600487 homebrew sinl 280 -0.9900990099009901 comparison tcl derived sind -0.9848077530122225 error -0.5344169457655368 homebrew sinl 310 -0.768775872264932 comparison tcl derived sind -0.766044443119037 error -0.35529589890066493 homebrew sinl 340 -0.3448275862068966 comparison tcl derived sind -0.3420201433257629 error -0.8141584355287557 homebrew sinl 45 -0.3448275862068966 comparison tcl derived sind -0.3420201433257629 timing quadrant 1 time is 21.5 microseconds per iteration timing TCL_sin time is 2.7 microseconds per iteration quadrant 1 time is 20.6 microseconds per iteration TCL_sin time is 2.8 microseconds per iteration switch works timing time_tester 1 switch works time is 3.98 microseconds per iteration ====== ---- ====== # test code for very rough tangent # based on early statement derivations # early base of Bhaskara derivations proc tanm {x} { set tanm [ expr { ($x*(180.-$x))/((90.-$x)*(90.+$x)) }] return $tanm } # tanm 45. 1.0 # tanm 30. 0.625 , should be (sqrt 3) /3, error 8 percent proc sin_angle_reduction {aa } {set pi [ expr { acos(-1) } ]; expr {abs($aa)>360? asin ( sin($aa*($pi/180.)) ) * (180./$pi) : $aa } } puts " sin angle reduction [ sin_angle_reduction 30. ] " puts " sin angle reduction [ sin_angle_reduction 760. ] " puts " sin angle reduction [ sin_angle_reduction -760. ] " puts " timing sin angle reduction [ time {sin_angle_reduction -760. } 100 ] " puts " timing degree_reduction [ degree_reduction 900005.0000000000001 ] " puts " timing degree_reduction [ time {degree_reduction 900055.0000000000001 } 100 ] " # sin angle reduction 30.0 #sin angle reduction 40.00000000000003 #sin angle reduction -40.00000000000003 #timing sin angle reduction 5.7 microseconds per iteration #timing degree_reduction 4.98 microseconds per iteration ====== ---- *** Kahan summation algorithm*** **Introduction** [gold] Here is some TCL starter code for the Kahan summation algorithm. The Kahan summation algorithm is used to counter round-off error with some effectiveness. Note: One won't see these (single precision) errors in normal TCL 8.6 use. The TCL script below uses to force single precision (sp) on expr and math operator statements. Expr from TCL 8.6 uses double precision inside its calculations and throws round off errors beyond normal sp use. However, this example of the kahan summation algorithm seems to be working correctly and can be compared to the gimmicked summation procs below. Kahan, Neumaier, Babuska, and others developed balanced or compensated summation algorithms. Some balanced algorithms subtract the compensations from the summing terms as the terms accumulate. Other balanced algorithms model total compensation with a first, second, or nth order curve and subtract the total compensation from the total terms at the end. Second order balanced algorithms can require 50 percent more time, but could be worth it for more accuracy ( eg. function tables). ---- **Pseudocode Section** ====== # using pseudocode for Kahan summation algorithm # possible problem instances for large angles n*360 degrees angle reduction degrees N50*740.00000000001 format %17.15f 280.000000000050930 angle reduction degrees N150*740.00000000001 format %17.15f 120.00000000016007 trying to "cure" or slow growth of tail digits from round off digits, dp shown # kahan summation algorithm in pseudocode a(i) = sequence of floating point numbers, a(i)>=3 c = keeper result sum of floating point numbers loop following y = a(i) -c t = sum + y c = (t-sum)-y sum = t 10000.0, 3.14159, 2.71828= (a + b) + c => single precision fp errors => 10005.8. Kahan function a, b, c results in 10005.9 ref normal TCL precision 12 or 17, expr is double precision inside calculations and not show these errors in sp. have to reproduce rd. error in single precision have to add fp format statements correct for inputs of large angles and accumularted round off errors check_answer (a + b) + c =? a + ( b + c ) (yes/no) set answers and printout with resulting values ====== ---- ***References:*** * search keywords for "faster" trig approximations. * sin cos tan trig series efficient approximation "nested polynomial" multiplication * "Horner's method" "Horner's form" recursive telescoping * Payne, Mary H.; Hanek, Robert N., Radian reduction for Large Angles, * implemented on Sparc 3, probably C++ code and bit instructions * Argument reduction for huge arguments: Good to the Last Bit, * K. C. Ng, SunPro Works , March 24, 1992 * SIAM J. Sci. Comput. Volume 31, Issue 1, pp. 189-224 (2008) * Accurate floating-point summation, part 1: faithful rounding * Siegfried M. Rump, Takeshi Ogita, and Shin Ichi Oishi * Design and Implementation of a High Precision Arithmetic * with Rigorous Error Bounds, * Alexander Wittig, MSUHEP-081126, December 2008 * A generalized Kahan-Babuska Summation Algorithm, * Andreas Klein, April 21, 2005 * implement a better summation algorithm, · Issue #199, · JuliaLang * Kahan's compensated summation algorithm, * William Kahan, Further remarks on reducing truncation errors. * Comm. ACM, 8:40, 1965 * Kahan and Babuska summation algorithm, Neumaier variant * A. Neumaier, Rundungsfehleranalyse einiger Verfahren * zur Summation endlicher Summen, in German * Math. Mechanik, 54:39–51, 1974. ---- *** Console TCL script for angle reduction with kahan summation algorithm*** ====== # console program for angle reduction with kahan algorithm # pretty print from autoindent and ased editor # kahan summation algorithm into TCL # written on Windows XP on TCL # working under TCL version 8.6 # gold on TCL WIKI , 8jan2017, kahan_baby3 package require Tk package require math::numtheory package require math::geometry package require math::constants package require math::bigfloat namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants math::bigfloat} #namespace import ::math::bigfloat::* set tclprecision 17 #set tclprecision 8 wm title . "angle reduction with kahan algorithm" console show proc summer_w_rd_error { lister } { set sum 0 foreach number $lister { set sum [+ $sum [ format %7.1f $number ] ] } # statement to recreate single precision r. errors set sum [ format %7.1f $sum ] return $sum} proc summer_w_rd_expr { lister } { set sum 0 foreach number $lister { set number [ format %7.1f $number ] set sum [ expr { $sum + $number } ] } # statement to recreate single precision r. errors set sum [ format %7.1f $sum ] return $sum} proc kahan_summation {lister} { set a {10000.0 3.14159 2.71828 } set b {9879879.88 6585497.99 875870989.54 765864865479.32 } set c { 1. 2. 3. } set compensation_keeper2 0 set sum 0 set counter 0 set yaada2 0 set term2 0 foreach number $lister { set yaada2 [- $number $compensation_keeper2 ] set term2 [+ $sum $yaada2 ] set compensation_keeper2 [- [- $term2 $sum ] $yaada2 ] set sum $term2 incr $counter} # statement to recreate single precision r. errors set sum [ format %7.1f $sum ] return $sum } proc degree_reduction {aa} { if { $aa > 360. } { while {$aa > 360.} { set aa [- $aa 360.] } return $aa } if { $aa < -360. } { while {$aa < -360.} { set aa [+ $aa 360.] } return $aa } return $aa } set kipper { 10000.0 3.14159 2.71828 } puts " normal expr summation, dp inside expr,format %7.1f [format %7.1f [ expr { 10000.0 + 3.14159 + 2.71828 } ] ]" puts " modify summer_w_rd_error, format %7.1f [ summer_w_rd_error $kipper ] " puts " modify summer_w_rd_expr, format %7.1f [ summer_w_rd_expr $kipper ] " puts " trial kahan summation, format %7.1f [ kahan_summation $kipper ] " puts " angle reduction degrees 740.00000000001 [ degree_reduction 740.000000000001 ] " ====== ---- output ====== # normal expr summation, dp inside expr,format %7.1f 10005.9 # modify summer_w_rd_error, format %7.1f 10005.8 # modify summer_w_rd_expr, format %7.1f 10005.8 # trial kahan summation, format %7.1f 10005.9 # angle reduction degrees 740.00000000001 20.000000000001023, # due to round off error # angle reduction degrees N50*740.00000000001 format %17.15f 280.000000000050930 # angle reduction degrees N150*740.00000000001 format %17.15f 120.000000000160070 ====== ---- *** Console TCL script for neumaier summation algorithm*** ====== # console program for neumaier summation algorithm # pretty print from autoindent and ased editor # neumaier algorithm summation algorithm into TCL # written on Windows XP on TCL # working under TCL version 8.6 # gold on TCL WIKI , 8jan2017,neumaier_baby5 package require Tk package require math::numtheory package require math::geometry package require math::constants package require math::bigfloat namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants math::bigfloat} #namespace import ::math::bigfloat::* set tclprecision 17 #set tclprecision 8 wm title . " neumaier algorithm" console show #10000.0, 3.14159, 2.71828= (a + b) + c # (a + b) + c =? a + (b + c) # => single precision fp errors => 10005.8. # neumaier algorithm a, b, c results in 10005.9 proc neumaier_summation {lister} { set a {10000.0 3.14159 2.71828 } set b {9879879.88 6585497.99 875870989.54 765864865479.32 } set c { 1. 2. 3. } set k { 1.0 +1.E100 1.0 -1.E100 } set keeper 0 set sum 0 set counter 0 set term2 0 set keeperx 0 foreach number $lister { set term2 [+ $sum $number ] if { [abs $sum ] >= [abs $number ] } { set keeper [+ [- $sum $term2 ] $number ] } else { set keeper [+ [- $number $term2 ] $sum ] } set sum $term2 set keeper2 $keeper set keeperx [+ $keeperx $keeper2 ] incr $counter} # statement to recreate single precision r. errors set sum [ format %7.1f $sum ] set keeper [ format %7.1f $keeper ] # puts " sum $sum keeper $keeper sum+keeper [+ $sum $keeper ] $sum $keeperx [+ $sum $keeperx ]" return [ format %7.1f [+ $sum $keeperx ]] } set kipper { 10000.0 3.14159 2.71828 } set kipper { 1.0 +1.E16 1.0 -1.E16 } set kipper { 1. 2. 3. } set kipper { 10000.0 3.14159 2.71828 } puts " normal expr summation, dp inside expr,format %7.1f sum { 10000.0 3.14159 2.71828 } [format %7.1f [ expr { 10000.0 + 3.14159 + 2.71828 } ] ]" puts " normal expr summation, dp inside expr,format %7.1f sum { +1.0 + +1.E15 + +1.0 + -1.E15 } [format %7.1f [ expr { +1.0 + +1.E15 + +1.0 + -1.E15 } ] ]" puts " trial neumaier summation, format %7.1f sum { 10000.0 3.14159 2.71828 } [ neumaier_summation $kipper ] " set kipper { 1.0 +1.E16 1.0 -1.E16 } puts " trial neumaier summation, format %7.1f sum { 1.0 +1.E16 1.0 -1.E16 } [ neumaier_summation $kipper ] " set kipper { 1. 2. 3. } puts " trial neumaier summation, format %7.1f sum { 1. 2. 3. } = [ neumaier_summation $kipper ] " # normal expr summation, dp inside expr,format %7.1f sum { 10000.0 3.14159 2.71828 } 10005.9 # normal expr summation, dp inside expr,format %7.1f sum { +1.0 + +1.E15 + +1.0 + -1.E15 } 2.0 # trial neumaier summation, format %7.1f sum { 10000.0 3.14159 2.71828 } 10005.9 # trial neumaier summation, format %7.1f sum { 1.0 +1.E16 1.0 -1.E16 } 2.0 # trial neumaier summation, format %7.1f sum { 1. 2. 3. } = 6.0 ====== ---- *** Classic sigmoidal functions in TCL script *** ====== proc sindgaussian {x} { # fit gaussian growth curve to sine # condition 0<+x<90 #set x [* $x $math::constants::degtorad ]; set A 0.27601397923E+01 set B 0.89847055041E+02 set C -0.17926590835E+05 set D -0.17602884876E+01 set x [ expr { $A*exp((($x-$B)**2)/$C)+$D }] return $x} proc sindrichards {x} { # fit richards growth curve to sine # condition 0<+x<90 #set x [* $x $math::constants::degtorad ]; set A 0.48154253688E-07 set B 0.10525783963E-05 set C -0.59573538036E-01 set D 0.87125623376E-01 set E -0.32971579577E+01 set x [ expr { 1./($A+$B*exp($C*$x))**$D+$E }] return $x} proc sindgompertz {x} { # fit gompertz growth curve to sine # "double exponential fits most anything" # condition 0<+x<90 #set x [* $x $math::constants::degtorad ]; set A 0.12218253807E+01 set B -0.20592195352E+01 set C -0.38221525189E-01 set D -0.13115026413E+00 set x [ expr { $A*exp($B*exp($C*$x))+$D }] return $x} puts " sindgaussian 30 [ sindgaussian 30 ] " puts " sindrichards 30 [ sindrichards 30 ] " puts " sindgompertz 30 [ sindgompertz 30 ] " ====== ---- [gold] This page is copyrighted under the TCL/TK license terms, [http://tcl.tk/software/tcltk/license.html%|%this license]. **Comments Section** <> Please place any comments here, Thanks. <> Numerical Analysis | Toys | Calculator | Mathematics| Example| Toys and Games | Games | Application | GUI ---- <> Development | Concept| Algorithm