Updated 2017-12-16 09:01:43 by gold

Trig Procedures for degree measures as sind, cosd, tand,etc edit

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

gold Here is some TCL starter code for Trig Procedures using degree measures as sind, cosd, tand, etc. Recognise these trig functions (with radian measures) are convertible with your degToRad and radToDeg math::constants in the TCLLIB, but the usual trigonometric functions with input values as scalar or vector in degrees might be convenient to some users.

In planning any software, it is advisable to gather a number of testcases to check the results of the program. Here, a TCL slot calculator is being used as a testbed for trig procedures. The results of the testcases are estimated using the hand calculator and then checked in the slot calculator. Pseudocode and equations are developed from the hand calculations and theory. Small console programs are written to check or proof the alternate subroutines or procedures, rather than keeping the unblessed code and comment lines in the main slot calculator. Finally the improved or alternate subroutines are loaded into the slot calculator. The TCL slot calculator is effectively a shell program to input entries, retain loaded standard testcases, host calculation routines, and display results. Additional significant figures are used to check the TCL calculator, not to infer the accuracy of inputs and product reports.

The testbed is mostly using Padé trig functions, but it is clear that the Padé trig functions are accurate only at small angles. The calculator needs an angle reduction system and ranged switch installed. Pade' or Padé is a French mathematician with an accent, but pade as ASCII is used from the variables here. .

Angle reduction

Based on intervals of pi/4 or pi/N, there are several angle reduction algorithms under consideration. Angle $aa below pi/4 would have no correction needed. Angle $aa below -180 or above 180 degrees could be corrected by substitution table. Angle $aa below -360 or above 360 degrees could be partially corrected by available procedure and then reduced by other techniques. The algorithm for large angles (>> pi/4) known locally as the sin+cos angle sum algorithm has been implemented in C++ and Sparc fortran, but seems complex for the proposed TCL implementation.

Avenues for better accuracy

Avenues for better accuracy. Because the accuracy of the Pade trig functions degrade away from the origin point of computation, then the evaluation of the Pade trig functions should be restricted to the interval -(pi/4) to +(pi/4) for better accuracy. Mostly the Pade functions in the monographs are computed near the conventional origin (0,0), but moving the computation point of the Pade function near the evaluation interval of the specific angle is conceivable. The paper math to move the computation point would be heavy, but possibly a computation algorithm would be possible. The Pade function evaluation is generally a thousand or thousands of times more accurate in the interval near the origin point of computation. Since the trig functions are periodic and wrap around, subtracting +- 360 degrees from angles outside the -+360 degree interval would be a partial solution. Multiplication by 1/(2.*pi) or 1/(360) would reduce an angle inside the -+360 degree interval to inside the -+(pi/4). Then the double angle theorem or power angle theorem could be used to find the transform of the specific angle, ref monograph by Mendenhall.

