Tcl Library Source Code

Check-in [c2db185801]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Add two tests for the quasirandom packages; describe and test the estimates for the number of primes in an interval
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA3-256:c2db185801de1e1205f68240d4dff30b31d7ba65da23b0b7ab421e7f618a5a15
User & Date: arjenmarkus 2019-05-07 19:05:16
Context
2019-05-07
19:05
Add two tests for the quasirandom packages; describe and test the estimates for the number of primes in an interval Leaf check-in: c2db185801 user: arjenmarkus tags: trunk
01:21
Integrated the doc overhaul work into the trunk. This makes the various guides official. check-in: 6612c2b8a8 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-04-23  Arjen Markus <[email protected]>
	* quasirandom.tcl: New package - generate quasi-random numbers (for instance for estimating multidimensional integrals)
	* quasirandom.test: Tests for the new package
	* quasirandom.man: Documentation for the new package
	* pkgIndex.tcl: Add the new package

2019-04-18  Arjen Markus <[email protected]>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2019-05-07  Arjen Markus <[email protected]>
	* quasirandom.test: Add tests to deal with procedures in a different namespace
	* quasirandom.tcl: Deal with procedures in a different namespace

2019-04-24  Arjen Markus <[email protected]>
	* quasirandom.test: Add support code
	* numtheory.tcl: Add estimation of the number of primes between two limits
	* numtheory.test: Add tests regarding the estimated number of primes

2019-04-23  Arjen Markus <[email protected]>
	* quasirandom.tcl: New package - generate quasi-random numbers (for instance for estimating multidimensional integrals)
	* quasirandom.test: Tests for the new package
	* quasirandom.man: Documentation for the new package
	* pkgIndex.tcl: Add the new package

2019-04-18  Arjen Markus <[email protected]>

Changes to modules/math/numtheory.man.

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198








199
200
201
202
203
204
205
[list_end]

[call [cmd math::numtheory::numberPrimesGauss] [arg N]]
Estimate the number of primes according the formula by Gauss.

[list_begin arguments]
[arg_def integer N in]
Number in question
[list_end]

[call [cmd math::numtheory::numberPrimesLegendre] [arg N]]
Estimate the number of primes according the formula by Legendre.

[list_begin arguments]
[arg_def integer N in]
Number in question
[list_end]

[call [cmd math::numtheory::numberPrimesLegendreModified] [arg N]]
Estimate the number of primes according the modified formula by Legendre.

[list_begin arguments]
[arg_def integer N in]
Number in question








[list_end]

[list_end]

[vset CATEGORY {math :: numtheory}]
[include ../common-text/feedback.inc]
[manpage_end]






|







|







|
>
>
>
>
>
>
>
>







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
[list_end]

[call [cmd math::numtheory::numberPrimesGauss] [arg N]]
Estimate the number of primes according the formula by Gauss.

[list_begin arguments]
[arg_def integer N in]
Number in question, should be larger than 0
[list_end]

[call [cmd math::numtheory::numberPrimesLegendre] [arg N]]
Estimate the number of primes according the formula by Legendre.

[list_begin arguments]
[arg_def integer N in]
Number in question, should be larger than 0
[list_end]

[call [cmd math::numtheory::numberPrimesLegendreModified] [arg N]]
Estimate the number of primes according the modified formula by Legendre.

[list_begin arguments]
[arg_def integer N in]
Number in question, should be larger than 0
[list_end]

[call [cmd math::numtheory::differenceNumberPrimesLegendreModified] [arg lower] [arg upper]]
Estimate the number of primes between tow limits according the modified formula by Legendre.

[list_begin arguments]
[arg_def integer lower in] Lower limit for the primes, should be larger than 0
[arg_def integer upper in] Upper limit for the primes, should be larger than 0
[list_end]

[list_end]

[vset CATEGORY {math :: numtheory}]
[include ../common-text/feedback.inc]
[manpage_end]

Changes to modules/math/numtheory.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
20
21
22
23
24
25
26






27
28
29
30
31
32
33
...
203
204
205
206
207
208
209





















