Tcl Library Source Code

Check-in [883969dee1]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add simple procedures to return the Euler and Bernoulli numbers. The numbers themselves are stored in two look-up lists.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 883969dee10a3bfe2370f3ef0dd5f311fb07ba2a435cd97509d7df77d8c0e741
User & Date: arjenmarkus 2020-02-13 19:35:55
Context
2020-02-17
14:41
Closing fork Leaf check-in: b9b9ff9c74 user: hypnotoad tags: trunk
2020-02-13
19:35
Add simple procedures to return the Euler and Bernoulli numbers. The numbers themselves are stored in two look-up lists. check-in: 883969dee1 user: arjenmarkus tags: trunk
2019-12-07
19:55
Tkt [0e16703e411f4c9f] Updated current release on home page check-in: b0d89885fb user: aku tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to modules/math/ChangeLog.







1
2
3
4
5
6
7





2019-11-08  Arjen Markus <[email protected]>
	* statistics.tcl: Add a new type of error message, version to 1.5.0
	* pdf_stat.tcl: Add procedures for Laplace, Kumaraswamy and negative binomial distributions, also tests for homoscedasticity
	* statistics.tcl: Corresponding tests
	* statistics.man: Documentation of the new procedures
	* pkgIndex.tcl: Bumped version of statistics package to 1.5.0

>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
2020-02-13  Arjen Markus <[email protected]>
	* special.tcl: Add procs for returning Euler and Bernoulli number, version to 0.5.0
	* special.test: Add tests for these new procs
	* special.man: Add documentation for these new procs
	* pkgIndex.tcl: Bumped version of special functions package to 0.5.0

2019-11-08  Arjen Markus <[email protected]>
	* statistics.tcl: Add a new type of error message, version to 1.5.0
	* pdf_stat.tcl: Add procedures for Laplace, Kumaraswamy and negative binomial distributions, also tests for homoscedasticity
	* statistics.tcl: Corresponding tests
	* statistics.man: Documentation of the new procedures
	* pkgIndex.tcl: Bumped version of statistics package to 1.5.0

Changes to modules/math/TODO.

1
2















3
4
5
6
7
8
9
This file records outstanding actions for the math module
















dd. 4 november 2019
- Extend the set of test cases for linear interpolation with corner cases
  - these should fail with a clear error message.

dd. 4 september 2018
- Implement a "typical profile" for timeseries and determining residuals
  (Plus perhaps a notion of outliers)

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
This file records outstanding actions for the math module

dd. 6 february 2020
- Implement accelerations for infinite sums:
  - Method described on Wolfram
  - Method for alternating series from the book

dd. 9 february
http://numbers.computation.free.fr/Constants/Miscellaneous/seriesacceleration.html
- provides an overview
https://arxiv.org/pdf/math/0202009.pdf
- also interesting
https://www.cis.twcu.ac.jp/~osada/thesis_osada.pdf
- thesis
https://kconrad.math.uconn.edu/blurbs/analysis/series_acceleration.pdf
- yet another article

dd. 4 november 2019
- Extend the set of test cases for linear interpolation with corner cases
  - these should fail with a clear error message.

dd. 4 september 2018
- Implement a "typical profile" for timeseries and determining residuals
  (Plus perhaps a notion of outliers)

Changes to modules/math/pkgIndex.tcl.

26
27
28
29
30
31
32
33
34
35
36
37
package ifneeded math::calculus::symdiff 1.0.1 [list source [file join $dir symdiff.tcl]]
package ifneeded math::bigfloat          2.0.2 [list source [file join $dir bigfloat2.tcl]]
package ifneeded math::numtheory         1.1.1 [list source [file join $dir numtheory.tcl]]
package ifneeded math::decimal           1.0.3 [list source [file join $dir decimal.tcl]]
package ifneeded math::geometry          1.3.1 [list source [file join $dir geometry.tcl]]
package ifneeded math::trig              1.0   [list source [file join $dir trig.tcl]]
package ifneeded math::quasirandom       1.0   [list source [file join $dir quasirandom.tcl]]
package ifneeded math::special           0.4.0 [list source [file join $dir special.tcl]]

if {![package vsatisfies [package require Tcl] 8.6]} {return}
package ifneeded math::exact             1.0.1 [list source [file join $dir exact.tcl]]
package ifneeded math::PCA               1.0   [list source [file join $dir pca.tcl]]






|