Using Pade_ln(1+x) 720 as an analogy for a trig function, precede with multiplication 720*(1./360.) = 2.0. The third order Pade function would evaluate as Pade_ln_1_x(720) as` 3.6336653842253304, showing substantial error due to distance from the computation origin. The TCL_eval ( log 720) gives 6.579251212010101. The relative error was expr (6.5792-3.6336)/-3.6336) or 81 percent. 0.693121693121693. Closer to the computation origin, the Pade_ln_1_x(2 ) gives 0.693121693121693. The TCL_eval ( log 2) gives 0.6931471805599453. Near the computation origin, the relative error was expr (0.69314718-0.69312169)/0.69312169 , 3.67E-5. For the example of the Pade_ln, the relative error was .81/3.67E-5 or 2.2E4 greater distant from the function computation point. If the general solution ln(a*b) = ln(a) + ln(b) is used as a sort of transform, then ln(2*(360.)) = ln(2)+ln(360.). Adding Ln(360.) to Pade_ln(2) would give 5.886104031450156 + 0.693121693121693 as transform 6.579225724571849. An error would still be present as (6.579225724571849-6.579251212010101)/ 6.579251212010101 or error of 3.87e-6. Also, ln 360. or 5.8 can be treated as constant or fixed number in subroutine, rather than evaluated each time. An all Pade_ln would be possible eval ln(360.) as the sum of the Pade_ln for each small prime factor of 360 (2, 2, 2, 3, 3, 5). The all Pade_ln solution would be Pade_ln(2) + Pade_ln(2,2,2,3,3,5) as 6.747276688453158. The error from the TCL eval (log 720) would be expr (6.747276688453158-6.579251212010101)/6.579251212010101 or 2.5 percent error. Not sure about the exact antidotal numbers, but finding the Pade solution near the function computation point (usually 0,0) and transforming the solution to a more distant region seems possible.

Of course, the snag in small angle theory is that sin(n*x) =! n*sin(x), so sin(x) can be calculated as a small angle and then a transform must be used. The algorithm for large angles (>> pi/4) known locally as the sin+cos angle sum algorithm has been implemented in C++ and Sparc fortran. The c++ strategy in Umut's tech-blog seems fast and understandable to implement using the sin+cos angle sum. The essential strategy is breaking an angle into the sum of a large angle and small angle, then using small angle theory to find sin (and cos) of the small angle and then transforming the small angle solution into the region of the original combined angle, angle sum formula. The sin and cos components of the large angle at 10 degree intervals can be stored in tables for the transform. A similar strategy may be undertaken with the sin and cos recurrence formula as sin(n*x)=2*sin((n-1)*x)*cos(x) - sin ((n-2)*x). Subbing 361 for n, sin(361*x)=2*sin((361-1)*x)*cos(x) - sin ((361-2)*x) and reduction of terms, sin(361*x)=2*sin((360)*x)*cos x - sin ((360-1)*x). Since sin(360*x) is equivalent to sin(x), then sin(361*x)=2*sin(x)*cos (x) - sin ((360-1)*x). A small angle called alpha from original x, alpha=x*(1./361.). Since there will be some inaccuracy from the small angle theory, the TCL script procedure can probably use the approximations alpha=x*(1./361.);sin(361*alpha)=~~ 2*sin(alpha)*cos (alpha) - sin (alpha). Hence the small angle approximations for both sin (alpha) and cos (alpha) are loaded into procs. When the sin and cos recurrence code is more confident, then pade_trig procs could replace the small angle procs.

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 or believed 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 seventh century, but a post on Math Exchange suggested constants could be gamed or normalized to fit sine curve better. 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.

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 either the degree or radian measures. The Bhaskara sind was expr { (4.*$x*(180.-$x))/( 40500.-$x*(180.-$x)) }, for positive pi and 0>$x<pi. Dr. Shirali used the the identity cos(a)deg = sin(90-x) deg for the derived Bhaskara cosd of expr { (4.*(90.-$x))*(90.+$x)/( 32400.+$x*$x) }, -pi/2<$x>pi/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_cscdx was expr { ( 32400.+$x*$x)/(4.*(90.-$x))*(90.+$x) } and bhaskara_cscdx was expr { ( 40500.-$x*(180.-$x))/(4.*$x*(180.-$x)) } . One post on the Math Exchange gave another Bhaskara sine version as expr { (16.*($pi-$aa)*$aa) / (5.*$pi*$pi-4.*($pi-$aa)*$aa) } in radian measure and integer constants. Bhaskara used integers in the seventh century, but post on Math Exchange suggested constants could be gamed or normalized to fit sine curve better. A normalized derivative formula with constant (16+d ) was expr { (16.+ *($pi-$aa)*$aa) / (5.*$pi*$pi-4. *($pi-$aa)*$aa) }. A simple corrective constant evaled at 45 degrees would be 16*0.7071 /0.7058 or 16.0295 as an example. Most of the normalized curves are fit at several points, if not least squares.

Pseudocode Section edit

    # using  pseudocode for  procedure algorithm.
        3 quantities needed
        angle a  in radians. Multiply by pi/180 to convert degrees to radians.
        a in radians
        package require math::constants
        radtodeg = 57.295779513100001 = Conversion from radians to degrees
        degtorad = 0.017453292519943001 = Conversion from degrees to radians
        set con5 $math::constants::degtorad 
        set con6 $math::constants::radtodeg 
         invoke 0.017453292519943001 
        set a [* $a (3.14/180) ] , 3.14/180~0.01744
        set a [sin  $a  ] 
        return $a
        sind =  sin(0.174 * x), fortran 90 
        sin  =  sin(op) 
        cos  =  cos(op) 
        tan  =  tan(op)
        sind =  sin(op*(PI/180.0)) 
        cosd =  cos(op*(PI/180.0))
        tand =  tan(op*(PI/180.0))
        poss. sin(x) = 
        x^1/1! – x^3/3! + x^5/5! – x^7/7! + x^9/9! series, ref Matlab
        poss. cos(x) =
        1 – x^2/2! + x^4/4! series, ref Matlab  
        poss. sind=sin(x*Pi/180) =
        x*Pi/180 -(x*Pi/180)^3/3! + (x*Pi/180)^5/5! series, ref Matlab
        proc sind {aa} {set aa [* $aa $math::constants::degtorad ];return [sin $aa ]}
        check function in TCL
     ref. number format procedure
     check_answer   new area =? desired goal , desired goal reached (yes/no)
     set answers and printout with resulting values
     cos table from  Chebyshev approximation , console show; puts " $ctable  " 
     in table subroutine.

Testcases Section

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 2printed in tcl wiki format
quantity value comment, if any
2:testcase_number
45.0 :degrees
0.78539816339743507 :answers : conv. radians, used in arc functions
0.70710343676668519 :cosd function
0.99978768091494197 :tand function
1.0002123641740253 :cotd function
1.4142202512444562 :secd function
1.4142202512444562 :cscd function
0.70710678118653814 :sind function
45.000000000013131 :asind function
45.000000000013131 :acosd function
45.000000000013131:atand function
45.000000000013131:acotd function
1.0000939590259186:asecd function
45.000000000013131 :acscd function
pi = 3.1415926535897931 = ratio of circle circumference and diameter
e = 2.7182818284590451 = base for natural logarithm
radtodeg = 57.295779513100001 = Conversion from radians to degrees
degtorad = 0.017453292519943001 = Conversion from degrees to radians

Testcase 2

table 2printed in tcl wiki format
quantity value comment, if any
2:testcase_number
180.0 :degrees
0.86599999999999999 :radians
-1.0 :cosd function
-5.2969080652072186e-14 :tand functiondiff. residual
5.2969080652072186e-14 :sind function diff. residual


Testcase 3

table 3printed in tcl wiki format
quantity value comment, if any
3:testcase_number
270.0 :degrees
0.70699999999999996 :radians
-8.0119754792883374e-14 :cosd function diff. residual
undefined:tand function diff. residual
-1.0 :sind function


table 4printed in tcl wiki format
quantity value comment, if any
3:testcase_number
360.0 :degrees
0.94999999999999996 :radians
1.0 :cosd function
-1.0593816130414437e-13 :tand functiondiff. residual
-1.0593816130414437e-13 :sind function diff. residual


References:

  • Henri Padé, French mathematician, Wikipedia
  • Practical Numeric Math Functions, Pracma package,
  • R-language (GNU S), 21Nov2017, Hans w. Borchers,
  • includes acosd, acot, acotd, acsc, acscd,
  • asec, asecd, asind, atand, atan2d,
  • cosd, cot, cotd, csc, cscd, includes Pracma.pdf manual
  • Apparently, the E-console can invoke a tk/tcl library
  • and/or commands in tcl/bin to the Pragma library
  • Pade package distributed in R-language library,
  • includes Pade.pdf manual
  • Attachment "extrafuncs.tcl" to ticket No. 641143ffff
  • added by dkf on 2006-03-16 16:27:34.
  • Pade approximants for inverse trigonometric functions
  • and their applications, Shanhe Wu and Gabriel Bercu,
  • key paper on Pade trig.
  • sin
  • Maxima
  • Chebyshev approximation
  • get cos table from Chebyshev approximation,
  • TCL > console show; puts " $ctable "
  • Evaluating polynomial functions
  • a tcl script for function value listing based on a fortran expression
  • SQLite has cot?
  • Sine of argument in degrees - MATLAB sind, de.mathworks.com
  • degrees - MATLAB sin() vs sind() , Stack Overflow, stackoverflow.com
  • For integers n , sind(n*180) is exactly zero, whereas sin(n*pi)
  • Trigonometry Formulas , Math Is Fun Forum
  • Python: converting radians to degrees,Stack Overflow, stackoverflow.com
  • C mathematical functions, From Wikipedia, the free encyclopedia
  • Aircraft Trajectory Modeling and Alerting Algorithm,
  • modeling sind (fm f77) etc
  • with series, feel safe in the cockpit?
  • Computer Approximations,Hart and Cheney,
  • Ref. Chebyshev Polynomials.
  • Elementary Functions. Algorithms and Implementation},
  • Jean-Michel Muller, 2016
  • NIST, online library of digital functions, inverse series
  • Y. L. Luke (1975) Mathematical Functions and their Approximations.
  • Academic Press Inc., New York.
  • Padé Approximants,George A. Baker, Peter Graves-Morris
  • Pade approximants for inverse trigonometric functions and their applications,
  • Shanhe Wu and Gabriel Bercu
  • George A. Baker Essentials of Pade approximants
  • Academic Press 1975
  • Della Dora J. Approximation de fonctions complexe au sens
  • Hermite-Pade et Hardy, , PhD Thesis ed., 1980 in French
  • George A. Baker, P.R.Graves- Morris Encyclopedia of mathematics and its applications Section,
  • Mathematics of physics 14
  • Pade approximants ,Volume 2
  • C. Brezinski Continued fractions and Pade approximants
  • North-Holland, 1990 , English
  • Claude Brezinski (auth.) Springer Series in Computational Mathematics 12
  • History of Continued Fractions and Padé Approximants 1st ed.
  • Springer-Verlag Berlin Heidelberg, 1991,English
  • P.R.Graves- Morris Pade approximants and their applications Proc Kent
  • Academic Press Inc ,English
  • Baker G.A., et al. Collection of reviews and papers
  • on convergence of Pade approximants Kluwer, 1999 , English
  • George A. Baker Jr., John L. Gammel The Pade approximant in theoretical physics
  • Elsevier Science , 1970 , English
  • D. (ed.) Bessis Cargese lectures in physics.
  • Pade approximant methods in quantum field theory, Vol 5
  • Gordon and Breach New York. 1972,English
  • H. Cabannes, LNP0047
  • Pade Approximants Method and Its Applications to Mechanics ,1 ed.
  • Springer, 1976, English
  • E.B. Safe (Eds.) Pade and Rational Approximation. Theory and Applications
  • Academic Press 1977 English
  • Springer International Publishing 2014 , English
  • George A Baker Section, Mathematics of physics ,v. 1
  • Pade approximants, Addison-Wesley, Advanced Book Program 1981 English
  • George A Baker Section,
  • Mathematics of physics, v. 1
  • Pade approximants
  • Addison-Wesley, Advanced Book Program , 1981 , English
  • Jochen Pade Undergraduate Lecture Notes in Physics
  • Quantum Mechanics for Pedestrians 2: Applications and Extensions ,2014 ed.,
  • Claude Brezinski (auth.) International Series of Numerical Mathematics
  • Internationale Schriftenreihe zur Numerischen Mathematik ,
  • Série internationale d’Analyse numérique
  • Padé-Type Approximation and General Orthogonal Polynomials 1st ed.
  • Birkhäuser Basel, in German
  • Laurent Series and their Padé Approximations 1st ed.
  • Birkhäuser Basel, 1987, English
  • Baker,GA,Gammel,JL:ThePadéApproximantinTheoreticalPhysics.AcademicPress,NewYork(1970)
  • Baker,GA,Graves- Morris,P:PadéApproximants,2ndedn.CambridgeUniversityPress,Cambridge(1996)
  • Guo,B,Wang,R,Xu,M: Padé approximation of sine functions and its application in numerical
  • analysis. J.Inf.Comput. Sci.12(15),5545-5550(2015)
  • Bercu,G:Padé approximant related to remarkable inequalities involving
  • trigonometric functions.J.Inequal.Appl. 2016,ArticleID99(2016)
  • Bercu,G,Wu,S: Refinements of certain hyperbolic inequalities via the
  • Pade approximation method. J.NonlinearSci. Appl.9(7),5011-5020(2016)
  • An approximate analytic inversion of Kepler's equation,
  • D. Lynden-Bell, pade_sin used by astronomer to solve Kepler's equation.
  • A Fast, Vectorizable Algorithm for Producing Single-Precision Sine-Cosine Pairs
  • Marcus H. Mendenhall
  • ranged switch
  • range
  • Umut's tech-blog, Reinventing the wheel : write your own fast sine (c++ code),
  • seems fast and understandable to implement.
  • On 12/12/2017 received Umut's permission to load the
  • "Umut Tech fast sine algorithm" into TCL on the TCL/wiki
  • telescoping for $a+$b*$x+$c*$x**2+$d*$x**3 as (($d*x+$c)*$x+$b)*x+$a
  • www.boost.org, boost math, c++ library
  • search for TCL code on retained open source google code,
  • [1]
  • other keyword projects >>> label:tcl label:tcllib label:Tk
  • search on github.
  • 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


table 1list of proposed Pade_trig functions printed in tcl wiki format
designation definition inverse factors comment, if any
sind(x)Sine of argument in degrees
cosd(x)Cosine of argument in degrees
tand(x)Tangent of argument in degrees
cotd(x)Cotangent of argument in degrees
asind(x)returns the inverse sine (sin-1) of the elements of X in degrees
acosd(x)returns the inverse cosine (cosin-1) of the elements of X in degrees
atand(x)Inverse tangent in degrees
acotd(x)Inverse cotangent in degrees
secd(x)Secant of argument in degrees
cscd(x)Cosecant of argument in degrees
asecd(x)Inverse secant in degrees
acscd(x)Inverse cosecant in degrees


Note. For integers n, sind(n*180) is exactly zero in "older non-standard" Fortran library function. Some details on n*180 and pi need to be researched. Different return calculations of sin and sind were flagged in some GNU fortran trials, circa 2016. Proposed Pade_Trig functions probably need angle reduction procedure to interval of 0-(pi/4).

Small Trig Table , in TCL wiki format

Small Trig Table printed in TCL wiki format
Degrees Radians cos sin tan
0 0 1 0 0
30 π/6 sqrt(3)/2 1/2 sqrt(3)/3
45 π/4 sqrt(2)/2 sqrt(2)/2 1
60 π/3 1/2 sqrt(3)/2 sqrt(3)
90 π/2 01 undefined
120 2π/3 -1/2 sqrt(3)/2 -sqrt(3)
135 3π/4 -sqrt(2)/2 sqrt(2)/2 -1
150 5π/6 -sqrt(3)/2 1/2 -sqrt(3)/3
180 π -1 0 0
210 7π/6 -sqrt(3)/2 -1/2 sqrt(3)/3
225 5π/4 -sqrt(2)/2 -sqrt(2)/2 1
240 4π/3 -1/2 -sqrt(3)/2 sqrt(3)
270 3π/2 0 -1 undefined
300 5π/3 1/2 -sqrt(3)/2 -sqrt(3)
315 7π/4 sqrt(2)/2 -sqrt(2)/2 -1
330 11π/6 sqrt(3)/2 -1/2 -sqrt(3)/3


Appendix Code edit

appendix TCL programs and scripts

Testbed Calculator with fixed testcases and some Pade_trig subroutines

This is a testbed TCL Calculator for Pade_trig functions. Not all Pade_trig procedures here are invoked, but subroutine code can be used in homebrew scripts for comparison. Subroutines like proc pi from AMG, error code for zero/undefined division, proc errorx, and angle reduction procs may invoked or support the alternate subroutines under test below.
        # pretty print from autoindent and ased editor
        # Sind Functions calculator
        # written on Windows XP on TCL
        # working under TCL version 8.5.6 and eTCL 1.0.1
        # gold on TCL WIKI, 5nov2017
        package require Tk
        package require math::numtheory
        package require math::geometry
        package require math::constants
        namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants}
        set tcl_precision 17
        frame .frame -relief flat -bg aquamarine4
        pack .frame -side top -fill y -anchor center
        set names {{} {degrees :} }
        lappend names {answers: radians:}
        lappend names {cosd function: }
        lappend names {tand function: }
        lappend names {cotd function:}
        lappend names {secd function: }
        lappend names {cscd function: }
        lappend names {sind function:}
        foreach i {1 2 3 4 5 6 7 8} {
            label .frame.label$i -text [lindex $names $i] -anchor e
            entry .frame.entry$i -width 35 -textvariable side$i
            grid .frame.label$i .frame.entry$i -sticky ew -pady 2 -padx 1 }
        proc about {} {
            set msg "Calculator for Sind Functions
            from TCL WIKI,
            written on eTCL "
            tk_messageBox -title "About" -message $msg }
        proc ::tcl::mathfunc::precision {precision float}  {
            #  tcl:wiki:Floating-point formatting, [AM]
            set x [ format "%#.5g" $float ]
            return $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.}}
        # start sind procedures
        proc division_check {x y} {
            # ref. rossetta code for division by zero
            try {
                if {  [ / $x $y  ]  ==  Inf  } {
                    puts " strange Inf value generated " }
                if {"Inf" == "Inf" || "Inf" == "Inf"} {puts " strange Inf value generated "}
                puts "valid division: $x/$y=[expr {$x/$y}] checkit"
            } trap {ARITH DIVZERO} msg {
                puts "caught division by zero: $x/$y -> $msg"
            } trap {ARITH DOMAIN} msg {
                puts "caught bad division: $x/$y -> $msg"
            } on error msg {
                puts "caught another error: $x/$y -> $msg"
            }
        }
        # problems if $aa is pi/2 or 90 degs, if $aa is 3*pi/2 or 270 degs
        #if { [ catch {[ $aa ]   } ] == 0 } {
        #return -code error "opps tan 90/270 degs"
        # -errorinfo "undefined for tan 90/270 degs" -errorcode {ARITH DOMAIN}
        # ref. rossetta code for division by zero
        proc tangent_check {xx} {
            # ref. rossetta code for division by zero
            try {
                if { $xx  ==  Inf  } {
                    puts " strange Inf value generated " }
                if {$xx == 90. || $xx == 270.} {puts " strange tan value generated "}
                #return -code error "opps tan 90/270 degs"
                # -errorinfo "undefined for tan 90/270 degs" -errorcode {ARITH DOMAIN}
                puts "tan opps tan 90/270 degs error called"
                puts "valid tangent? : $xx=90. checkit"
            } trap {ARITH } msg {
                puts "caught bad tangent: $xx -> $msg"
            } trap {ARITH DOMAIN} msg {
                puts "caught bad tangent: $xx -> $msg"
            } on error msg {
                puts "caught another error: $xx -> $msg"
                #return -code error "opps tan 90/270 degs" -errorinfo "
                #undefined for tan 90/270 degs" -errorcode {ARITH DOMAIN}
            }
        }
        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 pi from AMG
        proc pi {} {expr acos(-1)}
        proc pade_asind_good {aa} {
            set term2 [ expr {  $aa*$aa*$aa*$aa*$aa*61.+1080.*$aa*$aa*$aa-2520.*$aa  } ] ;
            set term3 [ expr {  1500.*$aa*$aa-2520.  } ] ;
            set result  [ expr {  $term2/$term3 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_sin_testx {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  $aa-31.*$aa*$aa*$aa/294. } ] ;
            set term3 [ expr {  1.+3.*$aa*$aa/49.+11.*$aa*$aa*$aa*$aa/5880.} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc pade_acosd_check_it {aa} {
            set term2 [ expr {  12. - 5.*$aa*$aa } ] ;
            set term3 [ expr {  12. + $aa*$aa  } ] ;
            set result  [ expr {  $term2/$term3 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_cosd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc pade_tand_gtest {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  15.*$aa-$aa*$aa*$aa } ] ;
            set term3 [ expr {  15.-6.*$aa*$aa} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc pade_cottand_gtest {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  15.*$aa-$aa*$aa*$aa } ] ;
            set term3 [ expr {  15.-6.*$aa*$aa} ] ;
            set result  [ expr {  $term3/$term2 } ]}
        proc pade_cscd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term3/$term2 } ]}
        proc pade_secd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term3/$term2 } ] }
        proc pade_acscd_check {aa} {
            set term2 [ expr {  $aa*$aa*$aa*$aa*$aa*61.+1080.*$aa*$aa*$aa-2520.*$aa  } ] ;
            set term3 [ expr {  1500.*$aa*$aa-2520.  } ] ;
            set result  [ expr {  $term3/$term2 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_atand_good {aa} {
            set term2 [ expr {  $aa*$aa*$aa*55.+105.*$aa  } ] ;
            set term3 [ expr {  $aa*$aa*$aa*$aa*9.+$aa*$aa*90.+105.  } ] ;
            set result  [ expr {  $term2/$term3 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_acotd_check {aa} {
            set term2 [ expr {  $aa*$aa*$aa*55.+105.*$aa  } ] ;
            set term3 [ expr {  $aa*$aa*$aa*$aa*9.+$aa*$aa*90.+105.  } ] ;
            set result  [ expr {  $term3/$term2 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_acscd_check {aa} {
            set term2 [ expr {  $aa*$aa*$aa*$aa*$aa*61.+1080.*$aa*$aa*$aa-2520.*$aa  } ] ;
            set term3 [ expr {  1500.*$aa*$aa-2520.  } ] ;
            set result  [ expr {  $term3/$term2 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        proc pade_atand_good {aa} {
            set term2 [ expr {  $aa*$aa*$aa*55.+105.*$aa  } ] ;
            set term3 [ expr {  $aa*$aa*$aa*$aa*9.+$aa*$aa*90.+105.  } ] ;
            set result  [ expr {  $term2/$term3 } ]
            set aa [* $aa $math::constants::radtodeg ];}
        # end sind procedures
        proc calculate {     } {
            global answer2
            global side1 side2 side3 side4 side5
            global side6 side7 side8
            global testcase_number original_angle_side1
            incr testcase_number
            set side1 [* $side1 1. ]
            set side2 [* $side2 1. ]
            set side3 [* $side3 1. ]
            set side4 [* $side4 1. ]
            set side5 [* $side5 1. ]
            set side6 [* $side6 1. ]
            set side7 [* $side7 1. ]
            set side8 [* $side8 1. ]
            # testing angle reduction proc
            set original_angle_side1 $side1
            set side1 [ degree_reduction $side1 ]
            set side1x $side1
            set side2 [* $side1x  $math::constants::degtorad ]
            set side3 [ pade_cosd_g $side1x  ]
            set side4 [ pade_tand_gtest $side1x  ]
            catch { set side5 [ pade_cottand_gtest $side1x ] }
            catch { set side6 [ pade_secd_g $side1x ] }
            catch { set side7 [ pade_cscd_g $side1x ] }
            set side8 [ pade_sin_testx $side1x ]
        }
        proc fillup {aa bb cc dd ee ff gg hh} {
            .frame.entry1 insert 0 "$aa"
            .frame.entry2 insert 0 "$bb"
            .frame.entry3 insert 0 "$cc"
            .frame.entry4 insert 0 "$dd"
            .frame.entry5 insert 0 "$ee"
            .frame.entry6 insert 0 "$ff"
            .frame.entry7 insert 0 "$gg"
            .frame.entry8 insert 0 "$hh"
        }
        proc clearx {} {
            foreach i {1 2 3 4 5 6 7 8 } {
                .frame.entry$i delete 0 end } }
        proc reportx {} {
            global answer2
            global side1 side2 side3 side4 side5
            global side6 side7 side8
            global testcase_number original_angle_side1
            console show;
            puts "%|table $testcase_number|printed in| tcl wiki format|% "
            puts "&| quantity| value| comment, if any|& "
            puts "&| $testcase_number:|testcase_number | |&"
            puts "&| $original_angle_side1 :|degrees | original angle reduced for computation  |&"
            puts "&| $side1 :|degrees | entry angle after reduction   |&"
            puts "&| $side2 :|answers : conv. radians, used in arc functions | |& "
            puts "&| $side3 :|cosd function| |& "
            puts "&| $side4 :|tand function| |&"
            puts "&| $side5 :|cotd function | |&"
            puts "&| $side6 :|secd function |  |&"
            puts "&| $side7 :|cscd function |  |&"
            puts "&| $side8 :|sind function |  |&"
            puts "&|[ pade_asind_good $side2 ] :|asind function |  |&"
            puts "&| [ pade_acosd_check_it $side2 ] :|acosd function |  |&"
            puts "&|[ pade_atand_good $side2 ]:|atand function |  |&"
            puts "&|[ pade_acotd_check $side2 ]:|acotd function |  |&"
            puts "&|[ pade_secd_g $side2 ]:|asecd function |  |&"
            puts "&| [ pade_acscd_check $side2 ] :|acscd function |  |&"
            math::constants::print-constants
            puts " $math::constants::radtodeg "
            puts " $math::constants::degtorad "
            # math::geometry::print-geometry
        }
        frame .buttons -bg aquamarine4
        ::ttk::button .calculator -text "Solve" -command { set side8 0 ; calculate   }
        ::ttk::button .test2 -text "Testcase1" -command {clearx;fillup 0.0  0.0  0.1 1.0  0.0   0.0    0.00  0.0}
        ::ttk::button .test3 -text "Testcase2" -command {clearx;fillup 180.0 3.14 -1. 0.0   0.0   0.0  0.00 1.0}
        ::ttk::button .test4 -text "Testcase3" -command {clearx;fillup 360.0 6.28 1.0  0.0  0.0  -1.0  10000.00 0.001}
        ::ttk::button .clearallx -text clear -command {clearx }
        ::ttk::button .about -text about -command {about}
        ::ttk::button .cons -text report -command { reportx }
        ::ttk::button .exit -text exit -command {exit}
        pack .calculator  -in .buttons -side top -padx 10 -pady 5
        pack  .clearallx .cons .about .exit .test4 .test3 .test2   -side bottom -in .buttons
        grid .frame .buttons -sticky ns -pady {0 10}
        . configure -background aquamarine4 -highlightcolor brown -relief raised -border 30
        wm title . "Sind Functions Calculator"

Alternate subroutines under test

    proc pi {} {expr acos(-1)} # from AMG
    proc radian_reduction {aa} {
    set pi [pi]
    if { $aa > 0. } {
    while {$aa > [* 2. $pi ] } {
    set aa [- $aa [* 2. $pi ] ] }
    return $aa }
    if { $aa < [* -1. 2. $pi ]  } {
    while {$aa < [* -1. 2. $pi ] } {
    set aa [+ $aa [* 2. $pi ] ] }
    return $aa }
    return $aa }
    proc trial_degree_reduction_pi {aa} {
    if { $aa > 0. } {
    while {$aa > 180.} {
    set aa [- $aa 180.] }
    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 }
    return $aa }
    if { $aa < -180. } {
    while {$aa < -180.} {
    set aa [+ $aa 180.] }
    return $aa }
    return $aa }
    proc trial_degree_reduction_8ths {aa} {
    set counter 0
    if { $aa > 0. } {
    while {$aa > 45.} {
    incr counter
    set aa [- $aa 45.] }
    return $aa }
    if { $aa < -45. } {
    while {$aa < -45.} {
    incr counter
    set aa [+ $aa 45.] }
    return $aa }
    return $aa }
        # pade_ln (1+x) of 3/3 order used in discussion
        proc ln_1_x {x} {
        set term2 [ expr { $x + $x**2 + 0.1833333333333333*($x**3)} ] ;
        set term3 [ expr { 1 + 1.5*$x + .6*($x**2) + 0.05*($x**3)  } ] ;
        set result  [ expr {  $term2 / $term3 } ]
        return $result;}  

            proc sin_neg_flipper_check {aa} {
            if {$aa < 0 } {
            set keeper [* -1. $aa ]
            set keeper2 [  $keeper ] 
            set keeper2 [* -1. $keeper2 ] }
            return $keeper2}
       proc bhaskara_tandx {x} {
       #set x [* $x $math::constants::degtorad ];
       # -pi/2<  x < pi/2
       set pi [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 }
            proc pi {} {expr acos(-1)}
            proc para_sind {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set pi [pi]
            set result [ expr  { (16.*($pi-$aa)*$aa) / (5.*$pi*$pi-4.*($pi-$aa)*$aa) }]
            }
             puts "  para_sind 45. [ para_sind 45. ]  "
            # outout >>   para_sind 45. 0.7058823529411673 
       proc nested_taylor_sind_3ird {x} {
       set x [* $x $math::constants::degtorad ];
       set result [ expr {(((1./120.)*$x*$x*$x -(1./6.)*$x)*$x +1. )*$x } ]
       return $result }

       proc nested_taylor_sindx_9th {x} {
       set x [* $x $math::constants::degtorad ];
       #set result [ expr {(((((1./362880.)*$x*$x -(1./5040))*$x +(1./120.)*$x*$x)*$x -(1./6)*$x)*$x    +1. )*$x } ]
       set result [ expr { $x*( 1. - $x*$x*( 1./6. - $x*$x*( 1./120. - $x*$x*(1./5040.-$x*$x*(1./362880.)) ))) }]
       return $result }
       # puts " [ time {  set result [ expr { $x*( 1. - $x*$x*( 1./6. - $x*$x*( 1./120. - $x*$x*(1./5040.-$x*$x*(1./362880.)) ))) }]  } 1 ] "
       # 143 microseconds per iteration
       # Taylor sin evaluated at 2 degrees
       # nested_sind 2. 0.034899496407940836  
       # 3th 0.03489949670251291
       # 7th 0.034899496407935854
       # 9th                  0.034899496407940836 diff 9th place
       # TCL 8.6 derived sind 0.03489949670250038
       # Taylor sin evaluated at 4 degrees
       # nested_sind 45.       0.7071067829368578 , diff 8th place
       # TCL 8.6 derived sind  0.7071067811865381
       proc nested_taylor_cosd_3irdO {x} {
       set x [* $x $math::constants::degtorad ];
        set result [ expr { ((  ( ( (-1./3628800.)*$x*$x+1./40320.)*$x*$x  -1./720.)*$x*$x  +1./24.)*$x*$x  -(1./2.)*$x  )*$x +1.} ]
       return $result }
       # Taylor nested cosd evaluated at 2 degrees
       # nested_cosd 2. 0.999392537352738  
       # TCL 8.5 derived 0.9993908270190958
       proc nested_taylor_cosd_10thO {x} {
       set x [* $x $math::constants::degtorad ];
       set result [expr { 1.−$x*$x*(1./2.-$x*$x*(1./24.−$x*$x*(1./720.−$x*$x*(1./40320.-$x*$x* (1./ 3628800.))))) }]
       return $result }
       # Taylor cosd evaluated at 2 degrees
       # nested_cosd 2. 0.9993908270190958  
       # TCL 8.5 derived 0.9993908270190958   
       # numbers seem compatible
        proc nested_taylor_tand {x} {
        set x [* $x $math::constants::degtorad ];
        #set result [ expr  { $x*(1.+ $x*$x*(1./3.+$x*$x*(17./315.+$x*$x*62./2835.)))}]
        set result [ expr  { $x*(1.+ $x*$x*(1./3.)+$x*$x*(17./315.+$x*$x*(62./2835.+$x*$x*(4096.*4095.)/(42.*479001600.))))}]
        return $result}
        # needs checking
            proc taylor_cosd {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set result [ expr {  1.-$aa*$aa/2.+$aa*$aa*$aa*$aa/24.-$aa*$aa*$aa*$aa*$aa*$aa/720. } ]
            return $result  }
        proc cotdx {aa} {set aa [* $aa $math::constants::degtorad ];division_check [cos $aa] [sin $aa ] ; return [/
            [cos $aa] [sin $aa ]]}
        proc secdx {aa} {set aa [* $aa $math::constants::degtorad ];division_check [1.] [sin $aa ] ;return [/ 1.
            [sin $aa ]]}
        proc cscdx {aa} {set aa [* $aa $math::constants::degtorad ];division_check [1.] [cos $aa ] ; return [/ 1.
            [cos $aa ]]}
        proc acotd {aa} {set aa [/ [acos $aa] [asin $aa ]];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc asecd {aa} {set aa [/ 1. [asin $aa ]];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc acscd {aa} {set aa [/ 1. [acos $aa ]];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc sind {aa} {set aa [* $aa $math::constants::degtorad ];return [sin $aa ]}
        proc cosd {aa} {set aa [* $aa $math::constants::degtorad ];return [cos $aa ]}
        proc tand {aa} {tangent_check $aa ;set aa [* $aa $math::constants::degtorad ];return [tan $aa ]}
        proc cotd {aa} {set aa [* $aa $math::constants::degtorad ];return [cot $aa ]}
        proc secd {aa} {set aa [* $aa $math::constants::degtorad ];return [sec $aa ]}
        proc cscd {aa} {set aa [* $aa $math::constants::degtorad ];return [csc $aa ]}
        proc asind {aa} {set aa [asin $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc acosd {aa} {set aa [acos $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc atand {aa} {set aa [atan $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc acotd {aa} {set aa [acot $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc asecd {aa} {set aa [asec $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        proc acscd {aa} {set aa [acsc $aa ];set aa [* $aa $math::constants::radtodeg ];return $aa}
        # pretty print from autoindent and ased editor
        # small angle transform proc
        # written on Windows XP on eTCL
        # working under TCL version 8.5.6 and eTCL 1.0.1
        # gold on TCL WIKI , 10dec2017
        package require Tk
        package require math::numtheory
        package require math::geometry
        package require math::constants
        namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants}
        set tclprecision 17
        console show         
        wm title . "Console program for small angles and transform"
              proc pi {} {expr acos(-1)}
        proc pade_sin_testx {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  $aa-31.*$aa*$aa*$aa/294. } ] ;
            set term3 [ expr {  1.+3.*$aa*$aa/49.+11.*$aa*$aa*$aa*$aa/5880.} ] ;
            set result  [ expr {  $term2/$term3 } ]}
            proc pade_cosd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term2/$term3 } ]}
            proc taylor_cosd {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set result [ expr {  1.-$aa*$aa/2.+$aa*$aa*$aa*$aa/24.-$aa*$aa*$aa*$aa*$aa*$aa/720. } ]
            return $result  }
            proc sind {aa} {set aa [* $aa $math::constants::degtorad ];return [sin $aa ]}
      proc cosd {aa} {set aa [* $aa $math::constants::degtorad ];return [cos $aa ]}        
              proc small_angle_sind {aa} { return [/ [* $aa [pi] ] 180. ] }
      proc small_angle_cosd {aa} { return [- [/ [pi] 2. ] [/ [* $aa [pi] ] 180. ] ]   }
      proc small_angle_tand {aa} { return [/ [/ [* $aa [pi] ] 180. ]  [- [/ [pi] 2. ] [/ [* $aa [pi] ] 180. ] ]  ] }
     proc small_angle_cosdx {aa} {return [- 1. [*  [*  $aa  [/ [pi] 180.]]   [*  $aa  [/ [pi] 180.]] .5 ] ] }
        # alpha=x*(1./361.);sin(361*alpha)=~~ 2*sin(alpha)*cos (alpha) - sin (alpha)
        proc small_angle {aa} {        
        set alpha [* $aa [/ 1. 361. ]] 
  set result [- [* 2. [ sind [* 360. $alpha] ] [ cosd $alpha] ] [ sind [* 359. $alpha ]]]
        return $result }        
        puts " small_angle_sind  [* 1. [ small_angle 45. ]] taylor_cosd [ taylor_cosd 45.] "
        # small_angle_sind  0.7071067811865382
        # taylor_cosd 0.7071032148228549 

Range aware switch from ranged switch

Test with angle intervals of 90 degrees

        # pretty print from autoindent and ased editor
        # range switch2 calculator
        # written on Windows XP on eTCL
        # working under TCL version 8.5.6 and eTCL 1.0.1
        # gold on TCL WIKI , 2dec2017
        package require Tk
        package require math::numtheory
        package require math::geometry
        package require math::constants
        namespace path {::tcl::mathop ::tcl::mathfunc math::numtheory math::geometry math::constants}
        set tclprecision 17
        console show
        wm title . "Range Aware Switch for 360 deg and 4 Quadrants"
        proc sind {aa} {set aa [* $aa $math::constants::degtorad ];return [sin $aa ]}
        #proc pade_sin_testx {aa} {
        proc sindx {aa} {
            global angle1
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  $aa-31.*$aa*$aa*$aa/294. } ] ;
            set term3 [ expr {  1.+3.*$aa*$aa/49.+11.*$aa*$aa*$aa*$aa/5880.} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc pade_cosd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        #switch2 from Lars H:
        proc exprSwitch2 {switches} {
            set cmd ""
            foreach {expr body} $switches {lappend cmd elseif $expr then $body}
            uplevel 1 [lreplace $cmd 0 0 ::if]
        }
        
        proc demo {} {
            global angle1
            set result 1.
            set aa 0
            while {$aa < 360.} {
            set comment ""
            set angle1 $aa
            exprSwitch2 {
                {$angle1< 0}                 {set comment "less than 0 deg  [ sindx $angle1 ] compare TCL_f [ 

sind $angle1 ] "; set result [ sind $angle1 ]] }        
                {$angle1<90 && $angle1>0} {set comment "positive between 0 and 90 deg ,[ sindx $angle1 ] compare 

TCL_f [ sind $angle1 ]"; set result [ sind $angle1 ] }
                {$angle1 <180 && $angle1>90} {set comment "between 90 and 180 deg, [ sindx [- 180. $angle1  ] ] 

compare TCL_f  [ sind $angle1 ]"; set result [ sind $angle1 ] }
                {$angle1 <270 && $angle1>90} {set comment "between 180 and 270 deg,[* -1. [ sindx [- $angle1 

180.] ] ] compare TCL_f [ sind $angle1 ]"; set result [ sind $angle1] }
                {$angle1 <360 && $angle1>270} {set comment "between 270 and 360 deg, [* -1. [ sindx [- $angle1 

270. -90.] ] ] compare TCL_f [ sind $angle1 ]"; set result [ sind $angle1] }
                {$angle1>360}                 {set comment "greater than 360 deg, [ sindx $angle1 ] compare 

TCL_f [ sind $angle1 ] "; set result [ sind $angle1] }
            }
                incr aa 5
                puts "$angle1 is $comment"}
                return  $result}
                puts " [ demo  ] "
                puts "[ sindx 45 ]"
                puts "[ sindx 45. ]"

sample output
5 is positive between 0 and 90 [email protected],0.08715574274765489 compare TCL_f 0.08715574274765671
10 is positive between 0 and 90 [email protected],0.17364817766599888 compare TCL_f 0.17364817766692744
35 is positive between 0 and 90 [email protected],0.5735763655797433 compare TCL_f 0.5735764363510376
40 is positive between 0 and 90 [email protected],0.6427873769178369 compare TCL_f 0.6427876096865303
45 is positive between 0 and 90 [email protected],0.7071061177657524 compare TCL_f 0.7071067811865381
50 is positive between 0 and 90 [email protected],0.766042754816006 compare TCL_f 0.7660444431189686
150 is between 90 and 180 deg, 0.4815886300755488 compare TCL_f  0.5000000000000384
# loses useful accuracy beyond pi/2 here, so "fold " sin calculations onto 1st interval ( 0... pi/2)
340 is between 270 and 360 deg, -2.940152165863797 compare TCL_f -0.3420201433257629
345 is between 270 and 360 deg, -2.9931926693661937 compare TCL_f -0.2588190451026194
350 is between 270 and 360 deg, -3.0438074377978768 compare TCL_f -0.17364817766703186
# alternative is to " fold " sin calculations onto some sin and cos functions onto 1st interval ( 0... pi/2)
# some alternative homebrews use the cos function included on the console program script
# still getting unacceptable errors beyond 45 deg or pi/4
340 is between 270 and 360 deg, -0.3119297601688663 compare TCL_f -0.3420201433257629
345 is between 270 and 360 deg, -0.22093842832380617 compare TCL_f -0.2588190451026194
350 is between 270 and 360 deg, -0.12641192920432537 compare TCL_f -0.17364817766703186
355 is between 270 and 360 deg, -0.028781653705219044 compare TCL_f -0.08715574274776272
#  here, second pi/4 (45 deg) interval folded into pade_cos onto 1st interval ( 0... pi/2)
# agreement with TCL derived sin f to about 6 places (with pi/4 folding & (3/4) order Pade f.)
45 is positive between 0 and 90 deg ,0.7071034367666852 compare TCL_f 0.7071067811865381
50 is positive between 0 and 90 deg ,0.7660431199952724 compare TCL_f 0.7660444431189686
80 is positive between 0 and 90 deg ,0.9848077529909282 compare TCL_f 0.9848077530122039
85 is positive between 0 and 90 deg ,0.9961946980916621 compare TCL_f 0.9961946980917433

"Umut Tech fast sine algorithm" into TCL on the TCL/wiki

Test with angle intervals of 10 degrees

        # pretty print from autoindent and ased editor
        # Umut Tech fast sine algorithm" into TCL
        # written on Windows XP on eTCL
        # working under TCL version 8.5.6 and eTCL 1.0.1
        # gold on TCL WIKI , 2dec2017
        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
        console show
        proc sind {aa} {set aa [* $aa $math::constants::degtorad ];return [sin $aa ]}
        proc sindx {aa} {
            global angle1
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  $aa-31.*$aa*$aa*$aa/294. } ] ;
            set term3 [ expr {  1.+3.*$aa*$aa/49.+11.*$aa*$aa*$aa*$aa/5880.} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc pade_cosd_g {aa} {
            set aa [* $aa $math::constants::degtorad ];
            set term2 [ expr {  1080.-480.*$aa*$aa+$aa*$aa*$aa*$aa*17. } ] ;
            set term3 [ expr {  1080.+60.*$aa*$aa+2.*$aa*$aa*$aa*$aa} ] ;
            set result  [ expr {  $term2/$term3 } ]}
        proc degree_reduction {aa} {
            set aa [abs $aa ]
            if { $aa < 360. } {
                while {$aa > 10.} {
                    set aa [- $aa 10.] }
                return $aa }
                return $aa }
       proc umut_fast_sind {aa} {
            set fast_sine $aa
            set pi 3.141592653589793238462643383279502884197169399375105820974
            set sine_table {1. 2. 3. 4. 5.}
            set cos_table {1. 2. 3. 4. 5.} 
            set sine_table { 
                0.0
                0.17364817766693034885171662676931
                0.34202014332566873304409961468226
                0.5
                0.64278760968653932632264340990726
                0.76604444311897803520239265055542
                0.86602540378443864676372317075294
                0.93969262078590838405410927732473
                0.98480775301220805936674302458952
                1.0
                }           
            set cos_table_original { 
                1.0
                0.99984769515639123915701155881391
                0.99939082701909573000624344004393
                0.99862953475457387378449205843944
                0.99756405025982424761316268064426
                0.99619469809174553229501040247389
                0.99452189536827333692269194498057
                0.99254615164132203498006158933058
                0.99026806874157031508377486734485
                0.98768834059513772619004024769344  }
            set cos_table { 
                1.0 
                0.98480775301220805936674302458952
                0.93969262078590838405410927732473 
                0.86602540378443864676372317075294
                0.76604444311897803520239265055542
                0.64278760968653932632264340990726
                0.5
                0.34202014332566873304409961468226
                0.17364817766693034885171662676931
                0.0 } 
            set aa [degree_reduction $aa ]
            set fast_sine $aa
            # sin(71.654) = sin(70 + 1.654) = sin(70) cos(1.654) + sin(1.654) cos (70)
            set fast_sine [+ [* [ lindex $sine_table 7  ] [ pade_cosd_g $aa]] [* [ sindx $aa ] [lindex $cos_table 7 ]]]
            #set fast_sine [+ [* 1. [ pade_cosd_g $aa]] [* [ sindx $aa ] 2. ]]]
            #puts " [ list $costable ] [ list $sintable ]"
            puts " aa $aa sine_table  $sine_table cos_table $cos_table "
            puts " sine element 8 r [ lindex $sine_table 7 ] "
            puts " cosine element 8 r [ lindex $cos_table 7 ] "  
            return $fast_sine }
            puts " umut_fast_sind  [ umut_fast_sind 71.654 ] tcl sine derived [ sind 71.654 ]"
            puts "  pade sin, ac <<< pi/2 r [ sindx 71.654 ]"   
            #puts " umut_fast_sind timing [ time { umut_fast_sind 71.654 } 2 ] "

gold This page is copyrighted under the TCL/TK license terms, this license.

Comments Section edit

Please place any comments here, Thanks.