210
211
212
213
## 
## This is the file `numtheory.test',
## generated with the SAK utility
## (sak docstrip/regen).
## 
## The original source files were:
## 
## numtheory.dtx  (with options: `test test_common')
## 
## In other words:
## **************************************
## * This Source is not the True Source *
## **************************************
## the true source is the file from which this one was generated.
##
source [file join\
................................................................................
testsNeedTcl     8.5
testsNeedTcltest 2.1

testing {
    useLocal numtheory.tcl math::numtheory
}







test prime_trialdivision-1 "Trial division of 1" -body {
   ::math::numtheory::prime_trialdivision 1
} -returnCodes 2 -result 0
test prime_trialdivision-2 "Trial division of 2" -body {
   ::math::numtheory::prime_trialdivision 2
} -returnCodes 2 -result 1
test prime_trialdivision-3 "Trial division of 6" -body {
................................................................................
   ::math::numtheory::isprime 118670087467 -randommr 500
} -result on -cleanup {
   namespace eval ::math::numtheory {
      rename Miller--Rabin ""
      rename _orig_Miller--Rabin Miller--Rabin
   }
}





















testsuiteCleanup
## 
## 
## End of file `numtheory.test'.
|



|

|

|







 







>
>
>
>
>
>







 







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

|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
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
240
##
## This is the file `numtheory.test',
## generated with the SAK utility
## (sak docstrip/regen).
##
## The original source files were:
##
## numtheory.dtx  (with options: `test test_common')
##
## In other words:
## **************************************
## * This Source is not the True Source *
## **************************************
## the true source is the file from which this one was generated.
##
source [file join\
................................................................................
testsNeedTcl     8.5
testsNeedTcltest 2.1

testing {
    useLocal numtheory.tcl math::numtheory
}

proc compareRounded {expected actual} {
    return [expr {int($expected-$actual) == 0} ]
}

::tcltest::customMatch rounded compareRounded

test prime_trialdivision-1 "Trial division of 1" -body {
   ::math::numtheory::prime_trialdivision 1
} -returnCodes 2 -result 0
test prime_trialdivision-2 "Trial division of 2" -body {
   ::math::numtheory::prime_trialdivision 2
} -returnCodes 2 -result 1
test prime_trialdivision-3 "Trial division of 6" -body {
................................................................................
   ::math::numtheory::isprime 118670087467 -randommr 500
} -result on -cleanup {
   namespace eval ::math::numtheory {
      rename Miller--Rabin ""
      rename _orig_Miller--Rabin Miller--Rabin
   }
}

test numberPrimes-1.0 "Number of primes below 100" -match rounded -body {
   set result [::math::numtheory::numberPrimesLegendre 100]
} -result 28

test numberPrimes-1.1 "Number of primes below 100 (modified)" -match rounded -body {
   set result [::math::numtheory::numberPrimesLegendreModified 100]
} -result 28

test numberPrimes-1.2 "Number of primes below 0 (modified)" -body {
   set result [::math::numtheory::numberPrimesLegendreModified 0]
} -result "The limit must be larger than 1" -returnCodes 1

test numberPrimes-1.3 "Number of primes between 100 and 200" -match rounded -body {
   set result [::math::numtheory::differenceNumberPrimesLegendreModified 100 200]
} -result 19

test numberPrimes-1.4 "Number of primes between 100 and 0 - error expected" -body {
   set result [::math::numtheory::differenceNumberPrimesLegendreModified 100 0]
} -result "The upper limit must be larger than 1" -returnCodes 1

testsuiteCleanup
##
##
## End of file `numtheory.test'.

Changes to modules/math/primes.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
...
461
462
463
464
465
466
467



























468
469
470
## 
## This is the file `primes.tcl',
## generated with the SAK utility
## (sak docstrip/regen).
## 
## The original source files were:
## 
## numtheory.dtx  (with options: `pkg_primes pkg_common')
## 
## In other words:
## **************************************
## * This Source is not the True Source *
## **************************************
## the true source is the file from which this one was generated.
##
# Copyright (c) 2010 by Lars Hellstrom.  All rights reserved.
................................................................................
namespace eval ::math::numtheory {
    variable primes {2 3 5 7 11 13 17}
    variable nextPrimeCandidate 19
    variable nextPrimeIncrement  1 ;# Examine numbers 6n+1 and 6n+5

    namespace export firstNprimes primesLowerThan primeFactors uniquePrimeFactors factors \
                     totient moebius legendre jacobi gcd lcm \
                     numberPrimesGauss numberPrimesLegendre numberPrimesLegendreModified

}

# ComputeNextPrime --
#     Determine the next prime
#
# Arguments:
#     None
................................................................................
#
proc ::math::numtheory::numberPrimesLegendreModified {limit} {
    if { $limit <= 1 } {
        return -code error "The limit must be larger than 1"
    }
    expr {$limit / (log($limit) - 1.08366)}
}



























## 
## 
## End of file `primes.tcl'.
|



|

|

|







 







|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
##
## This is the file `primes.tcl',
## generated with the SAK utility
## (sak docstrip/regen).
##
## The original source files were:
##
## numtheory.dtx  (with options: `pkg_primes pkg_common')
##
## In other words:
## **************************************
## * This Source is not the True Source *
## **************************************
## the true source is the file from which this one was generated.
##
# Copyright (c) 2010 by Lars Hellstrom.  All rights reserved.
................................................................................
namespace eval ::math::numtheory {
    variable primes {2 3 5 7 11 13 17}
    variable nextPrimeCandidate 19
    variable nextPrimeIncrement  1 ;# Examine numbers 6n+1 and 6n+5

    namespace export firstNprimes primesLowerThan primeFactors uniquePrimeFactors factors \
                     totient moebius legendre jacobi gcd lcm \
                     numberPrimesGauss numberPrimesLegendre numberPrimesLegendreModified \
                     differenceNumberPrimesLegendreModified
}

# ComputeNextPrime --
#     Determine the next prime
#
# Arguments:
#     None
................................................................................
#
proc ::math::numtheory::numberPrimesLegendreModified {limit} {
    if { $limit <= 1 } {
        return -code error "The limit must be larger than 1"
    }
    expr {$limit / (log($limit) - 1.08366)}
}

# differenceNumberPrimesLegendreModified --
#     Return the approximate difference number of primes
#     between a lower and higher limit as given values
#     for approximate number of primes based on the
#     modified formula by Legendre
#
# Arguments:
#     limit1     The lower limit for the interval, largest prime to be included in the l.limit
#     limit2     The upper limit for the interval, largest prime to be included in the u.mlimit
#
# Returns:
#     Approximate difference number of primes
#
proc ::math::numtheory::differenceNumberPrimesLegendreModified {limit1 limit2} {
    if { $limit1 <= 1 } {
        return -code error "The lower limit must be larger than 1"
    }
    if { $limit2 <= 1 } {
        return -code error "The upper limit must be larger than 1"
    }

     set aa [::math::numtheory::numberPrimesLegendreModified [expr ($limit1)]]
     set bb [::math::numtheory::numberPrimesLegendreModified [expr ($limit2)]]
     expr {abs($bb-$aa)}
}

##
##
## End of file `primes.tcl'.

Changes to modules/math/quasirandom.tcl.

310
311
312
313
314
315
316


317
318
319
320
321
322
323
...
375
376
377
378
379
380
381


382
383
384
385
386
387
388
        my variable coord_factors
        my variable evaluations
        my variable use_radius
        my variable effective_dim

        set evals $evaluations



        foreach {key value} $args {
            switch -- $key {
            "-evaluations" {
                 if { ![string is integer -strict $value] || $value <= 0 } {
                     return -code error "The value for the option $key should be a positive integer value"
                 }

................................................................................
    #     -error value        - estimate of the error
    #     -rawvalues list     - list of raw values obtained for the integral
    #
    method integral-detailed {func minmax args} {
        my variable evaluations

        set evals $evaluations



        foreach {key value} $args {
            switch -- $key {
            "-evaluations" {
                 if { ![string is integer -strict $value] || $value <= 0 } {
                     return -code error "The value for the option $key should be a positive integer value"
                 }






>
>







 







>
>







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
        my variable coord_factors
        my variable evaluations
        my variable use_radius
        my variable effective_dim

        set evals $evaluations

        set func [uplevel 1 [list namespace which -command $func]]

        foreach {key value} $args {
            switch -- $key {
            "-evaluations" {
                 if { ![string is integer -strict $value] || $value <= 0 } {
                     return -code error "The value for the option $key should be a positive integer value"
                 }

................................................................................
    #     -error value        - estimate of the error
    #     -rawvalues list     - list of raw values obtained for the integral
    #
    method integral-detailed {func minmax args} {
        my variable evaluations

        set evals $evaluations

        set func [uplevel 1 [list namespace which -command $func]]

        foreach {key value} $args {
            switch -- $key {
            "-evaluations" {
                 if { ![string is integer -strict $value] || $value <= 0 } {
                     return -code error "The value for the option $key should be a positive integer value"
                 }

Changes to modules/math/quasirandom.test.

358
359
360
361
362
363
364







































365
366
367
368
369
370
371
    set result [simple integral-detailed fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}}]

    set rawvalues [dict get $result -rawvalues]

} -result {0.0022115062627913935 0.009840104253511376 0.014937934937801888 0.007838969739655276} -cleanup {simple destroy}









































# TODO:
# - func in different namespace
# - implement detailed integration and test the details
# - implement minimization

#






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







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    set result [simple integral-detailed fxyz4 {{0.0 1.0} {0.0 1.0} {0.0 1.0}}]

    set rawvalues [dict get $result -rawvalues]

} -result {0.0022115062627913935 0.009840104253511376 0.014937934937801888 0.007838969739655276} -cleanup {simple destroy}


#
# Test integration procedures in a different namespace
#
test "Quasirandom-6.1" "Integrate ::func::func" -match tolerant -body {
    namespace eval ::func {

        proc func {xy} {
            lassign $xy x y
            expr {$x**2+$y**2}
        }

        ::math::quasirandom::qrpoints create simple 2

        set ::result [simple integral func {{0.0 1.0} {0.0 1.0}}]
    }

    return $result

} -result {0.67353777} -cleanup {::func::simple destroy}


test "Quasirandom-6.2" "Integrate (details) ::func::func" -match tolerant -body {
    namespace eval ::func {

        proc func {xy} {
            lassign $xy x y
            expr {$x**2+$y**2}
        }

        ::math::quasirandom::qrpoints create simple 2

        set ::result [simple integral-detailed func {{0.0 1.0} {0.0 1.0}}]
    }

    return [dict get $result -estimate]

} -result {0.67353777} -cleanup {::func::simple destroy}


# TODO:
# - func in different namespace
# - implement detailed integration and test the details
# - implement minimization

#