26
27
28
29
30
31
32
33
34
35
36
37
package ifneeded math::calculus::symdiff 1.0.1 [list source [file join $dir symdiff.tcl]]
package ifneeded math::bigfloat          2.0.2 [list source [file join $dir bigfloat2.tcl]]
package ifneeded math::numtheory         1.1.1 [list source [file join $dir numtheory.tcl]]
package ifneeded math::decimal           1.0.3 [list source [file join $dir decimal.tcl]]
package ifneeded math::geometry          1.3.1 [list source [file join $dir geometry.tcl]]
package ifneeded math::trig              1.0   [list source [file join $dir trig.tcl]]
package ifneeded math::quasirandom       1.0   [list source [file join $dir quasirandom.tcl]]
package ifneeded math::special           0.5.0 [list source [file join $dir special.tcl]]

if {![package vsatisfies [package require Tcl] 8.6]} {return}
package ifneeded math::exact             1.0.1 [list source [file join $dir exact.tcl]]
package ifneeded math::PCA               1.0   [list source [file join $dir pca.tcl]]

Changes to modules/math/special.man.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
132
133
134
135
136
137
138






















139
140
141
142
143
144
145
[keywords math]
[keywords {special functions}]
[copyright {2004 Arjen Markus <[email protected]>}]
[moddesc   {Tcl Math Library}]
[titledesc {Special mathematical functions}]
[category  Mathematics]
[require Tcl [opt 8.5]]
[require math::special [opt 0.4]]

[description]
[para]
This package implements several so-called special functions, like
the Gamma function, the Bessel functions and such.

[para]
................................................................................
[list_end]

[section "PROCEDURES"]

The package defines the following public procedures:

[list_begin definitions]























[call [cmd ::math::special::Beta] [arg x] [arg y]]

Compute the Beta function for arguments "x" and "y"

[list_begin arguments]
[arg_def float x] First argument for the Beta function






|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
[keywords math]
[keywords {special functions}]
[copyright {2004 Arjen Markus <[email protected]>}]
[moddesc   {Tcl Math Library}]
[titledesc {Special mathematical functions}]
[category  Mathematics]
[require Tcl [opt 8.5]]
[require math::special [opt 0.5]]

[description]
[para]
This package implements several so-called special functions, like
the Gamma function, the Bessel functions and such.

[para]
................................................................................
[list_end]

[section "PROCEDURES"]

The package defines the following public procedures:

[list_begin definitions]

[call [cmd ::math::special::eulerNumber] [arg index]]

Return the index'th Euler number (note: these are integer values). As the
size of these numbers grows very fast, only a limited number are available.

[list_begin arguments]
[arg_def int index] Index of the number to be returned (should be between 0 and 54)
[list_end]

[para]

[call [cmd ::math::special::bernoulliNumber] [arg index]]

Return the index'th Bernoulli number. As the size of the numbers grows very fast,
only a limited number are available.

[list_begin arguments]
[arg_def int index] Index of the number to be returned (should be between 0 and 52)
[list_end]

[para]

[call [cmd ::math::special::Beta] [arg x] [arg y]]

Compute the Beta function for arguments "x" and "y"

[list_begin arguments]
[arg_def float x] First argument for the Beta function

Changes to modules/math/special.tcl.

32
33
34
35
36
37
38

39
40
41
42
43
44
45
...
417
418
419
420
421
422
423






























424
425
426
427
428
429
430
431
432
       namespace import ::math::ln_Gamma
    }

    #
    # Export the various functions
    #
    namespace export Beta ln_Gamma Gamma erf erfc fresnel_C fresnel_S sinc invnorm

}

# Gamma --
#    The Gamma function - synonym for "factorial"
#
proc ::math::special::Gamma {x} {
    if { [catch { expr {exp( [ln_Gamma $x] )} } result] } {
................................................................................

        set newx [expr {$x + $n}]

        return [expr {[digamma $newx] - $correction}]
    }
}
































# Bessel functions and elliptic integrals --
#
source [file join [file dirname [info script]] "bessel.tcl"]
source [file join [file dirname [info script]] "classic_polyns.tcl"]
source [file join [file dirname [info script]] "elliptic.tcl"]
source [file join [file dirname [info script]] "exponential.tcl"]

package provide math::special 0.4.0






>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
       namespace import ::math::ln_Gamma
    }

    #
    # Export the various functions
    #
    namespace export Beta ln_Gamma Gamma erf erfc fresnel_C fresnel_S sinc invnorm
    namespace export incBeta regIncBeta digamma eulerNumber bernoulliNumber
}

# Gamma --
#    The Gamma function - synonym for "factorial"
#
proc ::math::special::Gamma {x} {
    if { [catch { expr {exp( [ln_Gamma $x] )} } result] } {
................................................................................

        set newx [expr {$x + $n}]

        return [expr {[digamma $newx] - $correction}]
    }
}

# eulerNumber and bernoulliNumber --
#     Return the nth Euler number or Bernoulli number
#
# Arguments:
#     index           The index of the number to be returned
#
# Note:
#     If the index is outside the range, then an error is raised:
#     For Euler numbers: index should be between 0 and 54
#     For Bernoulli numbers: index should be between 0 and 52
#     - even though for odd indices the numbers are mostly zero
#     and could be returned as such
#
# Note:
#     The tables were found in Nelson H.F. Beebe - The Mathematical Function Computation Handbook
#
proc ::math::special::eulerNumber {index} {
    if { $index < 0 || $index > 54 } {
        return -code error "Index ($index) out of range - should be between 0 and 54"
    } else {
        return [lindex {1 0 -1 0 5 0 -61 0 1385 0 -50521 0 2702765 0 -199360981 0 19391512145 0 -2404879675441 0 370371188237525 0 -69348874393137901 0 15514534163557086905 0 -4087072509293123892361 0 1252259641403629865468285 0 -441543893249023104553682821 0 177519391579539289436664789665 0 -80723299235887898062168247453281 0 41222060339517702122347079671259045 0 -23489580527043108252017828576198947741 0 14851150718114980017877156781405826684425 0 -10364622733519612119397957304745185976310201 0 7947579422597592703608040510088070619519273805 0 -6667537516685544977435028474773748197524107684661 0 6096278645568542158691685742876843153976539044435185 0 -6053285248188621896314383785111649088103498225146815121 0 6506162486684608847715870634080822983483644236765385576565 0 -7546659939008739098061432565889736744212240024711699858645581} $index]
    }
}
proc ::math::special::bernoulliNumber {index} {
    if { $index < 0 || $index > 52 } {
        return -code error "Index ($index) out of range - should be between 0 and 52"
    } else {
        return [lindex {1.0 -0.5 0.16666666666666666 0.0 -0.03333333333333333 0.0 0.023809523809523808 0.0 -0.03333333333333333 0.0 0.07575757575757576 0.0 -0.2531135531135531 0.0 1.1666666666666667 0.0 -7.092156862745098 0.0 54.971177944862156 0.0 -529.1242424242424 0.0 6192.123188405797 0.0 -86580.25311355312 0.0 1425517.1666666667 0.0 -27298231.067816094 0.0 601580873.9006424 0.0 -15116315767.092157 0.0 429614643061.1667 0.0 -13711655205088.334 0.0 488332318973593.2 0.0 -19296579341940068.0 0.0 8.416930475736827e+17 0.0 -4.0338071854059454e+19 0.0 2.1150748638081993e+21 0.0 -1.2086626522296526e+23 0.0 7.500866746076964e+24 0.0 -5.038778101481068e+26} $index]
    }
}

# Bessel functions and elliptic integrals --
#
source [file join [file dirname [info script]] "bessel.tcl"]
source [file join [file dirname [info script]] "classic_polyns.tcl"]
source [file join [file dirname [info script]] "elliptic.tcl"]
source [file join [file dirname [info script]] "exponential.tcl"]

package provide math::special 0.5.0

Changes to modules/math/special.test.

202
203
204
205
206
207
208





























209
210
   foreach x {0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0} {
      lappend result [::math::special::regIncBeta $a $b $x]
   }
   set result
} -result {0 0.0146427741 0.0572695646 0.125736691 0.217579513 0.329891773 0.459123651 0.600707642 0.748250184 0.891242370 1}































# End of test cases
testsuiteCleanup






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
   foreach x {0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0} {
      lappend result [::math::special::regIncBeta $a $b $x]
   }
   set result
} -result {0 0.0146427741 0.0572695646 0.125736691 0.217579513 0.329891773 0.459123651 0.600707642 0.748250184 0.891242370 1}


#
# Euler and Bernoulli numbers - as they come from tables, merely check that the procedures work
#
test "eulerBernoulli-1.0" "Euler number within range" -body {
   set result {}
   foreach index {0 1 2 3 4} {
      lappend result [::math::special::eulerNumber $index]
   }
   set result
} -result {1 0 -1 0 5}

test "eulerBernoulli-1.1" "Euler number out of range" -body {
   ::math::special::eulerNumber -10
   return {}
} -returnCodes {error} -result {Index (-10) out of range - should be between 0 and 54}

test "eulerBernoulli-2.0" "Bernoulli number within range" -match numbers-accurate -body {
   set result {}
   foreach index {0 1 2 3 4} {
      # Multiply by 30 to get integer values
      lappend result [expr { 30.0 * [::math::special::bernoulliNumber $index] }]
   }
   set result
} -result {30.0 -15.0 5.0 0.0 -1.0}

test "eulerBernoulli-1.0" "Bernoulli number out of range" -body {
   ::math::special::bernoulliNumber -10
} -returnCodes {error} -result {Index (-10) out of range - should be between 0 and 52}

# End of test cases
testsuiteCleanup