From e707583709b97584927d5e835db1b346908c51e1 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Thu, 6 Oct 2016 22:42:41 +0200 Subject: remove Python material from R branch --- Python/SyncRNG.py | 48 ------------------------------------------------ setup.py | 19 ------------------- 2 files changed, 67 deletions(-) delete mode 100644 Python/SyncRNG.py delete mode 100644 setup.py diff --git a/Python/SyncRNG.py b/Python/SyncRNG.py deleted file mode 100644 index 0ab4c06..0000000 --- a/Python/SyncRNG.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Simple interface to SyncRNG. This file defines a SyncRNG object which can be -used to seed and pull numbers from the RNG. - -""" - -from __future__ import division - -from copy import deepcopy -from warnings import warn as _warn - -import syncrng - -class SyncRNG(object): - - def __init__(self, seed=0): - self.BPF = 32 - self.seed = seed - self.state = syncrng.seed(seed) - - def randi(self): - tmp = syncrng.rand(self.state) - self.state = tmp[:-1] - return(tmp[-1]) - - def rand(self): - return self.randi() * 2.3283064365387e-10 - - def randbelow(self, n): - maxsize = 1<= maxsize: - _warn("Underlying random generator does not supply \n" - "enough bits to choose from a population range this " - "large.\n") - return int(self.rand() * n) - rem = maxsize % n - limit = (maxsize - rem) / maxsize - r = self.rand() - while r >= limit: - r = self.rand() - return int(r*maxsize) % n - - def shuffle(self, x): - y = deepcopy(x) - for i in reversed(range(1, len(y))): - j = self.randbelow(i+1) - y[i], y[j] = y[j], y[i] - return y diff --git a/setup.py b/setup.py deleted file mode 100644 index 985c1eb..0000000 --- a/setup.py +++ /dev/null @@ -1,19 +0,0 @@ - -from distutils.core import setup, Extension - -setup( - name='SyncRNG', - author='Gertjan van den Burg', - version='1.0', - description='A synchronized Tausworthe RNG for Python and R', - license='GPL v2', - package_dir={'': 'Python'}, - packages=[''], - ext_modules=[ - Extension( - "syncrng", - define_macros=[('TARGETPYTHON', '1')], - sources=["src/syncrng.c"] - ) - ], - ) -- cgit v1.2.3 From e9e06589dd104a10170d195dddf5d0b9390e187e Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Wed, 12 Oct 2016 22:29:39 +0200 Subject: add testthat unit testing framework --- DESCRIPTION | 5 +- test/first_1000_seed_0.txt | 1000 ---------------------------------- test/run_tests.sh | 3 - test/test.R | 43 -- test/test.py | 34 -- tests/testthat.R | 4 + tests/testthat/first_1000_seed_0.txt | 1000 ++++++++++++++++++++++++++++++++++ tests/testthat/tests.R | 48 ++ 8 files changed, 1055 insertions(+), 1082 deletions(-) delete mode 100644 test/first_1000_seed_0.txt delete mode 100755 test/run_tests.sh delete mode 100644 test/test.R delete mode 100644 test/test.py create mode 100644 tests/testthat.R create mode 100644 tests/testthat/first_1000_seed_0.txt create mode 100644 tests/testthat/tests.R diff --git a/DESCRIPTION b/DESCRIPTION index ac0ee0c..ee619eb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: SyncRNG -Version: 1.0 -Date: 2015-07-31 +Version: 1.1.0 +Date: 2016-10-12 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg Maintainer: Gertjan van den Burg @@ -9,3 +9,4 @@ Description: Random number generation designed for cross-language usage. License: file LICENSE Imports: methods +Suggests: testthat diff --git a/test/first_1000_seed_0.txt b/test/first_1000_seed_0.txt deleted file mode 100644 index 50aef45..0000000 --- a/test/first_1000_seed_0.txt +++ /dev/null @@ -1,1000 +0,0 @@ -1574944 -268744 -33556004 -8390676 -16851968 -2147582472 -134350084 -1074315269 -2097666 -2693283843 -50598144 -402792448 -536872117 -2281705500 -2097216 -67127296 -1192 -4097 -413712 -68096 -537198610 -9502976 -1077936653 -23069188 -256 -271065282 -1375735819 -1075056808 -137344 -537396752 -71370760 -134520872 -3196164 -24836 -2164785857 -2183397387 -269344 -41977872 -943785105 -2195975 -2283815708 -3170454 -68182051 -2281710785 -34344960 -1074024480 -460824 -839122944 -7438364 -155238412 -2166440334 -67126401 -3489693830 -1124336267 -537284650 -8392144 -805381657 -2165408 -29452 -2146516 -33704323 -2148282537 -19138624 -1619267616 -33754640 -671155715 -549519625 -3422584857 -7889684 -12289 -3223323809 -302387200 -1334448 -12654616 -940410368 -69321472 -205808168 -2167956679 -422150 -3506449091 -3263561808 -1350900792 -6425240 -809550976 -543263112 -203481359 -2146694 -1196512 -3355967617 -61734977 -8853552 -46403088 -704741917 -540082961 -2365612954 -2149671132 -117458370 -2147925124 -59121344 -1342640170 -4362072 -805610753 -5308846 -37785610 -20730196 -28992 -2952790235 -1082458123 -466480 -10487956 -1006651158 -11135872 -1241543311 -3229405863 -84162883 -2687116417 -308610137 -1217697952 -34756884 -940057617 -2757853260 -2281750584 -2117046 -8536213 -2432762497 -2200211979 -143004704 -9555090 -541402267 -2688090691 -140792396 -18901124 -34619827 -2281975939 -1126991882 -1611028540 -1510426 -570433665 -4261976 -201367560 -2151409932 -159745 -2416476396 -36078209 -545545526 -47188314 -570525328 -540398565 -2231400988 -2688182423 -359426 -3489672937 -10915924 -1409751076 -8104090 -805697154 -1089569002 -1296220170 -23228310 -71304648 -3357573835 -1402388746 -68628924 -2161655515 -571323533 -1144329024 -226905022 -807660740 -123848654 -3507419777 -2206633420 -1879528495 -39521946 -675329344 -4260201 -2342551838 -4160788 -1080928 -2952791293 -42848321 -350126 -2159872543 -1023504852 -4190932 -171990682 -1631541431 -19363907 -3758286790 -1113949782 -1845794863 -948310 -536886913 -3764488345 -17297420 -2279406 -81939869 -2349451169 -18637697 -243556660 -3263987441 -705043609 -3232571140 -3385285445 -946061980 -106022815 -2149881281 -2466519302 -1645367474 -918576 -546053696 -877659196 -216334888 -154739468 -70398851 -3707790308 -1107714240 -41949434 -3234631865 -960994496 -271830786 -205637392 -2285371587 -68563108 -3355977792 -2192441361 -1367412784 -40143408 -981517841 -543196563 -2367734299 -2283872410 -1344 -2181071879 -2206859904 -553846898 -549654344 -805609997 -2163104 -71332746 -86007956 -117991874 -3490064554 -25562218 -1879511088 -4425864 -541165322 -146901518 -1242620175 -75297540 -2148145409 -2687242416 -1386547200 -1515192 -312547844 -879347469 -606675077 -2315539260 -3292288180 -84170823 -2701271680 -3259307090 -1208409120 -1231108 -805578376 -2691760719 -141869068 -86001956 -76571121 -2298545346 -53381707 -142892072 -278219778 -574726163 -2150205781 -151286350 -2250360974 -101086355 -3490494661 -1661242064 -1074073654 -34738122 -945816717 -608289773 -2232988060 -104487366 -1141132385 -3506572416 -1610914817 -12933420 -416320010 -980706718 -10825792 -3443551182 -2776525524 -335138 -3231722194 -44532831 -1421335228 -142342666 -811120154 -1147218925 -2367611246 -69654868 -4222348 -3624435928 -3551840523 -77967668 -2463755847 -706032790 -1077262534 -2376231880 -925059286 -125304554 -3624333504 -1940823454 -1887737903 -6262158 -578073551 -106029822 -182235594 -2252236174 -1678131760 -3909323963 -847760523 -552000424 -2629422019 -795718747 -3090656 -3271585593 -3845708012 -19353971 -2966053808 -1212416724 -1312070453 -235870850 -3091824202 -3269792698 -152819996 -98860412 -820192477 -2369799568 -1396620160 -244589602 -3498863850 -574856834 -3829239105 -159603286 -1067697294 -39236251 -2432997826 -721684755 -1644254266 -955946 -2695372509 -356835194 -211485320 -238662558 -1076233167 -3307891111 -3794546048 -37949562 -3637088288 -863193421 -271789329 -761391063 -205299928 -67378860 -2158013456 -3599194065 -1907079858 -174119784 -1624289467 -7483173 -2759382862 -224727064 -134258952 -3543155069 -2441640202 -2174979241 -851922069 -542448292 -3253137 -2080458461 -54616262 -252468170 -3223217159 -665218426 -4028018793 -4626772 -1748803383 -709060767 -3121149182 -56479134 -3893141625 -2686933815 -2995214218 -2162482869 -262490641 -1011561522 -549060114 -3932247987 -3223024295 -152321631 -3101843551 -1280099225 -3358647209 -252846296 -3524154097 -2187760847 -3909680653 -2179387890 -1015137433 -3494929304 -50606464 -3901100357 -9850320 -940382251 -2699631292 -3087385960 -9538500 -234958491 -272389742 -220260678 -2684647653 -43257408 -4027072178 -28810004 -2101495309 -18607774 -134280454 -3223347501 -1376157898 -3222543805 -22419610 -973776048 -83221848 -218483748 -2685071319 -134550656 -3506980865 -2173075612 -2483766325 -66860762 -138671625 -1075841013 -2367832091 -2247808 -38814954 -3490485897 -60737793 -604469508 -2153524819 -536917141 -1074075984 -12724890 -2972321868 -23188040 -1074423975 -1117820684 -1879381029 -1739586 -939530176 -5327050 -58757130 -2151669013 -67532608 -3087534325 -2474001 -277224382 -2191034903 -1057240535 -549434183 -3405807240 -1618369262 -86191107 -2955045761 -308647117 -1578408101 -3139990 -806116500 -3831595195 -155443373 -19022846 -98715033 -2634272139 -3275515777 -512124196 -3230432369 -575086366 -3225228801 -199711444 -942108876 -121867967 -2819529105 -2200767815 -1921129010 -36410428 -780163669 -274212015 -2376151708 -3359123316 -20068231 -2349001203 -2185655880 -973119224 -3235762297 -755212101 -2956716003 -103138961 -3376199891 -92680340 -3758301290 -3236398675 -1090770984 -4196670 -813793301 -16288768 -1277219531 -140550882 -25313600 -3257601090 -2477397505 -429066492 -583196168 -671646619 -2754150662 -2399163262 -69629076 -101346518 -3775145624 -3282507882 -1619334952 -6457996 -637846925 -676180878 -175175818 -1698451828 -2233162017 -3087408874 -49089607 -478663992 -280881932 -945942552 -3224705271 -151407497 -607767788 -80172123 -3624479885 -1110753748 -2013690146 -2184431875 -709117454 -2692553290 -2157242825 -874605844 -86108881 -2567065312 -1092017287 -344356159 -2425400907 -574662615 -1084594274 -1262643867 -929455814 -56999307 -2821124246 -858115549 -1888834109 -2150800911 -627861145 -6024170 -228373816 -1178327534 -1093027685 -3624421308 -3798255747 -449290167 -2597181707 -926243929 -2687439124 -254107214 -3829027460 -93803542 -3968018064 -1388720668 -1151812149 -1214147364 -844558349 -1080633195 -2350576007 -2368200508 -97528200 -2365796063 -2476535242 -1017242931 -3503925127 -852957056 -3492589682 -115795988 -925186774 -40237656 -4094491891 -1906813406 -1611043710 -1115295490 -787740617 -652006269 -3420228435 -1736435170 -1628768048 -3173066342 -1659370060 -502667371 -3701617539 -971219790 -3559002171 -3372410256 -2218574844 -14962797 -2680285584 -2318530008 -1580611180 -3962509653 -2995731663 -3262644231 -3386622672 -832903192 -826852989 -2339061594 -52616487 -319161836 -848007203 -713596765 -405804387 -2343674302 -2393126614 -2268412740 -3959609298 -3943003701 -1375818464 -3492713455 -3041590872 -1028634474 -69944722 -1329116577 -3238922414 -3508802651 -2688827650 -432118456 -181619625 -1020588554 -2158511183 -3996414429 -3430521601 -92558330 -4085981271 -3335052120 -1094411888 -943803286 -2019381420 -612050958 -739046845 -40203708 -160356556 -3241366485 -3011934011 -2552681725 -46401557 -544316860 -2897832596 -1064122014 -34062854 -3390969819 -4180831325 -2007854337 -3762749433 -174296912 -1678023203 -39792904 -3137637515 -3780663668 -688110716 -3769355130 -46416140 -3162873767 -230484689 -571417648 -3770011349 -1611628070 -2703187687 -147275591 -2556554365 -236196063 -3627157681 -2268570387 -3524220149 -2196407803 -683730648 -832718794 -958399385 -2289805767 -1393849733 -3560321216 -2190933457 -570506109 -1190464059 -855891340 -815207364 -727755671 -959944786 -2399256258 -2955296368 -2226474309 -4248919733 -54373041 -4255540140 -1079558374 -758297126 -3494062195 -172905473 -3660879546 -2169485331 -3171064613 -2734421278 -239124661 -1636792719 -1032199552 -3022143494 -1238328860 -2755367096 -1172068287 -2416030799 -1111231360 -1162238438 -136341168 -936511690 -3697688233 -2310946572 -1017208991 -3260655066 -2861019521 -4085782611 -3269494883 -820892676 -610312130 -873064187 -444719755 -1077221226 -1178295173 -2928297301 -123238584 -1803717266 -3778860833 -622164036 -2906858569 -3462751317 -230473195 -3229782038 -4056351409 -4062480954 -157481248 -15888294 -1022616105 -2251826379 -236458376 -3468433827 -3859679691 -4169609282 -3270154816 -3638739572 -3024095882 -811148317 -3261183116 -1325974504 -589588966 -546263216 -4039391440 -1001817745 -16154680 -165750980 -2788265304 -2620478124 -3439592229 -1654681662 -3608040307 -3777078995 -994394444 -1014396095 -138120475 -2685072838 -3228373358 -2552662027 -28069284 -314728824 -2426995424 -649430792 -2352053910 -2291666758 -940013010 -3257519298 -143153873 -2445086935 -895972163 -2420598353 -573867732 -1148475689 -120727570 -874272160 -1499568331 -730384503 -2381214 -272910609 -2992637073 -253053713 -84832812 -2226240734 -3876274424 -18983620 -1268799900 -1348803766 -205671635 -2826229385 -660957935 -1646191083 -103509332 -1678012033 -2713914564 -2105972745 -14594356 -278969605 -3966027377 -46113154 -1246514745 -3316402942 -990363635 -2962749314 -524577371 -3903648383 -202779778 -3762835161 -2261224091 -3692935449 -90068990 -813864789 -3496510266 -3456387596 -143015350 -315738178 -4026606747 -2176794694 -2351395438 -2264420045 -68273726 -3627034496 -1856958854 -1350988020 -58099784 -4067096716 -100097690 -1012654471 -2271403796 -1141174688 -2164427209 -562335369 -549995830 -416389002 -309413793 -11860448 -2231458885 -604433027 -251864294 -3498465912 -1401395398 -3022766621 -190641354 -139719433 -1619043956 -1125777754 -74067650 -4207624 -958432937 -1116985600 -79164300 -2419620443 -777581327 -1142807361 -63314936 -4130282535 -23324492 -554363587 -2992739718 -1208439855 -772634 -540021839 -2789338031 -163090632 -120839590 -1620336448 -2164918412 -1913539649 -141022634 -2660075661 -963507036 -2687451280 -1208246255 -2771730565 -69420323 -3233866653 -1241879628 -1723226915 -202266692 -2689359561 -1651839518 -3227502861 -78020380 -811821517 -2640397810 -18786699 -109454782 -3498917610 -542022675 -1621201984 -1220764211 -518079134 -106428047 -2150406528 -4213442838 -1712410802 -33957546 -2833255501 -1363466077 -2361205692 -238621598 -1081475811 -3290623399 -1645509834 -105086074 -1522806889 -959667661 -1344480514 -2894325459 -2637988048 -7641220 -3634424343 -2525971609 -1437315771 -174455456 -1926534907 -1080174481 -2914707278 -2355466320 -138587648 -2201502550 -3552082560 -2770463793 -818376469 -961820903 -1622385204 -3028513484 -318825118 -189698242 -3224822639 -898006137 -4135907579 -37993300 -1613862757 -1859348874 -2060448975 -35441046 -3966690161 -3037175409 -1654613515 -2255792831 -1335945969 -1023753955 -1688992272 -3938874011 -3642382007 -225770871 -2716500061 -207929882 -3426021282 -219580528 -3637400609 -3530004700 -1753898265 -166081018 -1019445811 -2555921818 -2201231873 -3422693765 -43214040 -587807866 -3506115085 -837243260 -2442251152 -240230417 -1077703104 -1327561358 -2265348349 diff --git a/test/run_tests.sh b/test/run_tests.sh deleted file mode 100755 index 4c7c5da..0000000 --- a/test/run_tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -paste <(python test.py) <(Rscript test.R) diff --git a/test/test.R b/test/test.R deleted file mode 100644 index 0937f52..0000000 --- a/test/test.R +++ /dev/null @@ -1,43 +0,0 @@ -library(SyncRNG) - -test.randi <- function() -{ - s <- SyncRNG(seed=123456) - for (i in 1:5) - cat(s$randi(), '\n') -} - -test.rand <- function() -{ - s <- SyncRNG(seed=123456) - for (i in 1:5) - cat(sprintf('%.16f\n', s$rand())) -} - -test.randbelow <- function() -{ - s <- SyncRNG(seed=123456) - for (i in 1:5) - cat(s$randbelow(i), '\n') -} - -test.shuffle <- function() -{ - s <- SyncRNG(seed=123456) - x <- c(1:5) - for (i in 1:5) { - y <- s$shuffle(x) - x <- y - cat('[', paste(y, collapse=', '), ']\n', sep='') - } -} - -main <- function() -{ - test.randi() - test.rand() - test.randbelow() - test.shuffle() -} - -main() diff --git a/test/test.py b/test/test.py deleted file mode 100644 index 7d3f9f5..0000000 --- a/test/test.py +++ /dev/null @@ -1,34 +0,0 @@ - -from SyncRNG import SyncRNG - -def test_randi(): - s = SyncRNG(seed=123456) - for i in range(5): - print(s.randi()) - -def test_rand(): - s = SyncRNG(seed=123456) - for i in range(5): - print('%.16f' % s.rand()) - -def test_randbelow(): - s = SyncRNG(seed=123456) - for i in range(5): - print(s.randbelow(i+1)) - -def test_shuffle(): - s = SyncRNG(seed=123456) - x = [1, 2, 3, 4, 5] - for i in range(5): - y = s.shuffle(x) - x = y - print(y) - -def main(): - test_randi() - test_rand() - test_randbelow() - test_shuffle() - -if __name__ == '__main__': - main() diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..b1f5cc8 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,4 @@ +library(testthat) +library(SyncRNG) + +test_check("SyncRNG") diff --git a/tests/testthat/first_1000_seed_0.txt b/tests/testthat/first_1000_seed_0.txt new file mode 100644 index 0000000..50aef45 --- /dev/null +++ b/tests/testthat/first_1000_seed_0.txt @@ -0,0 +1,1000 @@ +1574944 +268744 +33556004 +8390676 +16851968 +2147582472 +134350084 +1074315269 +2097666 +2693283843 +50598144 +402792448 +536872117 +2281705500 +2097216 +67127296 +1192 +4097 +413712 +68096 +537198610 +9502976 +1077936653 +23069188 +256 +271065282 +1375735819 +1075056808 +137344 +537396752 +71370760 +134520872 +3196164 +24836 +2164785857 +2183397387 +269344 +41977872 +943785105 +2195975 +2283815708 +3170454 +68182051 +2281710785 +34344960 +1074024480 +460824 +839122944 +7438364 +155238412 +2166440334 +67126401 +3489693830 +1124336267 +537284650 +8392144 +805381657 +2165408 +29452 +2146516 +33704323 +2148282537 +19138624 +1619267616 +33754640 +671155715 +549519625 +3422584857 +7889684 +12289 +3223323809 +302387200 +1334448 +12654616 +940410368 +69321472 +205808168 +2167956679 +422150 +3506449091 +3263561808 +1350900792 +6425240 +809550976 +543263112 +203481359 +2146694 +1196512 +3355967617 +61734977 +8853552 +46403088 +704741917 +540082961 +2365612954 +2149671132 +117458370 +2147925124 +59121344 +1342640170 +4362072 +805610753 +5308846 +37785610 +20730196 +28992 +2952790235 +1082458123 +466480 +10487956 +1006651158 +11135872 +1241543311 +3229405863 +84162883 +2687116417 +308610137 +1217697952 +34756884 +940057617 +2757853260 +2281750584 +2117046 +8536213 +2432762497 +2200211979 +143004704 +9555090 +541402267 +2688090691 +140792396 +18901124 +34619827 +2281975939 +1126991882 +1611028540 +1510426 +570433665 +4261976 +201367560 +2151409932 +159745 +2416476396 +36078209 +545545526 +47188314 +570525328 +540398565 +2231400988 +2688182423 +359426 +3489672937 +10915924 +1409751076 +8104090 +805697154 +1089569002 +1296220170 +23228310 +71304648 +3357573835 +1402388746 +68628924 +2161655515 +571323533 +1144329024 +226905022 +807660740 +123848654 +3507419777 +2206633420 +1879528495 +39521946 +675329344 +4260201 +2342551838 +4160788 +1080928 +2952791293 +42848321 +350126 +2159872543 +1023504852 +4190932 +171990682 +1631541431 +19363907 +3758286790 +1113949782 +1845794863 +948310 +536886913 +3764488345 +17297420 +2279406 +81939869 +2349451169 +18637697 +243556660 +3263987441 +705043609 +3232571140 +3385285445 +946061980 +106022815 +2149881281 +2466519302 +1645367474 +918576 +546053696 +877659196 +216334888 +154739468 +70398851 +3707790308 +1107714240 +41949434 +3234631865 +960994496 +271830786 +205637392 +2285371587 +68563108 +3355977792 +2192441361 +1367412784 +40143408 +981517841 +543196563 +2367734299 +2283872410 +1344 +2181071879 +2206859904 +553846898 +549654344 +805609997 +2163104 +71332746 +86007956 +117991874 +3490064554 +25562218 +1879511088 +4425864 +541165322 +146901518 +1242620175 +75297540 +2148145409 +2687242416 +1386547200 +1515192 +312547844 +879347469 +606675077 +2315539260 +3292288180 +84170823 +2701271680 +3259307090 +1208409120 +1231108 +805578376 +2691760719 +141869068 +86001956 +76571121 +2298545346 +53381707 +142892072 +278219778 +574726163 +2150205781 +151286350 +2250360974 +101086355 +3490494661 +1661242064 +1074073654 +34738122 +945816717 +608289773 +2232988060 +104487366 +1141132385 +3506572416 +1610914817 +12933420 +416320010 +980706718 +10825792 +3443551182 +2776525524 +335138 +3231722194 +44532831 +1421335228 +142342666 +811120154 +1147218925 +2367611246 +69654868 +4222348 +3624435928 +3551840523 +77967668 +2463755847 +706032790 +1077262534 +2376231880 +925059286 +125304554 +3624333504 +1940823454 +1887737903 +6262158 +578073551 +106029822 +182235594 +2252236174 +1678131760 +3909323963 +847760523 +552000424 +2629422019 +795718747 +3090656 +3271585593 +3845708012 +19353971 +2966053808 +1212416724 +1312070453 +235870850 +3091824202 +3269792698 +152819996 +98860412 +820192477 +2369799568 +1396620160 +244589602 +3498863850 +574856834 +3829239105 +159603286 +1067697294 +39236251 +2432997826 +721684755 +1644254266 +955946 +2695372509 +356835194 +211485320 +238662558 +1076233167 +3307891111 +3794546048 +37949562 +3637088288 +863193421 +271789329 +761391063 +205299928 +67378860 +2158013456 +3599194065 +1907079858 +174119784 +1624289467 +7483173 +2759382862 +224727064 +134258952 +3543155069 +2441640202 +2174979241 +851922069 +542448292 +3253137 +2080458461 +54616262 +252468170 +3223217159 +665218426 +4028018793 +4626772 +1748803383 +709060767 +3121149182 +56479134 +3893141625 +2686933815 +2995214218 +2162482869 +262490641 +1011561522 +549060114 +3932247987 +3223024295 +152321631 +3101843551 +1280099225 +3358647209 +252846296 +3524154097 +2187760847 +3909680653 +2179387890 +1015137433 +3494929304 +50606464 +3901100357 +9850320 +940382251 +2699631292 +3087385960 +9538500 +234958491 +272389742 +220260678 +2684647653 +43257408 +4027072178 +28810004 +2101495309 +18607774 +134280454 +3223347501 +1376157898 +3222543805 +22419610 +973776048 +83221848 +218483748 +2685071319 +134550656 +3506980865 +2173075612 +2483766325 +66860762 +138671625 +1075841013 +2367832091 +2247808 +38814954 +3490485897 +60737793 +604469508 +2153524819 +536917141 +1074075984 +12724890 +2972321868 +23188040 +1074423975 +1117820684 +1879381029 +1739586 +939530176 +5327050 +58757130 +2151669013 +67532608 +3087534325 +2474001 +277224382 +2191034903 +1057240535 +549434183 +3405807240 +1618369262 +86191107 +2955045761 +308647117 +1578408101 +3139990 +806116500 +3831595195 +155443373 +19022846 +98715033 +2634272139 +3275515777 +512124196 +3230432369 +575086366 +3225228801 +199711444 +942108876 +121867967 +2819529105 +2200767815 +1921129010 +36410428 +780163669 +274212015 +2376151708 +3359123316 +20068231 +2349001203 +2185655880 +973119224 +3235762297 +755212101 +2956716003 +103138961 +3376199891 +92680340 +3758301290 +3236398675 +1090770984 +4196670 +813793301 +16288768 +1277219531 +140550882 +25313600 +3257601090 +2477397505 +429066492 +583196168 +671646619 +2754150662 +2399163262 +69629076 +101346518 +3775145624 +3282507882 +1619334952 +6457996 +637846925 +676180878 +175175818 +1698451828 +2233162017 +3087408874 +49089607 +478663992 +280881932 +945942552 +3224705271 +151407497 +607767788 +80172123 +3624479885 +1110753748 +2013690146 +2184431875 +709117454 +2692553290 +2157242825 +874605844 +86108881 +2567065312 +1092017287 +344356159 +2425400907 +574662615 +1084594274 +1262643867 +929455814 +56999307 +2821124246 +858115549 +1888834109 +2150800911 +627861145 +6024170 +228373816 +1178327534 +1093027685 +3624421308 +3798255747 +449290167 +2597181707 +926243929 +2687439124 +254107214 +3829027460 +93803542 +3968018064 +1388720668 +1151812149 +1214147364 +844558349 +1080633195 +2350576007 +2368200508 +97528200 +2365796063 +2476535242 +1017242931 +3503925127 +852957056 +3492589682 +115795988 +925186774 +40237656 +4094491891 +1906813406 +1611043710 +1115295490 +787740617 +652006269 +3420228435 +1736435170 +1628768048 +3173066342 +1659370060 +502667371 +3701617539 +971219790 +3559002171 +3372410256 +2218574844 +14962797 +2680285584 +2318530008 +1580611180 +3962509653 +2995731663 +3262644231 +3386622672 +832903192 +826852989 +2339061594 +52616487 +319161836 +848007203 +713596765 +405804387 +2343674302 +2393126614 +2268412740 +3959609298 +3943003701 +1375818464 +3492713455 +3041590872 +1028634474 +69944722 +1329116577 +3238922414 +3508802651 +2688827650 +432118456 +181619625 +1020588554 +2158511183 +3996414429 +3430521601 +92558330 +4085981271 +3335052120 +1094411888 +943803286 +2019381420 +612050958 +739046845 +40203708 +160356556 +3241366485 +3011934011 +2552681725 +46401557 +544316860 +2897832596 +1064122014 +34062854 +3390969819 +4180831325 +2007854337 +3762749433 +174296912 +1678023203 +39792904 +3137637515 +3780663668 +688110716 +3769355130 +46416140 +3162873767 +230484689 +571417648 +3770011349 +1611628070 +2703187687 +147275591 +2556554365 +236196063 +3627157681 +2268570387 +3524220149 +2196407803 +683730648 +832718794 +958399385 +2289805767 +1393849733 +3560321216 +2190933457 +570506109 +1190464059 +855891340 +815207364 +727755671 +959944786 +2399256258 +2955296368 +2226474309 +4248919733 +54373041 +4255540140 +1079558374 +758297126 +3494062195 +172905473 +3660879546 +2169485331 +3171064613 +2734421278 +239124661 +1636792719 +1032199552 +3022143494 +1238328860 +2755367096 +1172068287 +2416030799 +1111231360 +1162238438 +136341168 +936511690 +3697688233 +2310946572 +1017208991 +3260655066 +2861019521 +4085782611 +3269494883 +820892676 +610312130 +873064187 +444719755 +1077221226 +1178295173 +2928297301 +123238584 +1803717266 +3778860833 +622164036 +2906858569 +3462751317 +230473195 +3229782038 +4056351409 +4062480954 +157481248 +15888294 +1022616105 +2251826379 +236458376 +3468433827 +3859679691 +4169609282 +3270154816 +3638739572 +3024095882 +811148317 +3261183116 +1325974504 +589588966 +546263216 +4039391440 +1001817745 +16154680 +165750980 +2788265304 +2620478124 +3439592229 +1654681662 +3608040307 +3777078995 +994394444 +1014396095 +138120475 +2685072838 +3228373358 +2552662027 +28069284 +314728824 +2426995424 +649430792 +2352053910 +2291666758 +940013010 +3257519298 +143153873 +2445086935 +895972163 +2420598353 +573867732 +1148475689 +120727570 +874272160 +1499568331 +730384503 +2381214 +272910609 +2992637073 +253053713 +84832812 +2226240734 +3876274424 +18983620 +1268799900 +1348803766 +205671635 +2826229385 +660957935 +1646191083 +103509332 +1678012033 +2713914564 +2105972745 +14594356 +278969605 +3966027377 +46113154 +1246514745 +3316402942 +990363635 +2962749314 +524577371 +3903648383 +202779778 +3762835161 +2261224091 +3692935449 +90068990 +813864789 +3496510266 +3456387596 +143015350 +315738178 +4026606747 +2176794694 +2351395438 +2264420045 +68273726 +3627034496 +1856958854 +1350988020 +58099784 +4067096716 +100097690 +1012654471 +2271403796 +1141174688 +2164427209 +562335369 +549995830 +416389002 +309413793 +11860448 +2231458885 +604433027 +251864294 +3498465912 +1401395398 +3022766621 +190641354 +139719433 +1619043956 +1125777754 +74067650 +4207624 +958432937 +1116985600 +79164300 +2419620443 +777581327 +1142807361 +63314936 +4130282535 +23324492 +554363587 +2992739718 +1208439855 +772634 +540021839 +2789338031 +163090632 +120839590 +1620336448 +2164918412 +1913539649 +141022634 +2660075661 +963507036 +2687451280 +1208246255 +2771730565 +69420323 +3233866653 +1241879628 +1723226915 +202266692 +2689359561 +1651839518 +3227502861 +78020380 +811821517 +2640397810 +18786699 +109454782 +3498917610 +542022675 +1621201984 +1220764211 +518079134 +106428047 +2150406528 +4213442838 +1712410802 +33957546 +2833255501 +1363466077 +2361205692 +238621598 +1081475811 +3290623399 +1645509834 +105086074 +1522806889 +959667661 +1344480514 +2894325459 +2637988048 +7641220 +3634424343 +2525971609 +1437315771 +174455456 +1926534907 +1080174481 +2914707278 +2355466320 +138587648 +2201502550 +3552082560 +2770463793 +818376469 +961820903 +1622385204 +3028513484 +318825118 +189698242 +3224822639 +898006137 +4135907579 +37993300 +1613862757 +1859348874 +2060448975 +35441046 +3966690161 +3037175409 +1654613515 +2255792831 +1335945969 +1023753955 +1688992272 +3938874011 +3642382007 +225770871 +2716500061 +207929882 +3426021282 +219580528 +3637400609 +3530004700 +1753898265 +166081018 +1019445811 +2555921818 +2201231873 +3422693765 +43214040 +587807866 +3506115085 +837243260 +2442251152 +240230417 +1077703104 +1327561358 +2265348349 diff --git a/tests/testthat/tests.R b/tests/testthat/tests.R new file mode 100644 index 0000000..4be1756 --- /dev/null +++ b/tests/testthat/tests.R @@ -0,0 +1,48 @@ +library(SyncRNG) +context("SyncRNG unit tests") + +test_that("test_randi", { + s <- SyncRNG(seed=123456) + expect_equal(s$randi(), 959852049) + expect_equal(s$randi(), 2314333085) + expect_equal(s$randi(), 2255782734) + expect_equal(s$randi(), 2921461239) + expect_equal(s$randi(), 1024197102) +}) + +test_that("test_rand", { + s <- SyncRNG(seed=123456) + expect_equal(s$rand(), 959852049 /(2**32)) + expect_equal(s$rand(), 2314333085/(2**32)) + expect_equal(s$rand(), 2255782734/(2**32)) + expect_equal(s$rand(), 2921461239/(2**32)) + expect_equal(s$rand(), 1024197102/(2**32)) +}) + +test_that("test_randbelow", { + s <- SyncRNG(seed=123456) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 0) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 2) +}) + +test_that("test_shuffle", { + s <- SyncRNG(seed=123456) + x <- c(1, 2, 3, 4, 5) + y <- s$shuffle(x) + expect_equal(y, c(3, 4, 1, 2, 5)) +}) + +test_that("test_first_1000", { + s <- SyncRNG(seed=0) + fileName <- "./first_1000_seed_0.txt" + conn <- file(fileName, open="r") + linn <- readLines(conn) + for (i in 1:length(linn)) { + exp <- as.numeric(linn[i]) + expect_equal(exp, s$randi()) + } + close(conn) +}) -- cgit v1.2.3 From 5245e3a8f8bcaabcbf793cacc7047dce4017dfc6 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 14 Oct 2016 21:47:36 +0200 Subject: minor documentation fixes and add cran-comments --- .gitignore | 2 ++ R/SyncRNG.R | 2 +- cran-comments.md | 5 +++++ man/SyncRNG-class.Rd | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 cran-comments.md diff --git a/.gitignore b/.gitignore index ed61eb2..7a22bc3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc *.so *.o +.Rproj.user +SyncRNG.Rproj diff --git a/R/SyncRNG.R b/R/SyncRNG.R index 84088b0..72156df 100644 --- a/R/SyncRNG.R +++ b/R/SyncRNG.R @@ -7,7 +7,7 @@ library(methods) #' user #' #' @examples -#' s = SyncRNG(seed=123456) +#' s <- SyncRNG(seed=123456) #' for (i in 1:10) #' cat(s$randi(), '\n') #' diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 0000000..4dc64c6 --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,5 @@ +## Test environments +* local Arch Linux install, R 3.3.1 + +## R CMD check results + diff --git a/man/SyncRNG-class.Rd b/man/SyncRNG-class.Rd index 599b540..d09f331 100644 --- a/man/SyncRNG-class.Rd +++ b/man/SyncRNG-class.Rd @@ -30,7 +30,7 @@ user} \item{\code{shuffle(x)}}{Randomly shuffle a provided array of values} }} \examples{ -s = SyncRNG(seed=123456) +s <- SyncRNG(seed=123456) for (i in 1:10) cat(s$randi(), '\\n') } -- cgit v1.2.3 From 966e761ca3fdd70791b4cabc63427b7e5d531e8d Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 14 Oct 2016 22:29:08 +0200 Subject: version bump due switch from md to rst --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index ee619eb..9920125 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: SyncRNG -Version: 1.1.0 +Version: 1.1.1 Date: 2016-10-12 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg -- cgit v1.2.3 From 1981ca8c6277bda5fc145ef05e64bc0ca2752718 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sat, 15 Oct 2016 10:58:41 +0200 Subject: update version and rename rst to md readme --- DESCRIPTION | 2 +- README.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.rst | 70 -------------------------------------------------------- cran-comments.md | 11 +++++++++ 4 files changed, 82 insertions(+), 71 deletions(-) create mode 100644 README.md delete mode 100644 README.rst diff --git a/DESCRIPTION b/DESCRIPTION index 9920125..f2326d1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: SyncRNG -Version: 1.1.1 +Version: 1.2.0 Date: 2016-10-12 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg diff --git a/README.md b/README.md new file mode 100644 index 0000000..08afc28 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +======= +SyncRNG +======= +A synchronized Tausworthe RNG usable in R and Python. + +Why? +==== + +This program was created because it was desired to have the same random +numbers in both R and Python programs. Although both languages implement a +Mersenne-Twister RNG, the implementations are so different that it is not +possible to get the same random numbers with the same seed. + +SyncRNG is a Tausworthe RNG implemented in ``syncrng.c``, and linked to both R +and Python. Since both use the same underlying C code, the random numbers will +be the same in both languages, provided the same seed is used. + +How +=== + +First install the packages as stated under Installation. Then, in Python you +can do:: + + from SyncRNG import SyncRNG + + s = SyncRNG(seed=123456) + for i in range(10): + print(s.randi()) + +Similarly, after installing the R library you can do in R:: + + library(SyncRNG) + + s <- SyncRNG(seed=123456) + for (i in 1:10) { + cat(s$randi(), '\n') + } + +You'll notice that the random numbers are indeed the same. + +Installation +============ + +Installing the R package can be done through CRAN:: + + install.packages('SyncRNG') + +The Python package can be installed using pip:: + + pip install syncrng + + +Usage +===== + +In both R and Python the following methods are available for the ``SyncRNG`` +class: + +1. ``randi()``: generate a random integer on the interval [0, 2^32). +2. ``rand()``: generate a random floating point number on the interval [0.0, + 1.0) +3. ``randbelow(n)``: generate a random integer below a given integer ``n``. +4. ``shuffle(x)``: generate a permutation of a given list of numbers ``x``. + +Notes +===== + +The random numbers are uniformly distributed on ``[0, 2^32 - 1]``. + + diff --git a/README.rst b/README.rst deleted file mode 100644 index 08afc28..0000000 --- a/README.rst +++ /dev/null @@ -1,70 +0,0 @@ -======= -SyncRNG -======= -A synchronized Tausworthe RNG usable in R and Python. - -Why? -==== - -This program was created because it was desired to have the same random -numbers in both R and Python programs. Although both languages implement a -Mersenne-Twister RNG, the implementations are so different that it is not -possible to get the same random numbers with the same seed. - -SyncRNG is a Tausworthe RNG implemented in ``syncrng.c``, and linked to both R -and Python. Since both use the same underlying C code, the random numbers will -be the same in both languages, provided the same seed is used. - -How -=== - -First install the packages as stated under Installation. Then, in Python you -can do:: - - from SyncRNG import SyncRNG - - s = SyncRNG(seed=123456) - for i in range(10): - print(s.randi()) - -Similarly, after installing the R library you can do in R:: - - library(SyncRNG) - - s <- SyncRNG(seed=123456) - for (i in 1:10) { - cat(s$randi(), '\n') - } - -You'll notice that the random numbers are indeed the same. - -Installation -============ - -Installing the R package can be done through CRAN:: - - install.packages('SyncRNG') - -The Python package can be installed using pip:: - - pip install syncrng - - -Usage -===== - -In both R and Python the following methods are available for the ``SyncRNG`` -class: - -1. ``randi()``: generate a random integer on the interval [0, 2^32). -2. ``rand()``: generate a random floating point number on the interval [0.0, - 1.0) -3. ``randbelow(n)``: generate a random integer below a given integer ``n``. -4. ``shuffle(x)``: generate a permutation of a given list of numbers ``x``. - -Notes -===== - -The random numbers are uniformly distributed on ``[0, 2^32 - 1]``. - - diff --git a/cran-comments.md b/cran-comments.md index 4dc64c6..2d3f44a 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,5 +1,16 @@ ## Test environments * local Arch Linux install, R 3.3.1 +* win-builder (devel and release) ## R CMD check results +There were no ERRORs or WARNINGs. + +There was 1 NOTE: + +* checking CRAN incoming feasibility ... NOTE + Maintainer: ‘Gertjan van den Burg ’ + + New submission + + Non-FOSS package license (file LICENSE) -- cgit v1.2.3 From 3fb8d4aca52c3004d52bd510e183c1d5682b5540 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 16 Oct 2016 12:13:36 +0200 Subject: update to latest version of roxygen --- DESCRIPTION | 7 +++++-- NAMESPACE | 7 +++++-- R/SyncRNG.R | 5 +++++ man/SyncRNG-class.Rd | 5 +++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f2326d1..d9444f0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -4,9 +4,12 @@ Date: 2016-10-12 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg Maintainer: Gertjan van den Burg -Depends: R (>= 3.0.0) +Depends: + R (>= 3.0.0) Description: Random number generation designed for cross-language usage. License: file LICENSE Imports: methods -Suggests: testthat +Suggests: + testthat +RoxygenNote: 5.0.1 diff --git a/NAMESPACE b/NAMESPACE index bb2ff1a..160a4f2 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,3 +1,6 @@ -useDynLib(SyncRNG) +# Generated by roxygen2: do not edit by hand + export(SyncRNG) -import(methods) +exportClasses(SyncRNG) +importFrom(methods,new) +useDynLib(SyncRNG) diff --git a/R/SyncRNG.R b/R/SyncRNG.R index 72156df..95e6b3e 100644 --- a/R/SyncRNG.R +++ b/R/SyncRNG.R @@ -6,6 +6,11 @@ library(methods) #' @field state The current state of the RNG, should not be modified by the #' user #' +#' @useDynLib SyncRNG +#' @export SyncRNG +#' @exportClass SyncRNG +#' @importFrom methods new +#' #' @examples #' s <- SyncRNG(seed=123456) #' for (i in 1:10) diff --git a/man/SyncRNG-class.Rd b/man/SyncRNG-class.Rd index d09f331..6f6d27d 100644 --- a/man/SyncRNG-class.Rd +++ b/man/SyncRNG-class.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/SyncRNG.R \docType{class} \name{SyncRNG-class} @@ -13,7 +13,7 @@ A Reference Class for SyncRNG \describe{ \item{\code{seed}}{The seed for the random number generator} -\item{\code{state}}{The current state of the RNG, should not be modified by the +\item{\code{state}}{The current state of the RNG, should not be modified by the user} }} \section{Methods}{ @@ -33,5 +33,6 @@ user} s <- SyncRNG(seed=123456) for (i in 1:10) cat(s$randi(), '\\n') + } -- cgit v1.2.3 From b0eeb330ec594ea6555f1f3fd3c520c19418200f Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 16 Oct 2016 13:31:58 +0200 Subject: bump version to correspond to C version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d9444f0..027c4d8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: SyncRNG -Version: 1.2.0 +Version: 1.2.1 Date: 2016-10-12 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg -- cgit v1.2.3 From a344012ead4e81114821cf9704484c0993510249 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 16 Oct 2016 13:41:42 +0200 Subject: update description --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 027c4d8..9219317 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: SyncRNG Version: 1.2.1 -Date: 2016-10-12 +Date: 2016-10-16 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg Maintainer: Gertjan van den Burg -- cgit v1.2.3 From 90df49c308d4088ad9bca1076d2a74e08f600d75 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 16 Oct 2016 15:22:37 +0200 Subject: remove license file on request of CRAN --- DESCRIPTION | 2 +- LICENSE | 340 ------------------------------------------------------- cran-comments.md | 7 +- 3 files changed, 6 insertions(+), 343 deletions(-) delete mode 100644 LICENSE diff --git a/DESCRIPTION b/DESCRIPTION index 9219317..be7806f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,7 +7,7 @@ Maintainer: Gertjan van den Burg Depends: R (>= 3.0.0) Description: Random number generation designed for cross-language usage. -License: file LICENSE +License: GPL-2 Imports: methods Suggests: diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8cdb845..0000000 --- a/LICENSE +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {description} - Copyright (C) {year} {fullname} - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - {signature of Ty Coon}, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. - diff --git a/cran-comments.md b/cran-comments.md index 2d3f44a..c75610f 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,3 +1,8 @@ +## Resubmission +This is a resubmission. In this version I have: +* removed the LICENSE file +* updated the DESCRIPTION to state "License: GPL-2" + ## Test environments * local Arch Linux install, R 3.3.1 * win-builder (devel and release) @@ -12,5 +17,3 @@ There was 1 NOTE: New submission - Non-FOSS package license (file LICENSE) - -- cgit v1.2.3 From 0b05168b80f627e175edee95a79cd0fd45f01338 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 15 Dec 2017 15:46:06 -0500 Subject: Make SyncRNG an actual user-defined RNG --- src/syncrng.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 14 deletions(-) diff --git a/src/syncrng.c b/src/syncrng.c index 025b1ca..8957047 100644 --- a/src/syncrng.c +++ b/src/syncrng.c @@ -10,6 +10,7 @@ #include #include #include +#include #endif /** @@ -36,9 +37,10 @@ * * @return a generated random number */ -uint64_t lfsr113(uint64_t **state) +uint32_t lfsr113(uint64_t **state) { - uint64_t z1, z2, z3, z4, b; + uint64_t z1, z2, z3, z4; + uint64_t b; z1 = (*state)[0]; z2 = (*state)[1]; @@ -66,7 +68,7 @@ uint64_t lfsr113(uint64_t **state) b = b & 0xFFFFFFFF; - return(b); + return((uint32_t) b); } /** @@ -80,12 +82,12 @@ uint64_t lfsr113(uint64_t **state) * @param[in] seed user supplied seed value for the RNG * @param[out] state state of the RNG */ -void lfsr113_seed(uint64_t seed, uint64_t **state) +void lfsr113_seed(uint32_t seed, uint64_t **state) { uint64_t z1 = 2, - z2 = 8, - z3 = 16, - z4 = 128; + z2 = 8, + z3 = 16, + z4 = 128; z1 = (z1 * (seed + 1)); z2 = (z2 * (seed + 1)); @@ -116,7 +118,7 @@ void lfsr113_seed(uint64_t seed, uint64_t **state) static PyObject *syncrng_seed(PyObject *self, PyObject *args) { - uint64_t seed, *state = NULL; + uint32_t seed, *state = NULL; if (!PyArg_ParseTuple(args, "k", &seed)) return NULL; @@ -131,7 +133,7 @@ static PyObject *syncrng_seed(PyObject *self, PyObject *args) static PyObject *syncrng_rand(PyObject *self, PyObject *args) { - uint64_t i, value, numints, *localstate; + uint32_t i, value, numints, *localstate; PyObject *listObj; PyObject *intObj; @@ -140,15 +142,15 @@ static PyObject *syncrng_rand(PyObject *self, PyObject *args) return NULL; // we're just assuming you would never pass more than 4 values - localstate = malloc(sizeof(uint64_t)*5); + localstate = malloc(sizeof(uint32_t)*5); numints = PyList_Size(listObj); for (i=0; i 0.259/u + 0.35) + continue; + } while (z > -log(u)); + global_R_result_normal = x; + return &global_R_result_normal; +} + /* * * End of R code -- cgit v1.2.3 From a75d571165c525734cfa0f91440904249d43a4fe Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 15 Dec 2017 15:56:05 -0500 Subject: add unit test for runif rng --- tests/testthat/tests.R | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/testthat/tests.R b/tests/testthat/tests.R index 4be1756..59dc004 100644 --- a/tests/testthat/tests.R +++ b/tests/testthat/tests.R @@ -46,3 +46,18 @@ test_that("test_first_1000", { } close(conn) }) + +printf <- function(...) invisible(cat(sprintf(...))); + +test_that("test_first_1000_unif", { + set.seed(0, 'user', 'user') + fileName <- "./first_1000_seed_0.txt" + conn <- file(fileName, open="r") + linn <- readLines(conn) + for (i in 1:length(linn)) { + exp <- as.numeric(linn[i]) + u <- as.numeric(runif(1)*(2**32 - 1)) + expect_equal(exp, u) + } + close(conn) +}) -- cgit v1.2.3 From db0755d027f0f88568909e16b715c8e769333390 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 15 Dec 2017 17:25:50 -0500 Subject: fix warnings from R about routine registration --- src/syncrng.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/syncrng.c b/src/syncrng.c index 8957047..8a0b5b4 100644 --- a/src/syncrng.c +++ b/src/syncrng.c @@ -11,6 +11,7 @@ #include #include #include +#include #endif /** @@ -221,6 +222,24 @@ initsyncrng(void) * */ +SEXP R_syncrng_seed(SEXP seed); +SEXP R_syncrng_rand(SEXP state); + +R_CallMethodDef callMethods[] = { + {"R_syncrng_seed", (DL_FUNC) &R_syncrng_seed, 1}, + {"R_syncrng_rand", (DL_FUNC) &R_syncrng_seed, 1}, + {NULL, NULL, 0} +}; +R_CMethodDef cMethods[] = { + {NULL, NULL, 0} +}; + +void R_init_myLib(DllInfo *info) +{ + R_registerRoutines(info, cMethods, callMethods, NULL, NULL); + R_useDynamicSymbols(info, TRUE); +} + // Set the seed for the generator from the reference class SEXP R_syncrng_seed(SEXP seed) { -- cgit v1.2.3 From c7c6d55dfb75804b119ae310e5c59ac238348665 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 15 Dec 2017 17:26:12 -0500 Subject: update version and documentation --- DESCRIPTION | 4 ++-- NAMESPACE | 3 ++- R/SyncRNG.R | 4 +++- R/syncrng-package.R | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 27 +++++++++++++++++++++----- cran-comments.md | 17 ++--------------- man/SyncRNG-class.Rd | 2 +- man/syncrng-package.Rd | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 134 insertions(+), 25 deletions(-) create mode 100644 R/syncrng-package.R create mode 100644 man/syncrng-package.Rd diff --git a/DESCRIPTION b/DESCRIPTION index be7806f..12c5191 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: SyncRNG -Version: 1.2.1 -Date: 2016-10-16 +Version: 1.3.0 +Date: 2017-12-15 Title: A Synchronized Tausworthe RNG for R and Python Author: Gertjan van den Burg Maintainer: Gertjan van den Burg diff --git a/NAMESPACE b/NAMESPACE index 160a4f2..052e9e8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,5 +2,6 @@ export(SyncRNG) exportClasses(SyncRNG) +import(methods) importFrom(methods,new) -useDynLib(SyncRNG) +useDynLib(SyncRNG, .registration = TRUE) diff --git a/R/SyncRNG.R b/R/SyncRNG.R index 95e6b3e..e7176b4 100644 --- a/R/SyncRNG.R +++ b/R/SyncRNG.R @@ -1,12 +1,14 @@ library(methods) #' A Reference Class for SyncRNG +#' +#' See \link{syncrng-package} for package documentation. #' #' @field seed The seed for the random number generator #' @field state The current state of the RNG, should not be modified by the #' user #' -#' @useDynLib SyncRNG +#' @useDynLib SyncRNG, .registration = TRUE #' @export SyncRNG #' @exportClass SyncRNG #' @importFrom methods new diff --git a/R/syncrng-package.R b/R/syncrng-package.R new file mode 100644 index 0000000..949401d --- /dev/null +++ b/R/syncrng-package.R @@ -0,0 +1,50 @@ +#' @title SyncRNG - Synchronized Random Numbers in R and Python +#' +#' @description +#' The SyncRNG package provides a random number generator implemented in C and +#' linked to both R and Python. This way, you can generate the same random +#' number sequence in both languages by using the same seed. +#' +#' The package implements a Tausworthe LSFR RNG (more details at +#' \url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast +#' pseudo-random number generator. +#' +#' @section Usage: +#' There are two ways to use this package in R. It can be used as a reference +#' class, where a SyncRNG object is used to keep the state of the generator and +#' numbers are generated using the object methods. It can also be used as a +#' user-defined random number generator using the strategy outlined in +#' .Random.user. See the examples section below. +#' +#' @author +#' Gerrit J.J. van den Burg\cr +#' Maintainer: Gerrit J.J. van den Burg +#' +#' @references +#' URL: \url{https://github.com/GjjvdBurg/SyncRNG} +#' +#' @examples +#' library(SyncRNG) +#' +#' # As user defined RNG: +#' +#' set.seed(0, 'user', 'user') +#' runif(2) +#' # [1] 3.666952e-04 6.257184e-05 +#' set.seed(0, 'user', 'user') +#' rnorm(2) +#' # [1] 0.01006027 0.42889422 +#' +#' # As class: +#' +#' s <- SyncRNG(seed=0) +#' s$rand() +#' # [1] 0.0003666952 +#' s$rand() +#' # [1] 6.257184e-05 +#' +#' @name syncrng-package +#' @docType package +#' @import methods +NULL +#>NULL diff --git a/README.md b/README.md index 08afc28..d7aa3bc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -======= SyncRNG ======= A synchronized Tausworthe RNG usable in R and Python. @@ -6,15 +5,18 @@ A synchronized Tausworthe RNG usable in R and Python. Why? ==== -This program was created because it was desired to have the same random -numbers in both R and Python programs. Although both languages implement a -Mersenne-Twister RNG, the implementations are so different that it is not -possible to get the same random numbers with the same seed. +This program was created because I needed to have the same random numbers in +both R and Python. Although both languages implement a Mersenne-Twister RNG, +the implementations are so different that it is not possible to get the same +random numbers with the same seed. SyncRNG is a Tausworthe RNG implemented in ``syncrng.c``, and linked to both R and Python. Since both use the same underlying C code, the random numbers will be the same in both languages, provided the same seed is used. +You can read more about my motivations for creating this +[here](https://gertjanvandenburg.com/blog/syncrng/). + How === @@ -38,6 +40,21 @@ Similarly, after installing the R library you can do in R:: You'll notice that the random numbers are indeed the same. +R - User defined RNG +-------------------- + +R allows the user to define a custom random number generator, which is then +used for the common ``runif`` and ``rnorm`` functions in R. This has also been +implemented in SyncRNG as of version 1.3.0. To enable this, run:: + + library(SyncRNG) + + set.seed(123456, 'user', 'user') + runif(10) + +These numbers are between [0, 1) and multiplying by ``2**32 - 1`` gives the +same results as above. + Installation ============ diff --git a/cran-comments.md b/cran-comments.md index c75610f..168c814 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,19 +1,6 @@ -## Resubmission -This is a resubmission. In this version I have: -* removed the LICENSE file -* updated the DESCRIPTION to state "License: GPL-2" - ## Test environments -* local Arch Linux install, R 3.3.1 +* local Arch Linux install, R 3.4.3 * win-builder (devel and release) ## R CMD check results -There were no ERRORs or WARNINGs. - -There was 1 NOTE: - -* checking CRAN incoming feasibility ... NOTE - Maintainer: ‘Gertjan van den Burg ’ - - New submission - +There were no ERRORs or WARNINGs or NOTEs. diff --git a/man/SyncRNG-class.Rd b/man/SyncRNG-class.Rd index 6f6d27d..7a2c69b 100644 --- a/man/SyncRNG-class.Rd +++ b/man/SyncRNG-class.Rd @@ -6,7 +6,7 @@ \alias{SyncRNG-class} \title{A Reference Class for SyncRNG} \description{ -A Reference Class for SyncRNG +See \link{syncrng-package} for package documentation. } \section{Fields}{ diff --git a/man/syncrng-package.Rd b/man/syncrng-package.Rd new file mode 100644 index 0000000..a1b3d32 --- /dev/null +++ b/man/syncrng-package.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/syncrng-package.R +\docType{package} +\name{syncrng-package} +\alias{syncrng-package} +\title{SyncRNG - Synchronized Random Numbers in R and Python} +\description{ +The SyncRNG package provides a random number generator implemented in C and +linked to both R and Python. This way, you can generate the same random +number sequence in both languages by using the same seed. + +The package implements a Tausworthe LSFR RNG (more details at +\url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast +pseudo-random number generator. +} +\section{Usage}{ + +There are two ways to use this package in R. It can be used as a reference +class, where a SyncRNG object is used to keep the state of the generator and +numbers are generated using the object methods. It can also be used as a +user-defined random number generator using the strategy outlined in +.Random.user. See the examples section below. +} +\examples{ +library(SyncRNG) + +# As user defined RNG: + +set.seed(0, 'user', 'user') +runif(2) +# [1] 3.666952e-04 6.257184e-05 +set.seed(0, 'user', 'user') +rnorm(2) +# [1] 0.01006027 0.42889422 + +# As class: + +s <- SyncRNG(seed=0) +s$rand() +# [1] 0.0003666952 +s$rand() +# [1] 6.257184e-05 + +} +\author{ +Gerrit J.J. van den Burg\cr +Maintainer: Gerrit J.J. van den Burg +} +\references{ +URL: \url{https://github.com/GjjvdBurg/SyncRNG} +} + -- cgit v1.2.3 From 629af12279a9f6244ecbcb3d0021df7bc94188a3 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Fri, 15 Dec 2017 17:41:51 -0500 Subject: merge fixes from python branch --- src/syncrng.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/syncrng.c b/src/syncrng.c index 8a0b5b4..3cc77fa 100644 --- a/src/syncrng.c +++ b/src/syncrng.c @@ -119,7 +119,8 @@ void lfsr113_seed(uint32_t seed, uint64_t **state) static PyObject *syncrng_seed(PyObject *self, PyObject *args) { - uint32_t seed, *state = NULL; + uint32_t seed; + uint64_t *state = NULL; if (!PyArg_ParseTuple(args, "k", &seed)) return NULL; @@ -134,7 +135,8 @@ static PyObject *syncrng_seed(PyObject *self, PyObject *args) static PyObject *syncrng_rand(PyObject *self, PyObject *args) { - uint32_t i, value, numints, *localstate; + uint32_t i, value, numints; + uint64_t *localstate; PyObject *listObj; PyObject *intObj; -- cgit v1.2.3 From 8f4082e9be91169a04252e77206ae15ea8554b6b Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 17 Dec 2017 09:19:11 -0500 Subject: change type of global_R_nseed to match function --- src/syncrng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/syncrng.c b/src/syncrng.c index 3cc77fa..71fe58e 100644 --- a/src/syncrng.c +++ b/src/syncrng.c @@ -298,7 +298,7 @@ SEXP R_syncrng_rand(SEXP state) */ static uint32_t global_R_seed; -static uint32_t global_R_nseed = 1; +static int global_R_nseed = 1; static double global_R_result_uniform; static double global_R_result_normal; static uint64_t *global_R_state = NULL; -- cgit v1.2.3 From 4658306bc820bc86b8c3833042f3fbc6a73c449f Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 17 Dec 2017 09:19:29 -0500 Subject: update cran-comments with the win-builder note --- cran-comments.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/cran-comments.md b/cran-comments.md index 168c814..4f984f0 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -3,4 +3,15 @@ * win-builder (devel and release) ## R CMD check results -There were no ERRORs or WARNINGs or NOTEs. +There were no ERRORs or WARNINGs. + +There was 1 NOTE: + +* checking CRAN incoming feasibility ... NOTE +Maintainer: 'Gertjan van den Burg ' + +Possibly mis-spelled words in DESCRIPTION: + RNG (4:34) + Tausworthe (4:23) + + RNG is a common abbreviation and Tausworthe is a name. -- cgit v1.2.3 From 91eff3f27b10f97b8ccef60662b2576a41f4f216 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Sun, 17 Dec 2017 09:19:56 -0500 Subject: add NEWS.md to git --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 NEWS.md diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..8b038d8 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,4 @@ +# SyncRNG 1.3.0 + +* Allows using SyncRNG as a user-supplied random number generator in R. This + enables using the functions ``runif`` and ``rnorm``. -- cgit v1.2.3 From 4214782b1e06ce8510d70cc2fc36a3b544508948 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Thu, 14 Jan 2021 17:15:44 +0000 Subject: Move R package to separate directory Rearranging repository --- DESCRIPTION | 15 - NAMESPACE | 7 - NEWS.md | 4 - R/SyncRNG.R | 76 --- R/syncrng-package.R | 50 -- cran-comments.md | 17 - man/SyncRNG-class.Rd | 38 -- man/syncrng-package.Rd | 52 -- new_R/DESCRIPTION | 15 + new_R/NAMESPACE | 7 + new_R/NEWS.md | 4 + new_R/R/SyncRNG.R | 76 +++ new_R/R/syncrng-package.R | 50 ++ new_R/cran-comments.md | 17 + new_R/man/SyncRNG-class.Rd | 38 ++ new_R/man/syncrng-package.Rd | 52 ++ new_R/src/syncrng.c | 375 +++++++++++ new_R/tests/testthat.R | 4 + new_R/tests/testthat/first_1000_seed_0.txt | 1000 ++++++++++++++++++++++++++++ new_R/tests/testthat/tests.R | 63 ++ src/syncrng.c | 375 ----------- tests/testthat.R | 4 - tests/testthat/first_1000_seed_0.txt | 1000 ---------------------------- tests/testthat/tests.R | 63 -- 24 files changed, 1701 insertions(+), 1701 deletions(-) delete mode 100644 DESCRIPTION delete mode 100644 NAMESPACE delete mode 100644 NEWS.md delete mode 100644 R/SyncRNG.R delete mode 100644 R/syncrng-package.R delete mode 100644 cran-comments.md delete mode 100644 man/SyncRNG-class.Rd delete mode 100644 man/syncrng-package.Rd create mode 100644 new_R/DESCRIPTION create mode 100644 new_R/NAMESPACE create mode 100644 new_R/NEWS.md create mode 100644 new_R/R/SyncRNG.R create mode 100644 new_R/R/syncrng-package.R create mode 100644 new_R/cran-comments.md create mode 100644 new_R/man/SyncRNG-class.Rd create mode 100644 new_R/man/syncrng-package.Rd create mode 100644 new_R/src/syncrng.c create mode 100644 new_R/tests/testthat.R create mode 100644 new_R/tests/testthat/first_1000_seed_0.txt create mode 100644 new_R/tests/testthat/tests.R delete mode 100644 src/syncrng.c delete mode 100644 tests/testthat.R delete mode 100644 tests/testthat/first_1000_seed_0.txt delete mode 100644 tests/testthat/tests.R diff --git a/DESCRIPTION b/DESCRIPTION deleted file mode 100644 index 12c5191..0000000 --- a/DESCRIPTION +++ /dev/null @@ -1,15 +0,0 @@ -Package: SyncRNG -Version: 1.3.0 -Date: 2017-12-15 -Title: A Synchronized Tausworthe RNG for R and Python -Author: Gertjan van den Burg -Maintainer: Gertjan van den Burg -Depends: - R (>= 3.0.0) -Description: Random number generation designed for cross-language usage. -License: GPL-2 -Imports: - methods -Suggests: - testthat -RoxygenNote: 5.0.1 diff --git a/NAMESPACE b/NAMESPACE deleted file mode 100644 index 052e9e8..0000000 --- a/NAMESPACE +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(SyncRNG) -exportClasses(SyncRNG) -import(methods) -importFrom(methods,new) -useDynLib(SyncRNG, .registration = TRUE) diff --git a/NEWS.md b/NEWS.md deleted file mode 100644 index 8b038d8..0000000 --- a/NEWS.md +++ /dev/null @@ -1,4 +0,0 @@ -# SyncRNG 1.3.0 - -* Allows using SyncRNG as a user-supplied random number generator in R. This - enables using the functions ``runif`` and ``rnorm``. diff --git a/R/SyncRNG.R b/R/SyncRNG.R deleted file mode 100644 index e7176b4..0000000 --- a/R/SyncRNG.R +++ /dev/null @@ -1,76 +0,0 @@ -library(methods) - -#' A Reference Class for SyncRNG -#' -#' See \link{syncrng-package} for package documentation. -#' -#' @field seed The seed for the random number generator -#' @field state The current state of the RNG, should not be modified by the -#' user -#' -#' @useDynLib SyncRNG, .registration = TRUE -#' @export SyncRNG -#' @exportClass SyncRNG -#' @importFrom methods new -#' -#' @examples -#' s <- SyncRNG(seed=123456) -#' for (i in 1:10) -#' cat(s$randi(), '\n') -#' -SyncRNG <- setRefClass('SyncRNG', - fields=list( - seed='numeric', - state='numeric' - ), - methods=list( - initialize=function(..., seed=0) { - "Initialize the RNG using the C function R_syncrng_seed" - seed <<- seed - tmp <- .Call('R_syncrng_seed', - as.numeric(seed)) - state <<- tmp[1:4] - callSuper(...) - }, - randi=function() { - "Generate a single random 32-bit integer" - tmp <- .Call('R_syncrng_rand', - as.numeric(state)) - state <<- tmp[1:4] - return(tmp[5]) - }, - rand=function() { - "Generate a single random float in the range [0, 1)" - r <- randi() - return (r * 2.3283064365387e-10) - }, - randbelow=function(n) { - "Generate a random integer below a given number" - maxsize <- 2^32 - if (n >= maxsize) { - warning(paste("Underlying random generator ", - "does not supply\n enough bits ", - "to choose from a population ", - "range this large.\n")) - return(round(rand() * n)) - } - rem <- maxsize %% n - limit <- (maxsize - rem) / maxsize - r <- rand() - while (r >= limit) - r <- rand() - return(round(r*maxsize) %% n) - }, - shuffle=function(x) { - "Randomly shuffle a provided array of values" - y <- x - for (i in rev(1:(length(y)-1))) { - j <- randbelow(i+1) - tmp <- y[i+1] - y[i+1] <- y[j+1] - y[j+1] <- tmp - } - return(y) - } - ) - ) diff --git a/R/syncrng-package.R b/R/syncrng-package.R deleted file mode 100644 index 949401d..0000000 --- a/R/syncrng-package.R +++ /dev/null @@ -1,50 +0,0 @@ -#' @title SyncRNG - Synchronized Random Numbers in R and Python -#' -#' @description -#' The SyncRNG package provides a random number generator implemented in C and -#' linked to both R and Python. This way, you can generate the same random -#' number sequence in both languages by using the same seed. -#' -#' The package implements a Tausworthe LSFR RNG (more details at -#' \url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast -#' pseudo-random number generator. -#' -#' @section Usage: -#' There are two ways to use this package in R. It can be used as a reference -#' class, where a SyncRNG object is used to keep the state of the generator and -#' numbers are generated using the object methods. It can also be used as a -#' user-defined random number generator using the strategy outlined in -#' .Random.user. See the examples section below. -#' -#' @author -#' Gerrit J.J. van den Burg\cr -#' Maintainer: Gerrit J.J. van den Burg -#' -#' @references -#' URL: \url{https://github.com/GjjvdBurg/SyncRNG} -#' -#' @examples -#' library(SyncRNG) -#' -#' # As user defined RNG: -#' -#' set.seed(0, 'user', 'user') -#' runif(2) -#' # [1] 3.666952e-04 6.257184e-05 -#' set.seed(0, 'user', 'user') -#' rnorm(2) -#' # [1] 0.01006027 0.42889422 -#' -#' # As class: -#' -#' s <- SyncRNG(seed=0) -#' s$rand() -#' # [1] 0.0003666952 -#' s$rand() -#' # [1] 6.257184e-05 -#' -#' @name syncrng-package -#' @docType package -#' @import methods -NULL -#>NULL diff --git a/cran-comments.md b/cran-comments.md deleted file mode 100644 index 4f984f0..0000000 --- a/cran-comments.md +++ /dev/null @@ -1,17 +0,0 @@ -## Test environments -* local Arch Linux install, R 3.4.3 -* win-builder (devel and release) - -## R CMD check results -There were no ERRORs or WARNINGs. - -There was 1 NOTE: - -* checking CRAN incoming feasibility ... NOTE -Maintainer: 'Gertjan van den Burg ' - -Possibly mis-spelled words in DESCRIPTION: - RNG (4:34) - Tausworthe (4:23) - - RNG is a common abbreviation and Tausworthe is a name. diff --git a/man/SyncRNG-class.Rd b/man/SyncRNG-class.Rd deleted file mode 100644 index 7a2c69b..0000000 --- a/man/SyncRNG-class.Rd +++ /dev/null @@ -1,38 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/SyncRNG.R -\docType{class} -\name{SyncRNG-class} -\alias{SyncRNG} -\alias{SyncRNG-class} -\title{A Reference Class for SyncRNG} -\description{ -See \link{syncrng-package} for package documentation. -} -\section{Fields}{ - -\describe{ -\item{\code{seed}}{The seed for the random number generator} - -\item{\code{state}}{The current state of the RNG, should not be modified by the -user} -}} -\section{Methods}{ - -\describe{ -\item{\code{initialize(..., seed = 0)}}{Initialize the RNG using the C function R_syncrng_seed} - -\item{\code{rand()}}{Generate a single random float in the range [0, 1)} - -\item{\code{randbelow(n)}}{Generate a random integer below a given number} - -\item{\code{randi()}}{Generate a single random 32-bit integer} - -\item{\code{shuffle(x)}}{Randomly shuffle a provided array of values} -}} -\examples{ -s <- SyncRNG(seed=123456) -for (i in 1:10) - cat(s$randi(), '\\n') - -} - diff --git a/man/syncrng-package.Rd b/man/syncrng-package.Rd deleted file mode 100644 index a1b3d32..0000000 --- a/man/syncrng-package.Rd +++ /dev/null @@ -1,52 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/syncrng-package.R -\docType{package} -\name{syncrng-package} -\alias{syncrng-package} -\title{SyncRNG - Synchronized Random Numbers in R and Python} -\description{ -The SyncRNG package provides a random number generator implemented in C and -linked to both R and Python. This way, you can generate the same random -number sequence in both languages by using the same seed. - -The package implements a Tausworthe LSFR RNG (more details at -\url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast -pseudo-random number generator. -} -\section{Usage}{ - -There are two ways to use this package in R. It can be used as a reference -class, where a SyncRNG object is used to keep the state of the generator and -numbers are generated using the object methods. It can also be used as a -user-defined random number generator using the strategy outlined in -.Random.user. See the examples section below. -} -\examples{ -library(SyncRNG) - -# As user defined RNG: - -set.seed(0, 'user', 'user') -runif(2) -# [1] 3.666952e-04 6.257184e-05 -set.seed(0, 'user', 'user') -rnorm(2) -# [1] 0.01006027 0.42889422 - -# As class: - -s <- SyncRNG(seed=0) -s$rand() -# [1] 0.0003666952 -s$rand() -# [1] 6.257184e-05 - -} -\author{ -Gerrit J.J. van den Burg\cr -Maintainer: Gerrit J.J. van den Burg -} -\references{ -URL: \url{https://github.com/GjjvdBurg/SyncRNG} -} - diff --git a/new_R/DESCRIPTION b/new_R/DESCRIPTION new file mode 100644 index 0000000..12c5191 --- /dev/null +++ b/new_R/DESCRIPTION @@ -0,0 +1,15 @@ +Package: SyncRNG +Version: 1.3.0 +Date: 2017-12-15 +Title: A Synchronized Tausworthe RNG for R and Python +Author: Gertjan van den Burg +Maintainer: Gertjan van den Burg +Depends: + R (>= 3.0.0) +Description: Random number generation designed for cross-language usage. +License: GPL-2 +Imports: + methods +Suggests: + testthat +RoxygenNote: 5.0.1 diff --git a/new_R/NAMESPACE b/new_R/NAMESPACE new file mode 100644 index 0000000..052e9e8 --- /dev/null +++ b/new_R/NAMESPACE @@ -0,0 +1,7 @@ +# Generated by roxygen2: do not edit by hand + +export(SyncRNG) +exportClasses(SyncRNG) +import(methods) +importFrom(methods,new) +useDynLib(SyncRNG, .registration = TRUE) diff --git a/new_R/NEWS.md b/new_R/NEWS.md new file mode 100644 index 0000000..8b038d8 --- /dev/null +++ b/new_R/NEWS.md @@ -0,0 +1,4 @@ +# SyncRNG 1.3.0 + +* Allows using SyncRNG as a user-supplied random number generator in R. This + enables using the functions ``runif`` and ``rnorm``. diff --git a/new_R/R/SyncRNG.R b/new_R/R/SyncRNG.R new file mode 100644 index 0000000..e7176b4 --- /dev/null +++ b/new_R/R/SyncRNG.R @@ -0,0 +1,76 @@ +library(methods) + +#' A Reference Class for SyncRNG +#' +#' See \link{syncrng-package} for package documentation. +#' +#' @field seed The seed for the random number generator +#' @field state The current state of the RNG, should not be modified by the +#' user +#' +#' @useDynLib SyncRNG, .registration = TRUE +#' @export SyncRNG +#' @exportClass SyncRNG +#' @importFrom methods new +#' +#' @examples +#' s <- SyncRNG(seed=123456) +#' for (i in 1:10) +#' cat(s$randi(), '\n') +#' +SyncRNG <- setRefClass('SyncRNG', + fields=list( + seed='numeric', + state='numeric' + ), + methods=list( + initialize=function(..., seed=0) { + "Initialize the RNG using the C function R_syncrng_seed" + seed <<- seed + tmp <- .Call('R_syncrng_seed', + as.numeric(seed)) + state <<- tmp[1:4] + callSuper(...) + }, + randi=function() { + "Generate a single random 32-bit integer" + tmp <- .Call('R_syncrng_rand', + as.numeric(state)) + state <<- tmp[1:4] + return(tmp[5]) + }, + rand=function() { + "Generate a single random float in the range [0, 1)" + r <- randi() + return (r * 2.3283064365387e-10) + }, + randbelow=function(n) { + "Generate a random integer below a given number" + maxsize <- 2^32 + if (n >= maxsize) { + warning(paste("Underlying random generator ", + "does not supply\n enough bits ", + "to choose from a population ", + "range this large.\n")) + return(round(rand() * n)) + } + rem <- maxsize %% n + limit <- (maxsize - rem) / maxsize + r <- rand() + while (r >= limit) + r <- rand() + return(round(r*maxsize) %% n) + }, + shuffle=function(x) { + "Randomly shuffle a provided array of values" + y <- x + for (i in rev(1:(length(y)-1))) { + j <- randbelow(i+1) + tmp <- y[i+1] + y[i+1] <- y[j+1] + y[j+1] <- tmp + } + return(y) + } + ) + ) diff --git a/new_R/R/syncrng-package.R b/new_R/R/syncrng-package.R new file mode 100644 index 0000000..949401d --- /dev/null +++ b/new_R/R/syncrng-package.R @@ -0,0 +1,50 @@ +#' @title SyncRNG - Synchronized Random Numbers in R and Python +#' +#' @description +#' The SyncRNG package provides a random number generator implemented in C and +#' linked to both R and Python. This way, you can generate the same random +#' number sequence in both languages by using the same seed. +#' +#' The package implements a Tausworthe LSFR RNG (more details at +#' \url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast +#' pseudo-random number generator. +#' +#' @section Usage: +#' There are two ways to use this package in R. It can be used as a reference +#' class, where a SyncRNG object is used to keep the state of the generator and +#' numbers are generated using the object methods. It can also be used as a +#' user-defined random number generator using the strategy outlined in +#' .Random.user. See the examples section below. +#' +#' @author +#' Gerrit J.J. van den Burg\cr +#' Maintainer: Gerrit J.J. van den Burg +#' +#' @references +#' URL: \url{https://github.com/GjjvdBurg/SyncRNG} +#' +#' @examples +#' library(SyncRNG) +#' +#' # As user defined RNG: +#' +#' set.seed(0, 'user', 'user') +#' runif(2) +#' # [1] 3.666952e-04 6.257184e-05 +#' set.seed(0, 'user', 'user') +#' rnorm(2) +#' # [1] 0.01006027 0.42889422 +#' +#' # As class: +#' +#' s <- SyncRNG(seed=0) +#' s$rand() +#' # [1] 0.0003666952 +#' s$rand() +#' # [1] 6.257184e-05 +#' +#' @name syncrng-package +#' @docType package +#' @import methods +NULL +#>NULL diff --git a/new_R/cran-comments.md b/new_R/cran-comments.md new file mode 100644 index 0000000..4f984f0 --- /dev/null +++ b/new_R/cran-comments.md @@ -0,0 +1,17 @@ +## Test environments +* local Arch Linux install, R 3.4.3 +* win-builder (devel and release) + +## R CMD check results +There were no ERRORs or WARNINGs. + +There was 1 NOTE: + +* checking CRAN incoming feasibility ... NOTE +Maintainer: 'Gertjan van den Burg ' + +Possibly mis-spelled words in DESCRIPTION: + RNG (4:34) + Tausworthe (4:23) + + RNG is a common abbreviation and Tausworthe is a name. diff --git a/new_R/man/SyncRNG-class.Rd b/new_R/man/SyncRNG-class.Rd new file mode 100644 index 0000000..7a2c69b --- /dev/null +++ b/new_R/man/SyncRNG-class.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/SyncRNG.R +\docType{class} +\name{SyncRNG-class} +\alias{SyncRNG} +\alias{SyncRNG-class} +\title{A Reference Class for SyncRNG} +\description{ +See \link{syncrng-package} for package documentation. +} +\section{Fields}{ + +\describe{ +\item{\code{seed}}{The seed for the random number generator} + +\item{\code{state}}{The current state of the RNG, should not be modified by the +user} +}} +\section{Methods}{ + +\describe{ +\item{\code{initialize(..., seed = 0)}}{Initialize the RNG using the C function R_syncrng_seed} + +\item{\code{rand()}}{Generate a single random float in the range [0, 1)} + +\item{\code{randbelow(n)}}{Generate a random integer below a given number} + +\item{\code{randi()}}{Generate a single random 32-bit integer} + +\item{\code{shuffle(x)}}{Randomly shuffle a provided array of values} +}} +\examples{ +s <- SyncRNG(seed=123456) +for (i in 1:10) + cat(s$randi(), '\\n') + +} + diff --git a/new_R/man/syncrng-package.Rd b/new_R/man/syncrng-package.Rd new file mode 100644 index 0000000..a1b3d32 --- /dev/null +++ b/new_R/man/syncrng-package.Rd @@ -0,0 +1,52 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/syncrng-package.R +\docType{package} +\name{syncrng-package} +\alias{syncrng-package} +\title{SyncRNG - Synchronized Random Numbers in R and Python} +\description{ +The SyncRNG package provides a random number generator implemented in C and +linked to both R and Python. This way, you can generate the same random +number sequence in both languages by using the same seed. + +The package implements a Tausworthe LSFR RNG (more details at +\url{https://gertjanvandenburg.com/blog/syncrng/}). This is a very fast +pseudo-random number generator. +} +\section{Usage}{ + +There are two ways to use this package in R. It can be used as a reference +class, where a SyncRNG object is used to keep the state of the generator and +numbers are generated using the object methods. It can also be used as a +user-defined random number generator using the strategy outlined in +.Random.user. See the examples section below. +} +\examples{ +library(SyncRNG) + +# As user defined RNG: + +set.seed(0, 'user', 'user') +runif(2) +# [1] 3.666952e-04 6.257184e-05 +set.seed(0, 'user', 'user') +rnorm(2) +# [1] 0.01006027 0.42889422 + +# As class: + +s <- SyncRNG(seed=0) +s$rand() +# [1] 0.0003666952 +s$rand() +# [1] 6.257184e-05 + +} +\author{ +Gerrit J.J. van den Burg\cr +Maintainer: Gerrit J.J. van den Burg +} +\references{ +URL: \url{https://github.com/GjjvdBurg/SyncRNG} +} + diff --git a/new_R/src/syncrng.c b/new_R/src/syncrng.c new file mode 100644 index 0000000..71fe58e --- /dev/null +++ b/new_R/src/syncrng.c @@ -0,0 +1,375 @@ +#ifdef TARGETPYTHON +#include "Python.h" +#include +#endif + +#ifndef TARGETPYTHON +#define STRICT_R_HEADERS +#include +#include +#include +#include +#include +#include +#include +#endif + +/** + * @brief Generate a single random number using the capped Tausworthe RNG + * + * @details + * This generates random numbers according to the process described in [1]. As + * an additional step, the resulting random number is capped to 0xFFFFFFFF + * using a bitwise and. This is done to yield the range [0, 2^32-1]. On + * return, the state variables are updated. + * + * [1]: @article{l1996maximally, + * title={Maximally equidistributed combined Tausworthe generators}, + * author={L’ecuyer, Pierre}, + * journal={Mathematics of Computation of the American Mathematical + * Society}, + * volume={65}, + * number={213}, + * pages={203--213}, + * year={1996} + * } + * + * @param[in,out] state pointer to current state array + * + * @return a generated random number + */ +uint32_t lfsr113(uint64_t **state) +{ + uint64_t z1, z2, z3, z4; + uint64_t b; + + z1 = (*state)[0]; + z2 = (*state)[1]; + z3 = (*state)[2]; + z4 = (*state)[3]; + + b = (((z1 << 6) ^ z1) >> 13); + z1 = (((z1 & 4294967294) << 18) ^ b); + + b = (((z2 << 2) ^ z2) >> 27); + z2 = (((z2 & 4294967288) << 2) ^ b); + + b = (((z3 << 13) ^ z3) >> 21); + z3 = (((z3 & 4294967280) << 7) ^ b); + + b = (((z4 << 3) ^ z4) >> 12); + z4 = (((z4 & 4294967168) << 13) ^ b); + + b = (z1 ^ z2 ^ z3 ^ z4); + + (*state)[0] = z1; + (*state)[1] = z2; + (*state)[2] = z3; + (*state)[3] = z4; + + b = b & 0xFFFFFFFF; + + return((uint32_t) b); +} + +/** + * @brief Seed the Tausworthe RNG using a seed value + * + * @details + * This function seeds the state array using a supplied seed value. As noted + * in [1] (see lfsr113()), the values of z1, z2, z3, and z4 should be larger + * than 1, 7, 15, and 127 respectively. + * + * @param[in] seed user supplied seed value for the RNG + * @param[out] state state of the RNG + */ +void lfsr113_seed(uint32_t seed, uint64_t **state) +{ + uint64_t z1 = 2, + z2 = 8, + z3 = 16, + z4 = 128; + + z1 = (z1 * (seed + 1)); + z2 = (z2 * (seed + 1)); + z3 = (z3 * (seed + 1)); + z4 = (z4 * (seed + 1)); + + z1 = (z1 > 1) ? z1 : z1 + 1; + z2 = (z2 > 7) ? z2 : z2 + 7; + z3 = (z3 > 15) ? z3 : z3 + 15; + z4 = (z4 > 127) ? z4 : z4 + 127; + + if (*state == NULL) { + (*state) = malloc(sizeof(uint64_t)*4); + } + + (*state)[0] = z1; + (*state)[1] = z2; + (*state)[2] = z3; + (*state)[3] = z4; +} + +#ifdef TARGETPYTHON +/* + * + * Start of Python code + * + */ + +static PyObject *syncrng_seed(PyObject *self, PyObject *args) +{ + uint32_t seed; + uint64_t *state = NULL; + + if (!PyArg_ParseTuple(args, "k", &seed)) + return NULL; + + lfsr113_seed(seed, &state); + + PyObject *pystate = Py_BuildValue("[k, k, k, k]", + state[0], state[1], state[2], state[3]); + free(state); + return pystate; +} + +static PyObject *syncrng_rand(PyObject *self, PyObject *args) +{ + uint32_t i, value, numints; + uint64_t *localstate; + + PyObject *listObj; + PyObject *intObj; + + if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &listObj)) + return NULL; + + // we're just assuming you would never pass more than 4 values + localstate = malloc(sizeof(uint32_t)*5); + numints = PyList_Size(listObj); + for (i=0; i= 3 + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "syncrng", + "Python interface to SyncRNG", + -1, + SyncRNGMethods, + NULL, + NULL, + NULL, + NULL + }; +#endif + + +static PyObject * +moduleinit(void) +{ + PyObject *m; + + #if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); + #else + m = Py_InitModule3("syncrng", SyncRNGMethods, + "Python interface to SyncRNG"); + #endif + + return m; +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC +PyInit_syncrng(void) +{ + return moduleinit(); +} +#else +PyMODINIT_FUNC +initsyncrng(void) +{ + moduleinit(); +} +#endif +#endif + +#ifndef TARGETPYTHON + +/* + * + * Start of R code + * + */ + +SEXP R_syncrng_seed(SEXP seed); +SEXP R_syncrng_rand(SEXP state); + +R_CallMethodDef callMethods[] = { + {"R_syncrng_seed", (DL_FUNC) &R_syncrng_seed, 1}, + {"R_syncrng_rand", (DL_FUNC) &R_syncrng_seed, 1}, + {NULL, NULL, 0} +}; +R_CMethodDef cMethods[] = { + {NULL, NULL, 0} +}; + +void R_init_myLib(DllInfo *info) +{ + R_registerRoutines(info, cMethods, callMethods, NULL, NULL); + R_useDynamicSymbols(info, TRUE); +} + +// Set the seed for the generator from the reference class +SEXP R_syncrng_seed(SEXP seed) +{ + int i; + double *pseed = REAL(seed), + *pstate = NULL; + uint32_t useed = (uint32_t) *pseed; + uint64_t *state = NULL; + + lfsr113_seed(useed, &state); + + SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); + pstate = REAL(Rstate); + for (i=0; i<4; i++) { + pstate[i] = (double) state[i]; + } + pstate[4] = -1.0; + free(state); + + UNPROTECT(1); + return Rstate; +} + +// get a random number from the reference class +SEXP R_syncrng_rand(SEXP state) +{ + uint64_t *localstate = malloc(sizeof(uint64_t)*4); + double *pstate = REAL(state); + int i; + for (i=0; i<4; i++) { + localstate[i] = (uint64_t) pstate[i]; + } + + uint32_t rand = lfsr113(&localstate); + + SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); + pstate = REAL(Rstate); + + for (i=0; i<4; i++) { + pstate[i] = (double) localstate[i]; + } + pstate[4] = (double) rand; + UNPROTECT(1); + + free(localstate); + + return Rstate; +} + +/* + * The following code is used to make SyncRNG a real "user-defined" RNG + * follwing .Random.user documentation. + * + */ + +static uint32_t global_R_seed; +static int global_R_nseed = 1; +static double global_R_result_uniform; +static double global_R_result_normal; +static uint64_t *global_R_state = NULL; + +double *user_unif_rand() +{ + if (global_R_state == NULL) { + // if it's not seeded yet we seed it with 0 + global_R_seed = 0; + lfsr113_seed(global_R_seed, &global_R_state); + } + + uint32_t rand = lfsr113(&global_R_state); + global_R_result_uniform = rand * 2.3283064365387e-10; + return &global_R_result_uniform; +} + +// see: https://stackoverflow.com/q/47824450/1154005 +Int32 _unscramble(Int32 scram) +{ + int j; + for (j=0; j<50; j++) { + scram = ((scram - 1) * 2783094533); + } + return scram; +} + +// note that Int32 is "unsigned int" which is not necessarily 32 bit +void user_unif_init(Int32 seed_in) +{ + global_R_seed = seed_in; + uint32_t useed = _unscramble(seed_in); + + // destroy the previous state, we're reseeding the RNG + if (global_R_state != NULL) { + free(global_R_state); + global_R_state = NULL; + } + lfsr113_seed(useed, &global_R_state); +} + +int *user_unif_nseed() +{ + return &global_R_nseed; +} + +int *user_unif_seedloc() +{ + return (int *) &global_R_seed; +} + +double *user_norm_rand() +{ + double u, v, z, x; + do { + u = *user_unif_rand(); + v = 0.857764 * (2. * (*user_unif_rand()) - 1); + x = v/u; + z = 0.25 * x * x; + if (z < 1. - u) + break; + if (z > 0.259/u + 0.35) + continue; + } while (z > -log(u)); + global_R_result_normal = x; + return &global_R_result_normal; +} + +/* + * + * End of R code + * + */ +#endif diff --git a/new_R/tests/testthat.R b/new_R/tests/testthat.R new file mode 100644 index 0000000..b1f5cc8 --- /dev/null +++ b/new_R/tests/testthat.R @@ -0,0 +1,4 @@ +library(testthat) +library(SyncRNG) + +test_check("SyncRNG") diff --git a/new_R/tests/testthat/first_1000_seed_0.txt b/new_R/tests/testthat/first_1000_seed_0.txt new file mode 100644 index 0000000..50aef45 --- /dev/null +++ b/new_R/tests/testthat/first_1000_seed_0.txt @@ -0,0 +1,1000 @@ +1574944 +268744 +33556004 +8390676 +16851968 +2147582472 +134350084 +1074315269 +2097666 +2693283843 +50598144 +402792448 +536872117 +2281705500 +2097216 +67127296 +1192 +4097 +413712 +68096 +537198610 +9502976 +1077936653 +23069188 +256 +271065282 +1375735819 +1075056808 +137344 +537396752 +71370760 +134520872 +3196164 +24836 +2164785857 +2183397387 +269344 +41977872 +943785105 +2195975 +2283815708 +3170454 +68182051 +2281710785 +34344960 +1074024480 +460824 +839122944 +7438364 +155238412 +2166440334 +67126401 +3489693830 +1124336267 +537284650 +8392144 +805381657 +2165408 +29452 +2146516 +33704323 +2148282537 +19138624 +1619267616 +33754640 +671155715 +549519625 +3422584857 +7889684 +12289 +3223323809 +302387200 +1334448 +12654616 +940410368 +69321472 +205808168 +2167956679 +422150 +3506449091 +3263561808 +1350900792 +6425240 +809550976 +543263112 +203481359 +2146694 +1196512 +3355967617 +61734977 +8853552 +46403088 +704741917 +540082961 +2365612954 +2149671132 +117458370 +2147925124 +59121344 +1342640170 +4362072 +805610753 +5308846 +37785610 +20730196 +28992 +2952790235 +1082458123 +466480 +10487956 +1006651158 +11135872 +1241543311 +3229405863 +84162883 +2687116417 +308610137 +1217697952 +34756884 +940057617 +2757853260 +2281750584 +2117046 +8536213 +2432762497 +2200211979 +143004704 +9555090 +541402267 +2688090691 +140792396 +18901124 +34619827 +2281975939 +1126991882 +1611028540 +1510426 +570433665 +4261976 +201367560 +2151409932 +159745 +2416476396 +36078209 +545545526 +47188314 +570525328 +540398565 +2231400988 +2688182423 +359426 +3489672937 +10915924 +1409751076 +8104090 +805697154 +1089569002 +1296220170 +23228310 +71304648 +3357573835 +1402388746 +68628924 +2161655515 +571323533 +1144329024 +226905022 +807660740 +123848654 +3507419777 +2206633420 +1879528495 +39521946 +675329344 +4260201 +2342551838 +4160788 +1080928 +2952791293 +42848321 +350126 +2159872543 +1023504852 +4190932 +171990682 +1631541431 +19363907 +3758286790 +1113949782 +1845794863 +948310 +536886913 +3764488345 +17297420 +2279406 +81939869 +2349451169 +18637697 +243556660 +3263987441 +705043609 +3232571140 +3385285445 +946061980 +106022815 +2149881281 +2466519302 +1645367474 +918576 +546053696 +877659196 +216334888 +154739468 +70398851 +3707790308 +1107714240 +41949434 +3234631865 +960994496 +271830786 +205637392 +2285371587 +68563108 +3355977792 +2192441361 +1367412784 +40143408 +981517841 +543196563 +2367734299 +2283872410 +1344 +2181071879 +2206859904 +553846898 +549654344 +805609997 +2163104 +71332746 +86007956 +117991874 +3490064554 +25562218 +1879511088 +4425864 +541165322 +146901518 +1242620175 +75297540 +2148145409 +2687242416 +1386547200 +1515192 +312547844 +879347469 +606675077 +2315539260 +3292288180 +84170823 +2701271680 +3259307090 +1208409120 +1231108 +805578376 +2691760719 +141869068 +86001956 +76571121 +2298545346 +53381707 +142892072 +278219778 +574726163 +2150205781 +151286350 +2250360974 +101086355 +3490494661 +1661242064 +1074073654 +34738122 +945816717 +608289773 +2232988060 +104487366 +1141132385 +3506572416 +1610914817 +12933420 +416320010 +980706718 +10825792 +3443551182 +2776525524 +335138 +3231722194 +44532831 +1421335228 +142342666 +811120154 +1147218925 +2367611246 +69654868 +4222348 +3624435928 +3551840523 +77967668 +2463755847 +706032790 +1077262534 +2376231880 +925059286 +125304554 +3624333504 +1940823454 +1887737903 +6262158 +578073551 +106029822 +182235594 +2252236174 +1678131760 +3909323963 +847760523 +552000424 +2629422019 +795718747 +3090656 +3271585593 +3845708012 +19353971 +2966053808 +1212416724 +1312070453 +235870850 +3091824202 +3269792698 +152819996 +98860412 +820192477 +2369799568 +1396620160 +244589602 +3498863850 +574856834 +3829239105 +159603286 +1067697294 +39236251 +2432997826 +721684755 +1644254266 +955946 +2695372509 +356835194 +211485320 +238662558 +1076233167 +3307891111 +3794546048 +37949562 +3637088288 +863193421 +271789329 +761391063 +205299928 +67378860 +2158013456 +3599194065 +1907079858 +174119784 +1624289467 +7483173 +2759382862 +224727064 +134258952 +3543155069 +2441640202 +2174979241 +851922069 +542448292 +3253137 +2080458461 +54616262 +252468170 +3223217159 +665218426 +4028018793 +4626772 +1748803383 +709060767 +3121149182 +56479134 +3893141625 +2686933815 +2995214218 +2162482869 +262490641 +1011561522 +549060114 +3932247987 +3223024295 +152321631 +3101843551 +1280099225 +3358647209 +252846296 +3524154097 +2187760847 +3909680653 +2179387890 +1015137433 +3494929304 +50606464 +3901100357 +9850320 +940382251 +2699631292 +3087385960 +9538500 +234958491 +272389742 +220260678 +2684647653 +43257408 +4027072178 +28810004 +2101495309 +18607774 +134280454 +3223347501 +1376157898 +3222543805 +22419610 +973776048 +83221848 +218483748 +2685071319 +134550656 +3506980865 +2173075612 +2483766325 +66860762 +138671625 +1075841013 +2367832091 +2247808 +38814954 +3490485897 +60737793 +604469508 +2153524819 +536917141 +1074075984 +12724890 +2972321868 +23188040 +1074423975 +1117820684 +1879381029 +1739586 +939530176 +5327050 +58757130 +2151669013 +67532608 +3087534325 +2474001 +277224382 +2191034903 +1057240535 +549434183 +3405807240 +1618369262 +86191107 +2955045761 +308647117 +1578408101 +3139990 +806116500 +3831595195 +155443373 +19022846 +98715033 +2634272139 +3275515777 +512124196 +3230432369 +575086366 +3225228801 +199711444 +942108876 +121867967 +2819529105 +2200767815 +1921129010 +36410428 +780163669 +274212015 +2376151708 +3359123316 +20068231 +2349001203 +2185655880 +973119224 +3235762297 +755212101 +2956716003 +103138961 +3376199891 +92680340 +3758301290 +3236398675 +1090770984 +4196670 +813793301 +16288768 +1277219531 +140550882 +25313600 +3257601090 +2477397505 +429066492 +583196168 +671646619 +2754150662 +2399163262 +69629076 +101346518 +3775145624 +3282507882 +1619334952 +6457996 +637846925 +676180878 +175175818 +1698451828 +2233162017 +3087408874 +49089607 +478663992 +280881932 +945942552 +3224705271 +151407497 +607767788 +80172123 +3624479885 +1110753748 +2013690146 +2184431875 +709117454 +2692553290 +2157242825 +874605844 +86108881 +2567065312 +1092017287 +344356159 +2425400907 +574662615 +1084594274 +1262643867 +929455814 +56999307 +2821124246 +858115549 +1888834109 +2150800911 +627861145 +6024170 +228373816 +1178327534 +1093027685 +3624421308 +3798255747 +449290167 +2597181707 +926243929 +2687439124 +254107214 +3829027460 +93803542 +3968018064 +1388720668 +1151812149 +1214147364 +844558349 +1080633195 +2350576007 +2368200508 +97528200 +2365796063 +2476535242 +1017242931 +3503925127 +852957056 +3492589682 +115795988 +925186774 +40237656 +4094491891 +1906813406 +1611043710 +1115295490 +787740617 +652006269 +3420228435 +1736435170 +1628768048 +3173066342 +1659370060 +502667371 +3701617539 +971219790 +3559002171 +3372410256 +2218574844 +14962797 +2680285584 +2318530008 +1580611180 +3962509653 +2995731663 +3262644231 +3386622672 +832903192 +826852989 +2339061594 +52616487 +319161836 +848007203 +713596765 +405804387 +2343674302 +2393126614 +2268412740 +3959609298 +3943003701 +1375818464 +3492713455 +3041590872 +1028634474 +69944722 +1329116577 +3238922414 +3508802651 +2688827650 +432118456 +181619625 +1020588554 +2158511183 +3996414429 +3430521601 +92558330 +4085981271 +3335052120 +1094411888 +943803286 +2019381420 +612050958 +739046845 +40203708 +160356556 +3241366485 +3011934011 +2552681725 +46401557 +544316860 +2897832596 +1064122014 +34062854 +3390969819 +4180831325 +2007854337 +3762749433 +174296912 +1678023203 +39792904 +3137637515 +3780663668 +688110716 +3769355130 +46416140 +3162873767 +230484689 +571417648 +3770011349 +1611628070 +2703187687 +147275591 +2556554365 +236196063 +3627157681 +2268570387 +3524220149 +2196407803 +683730648 +832718794 +958399385 +2289805767 +1393849733 +3560321216 +2190933457 +570506109 +1190464059 +855891340 +815207364 +727755671 +959944786 +2399256258 +2955296368 +2226474309 +4248919733 +54373041 +4255540140 +1079558374 +758297126 +3494062195 +172905473 +3660879546 +2169485331 +3171064613 +2734421278 +239124661 +1636792719 +1032199552 +3022143494 +1238328860 +2755367096 +1172068287 +2416030799 +1111231360 +1162238438 +136341168 +936511690 +3697688233 +2310946572 +1017208991 +3260655066 +2861019521 +4085782611 +3269494883 +820892676 +610312130 +873064187 +444719755 +1077221226 +1178295173 +2928297301 +123238584 +1803717266 +3778860833 +622164036 +2906858569 +3462751317 +230473195 +3229782038 +4056351409 +4062480954 +157481248 +15888294 +1022616105 +2251826379 +236458376 +3468433827 +3859679691 +4169609282 +3270154816 +3638739572 +3024095882 +811148317 +3261183116 +1325974504 +589588966 +546263216 +4039391440 +1001817745 +16154680 +165750980 +2788265304 +2620478124 +3439592229 +1654681662 +3608040307 +3777078995 +994394444 +1014396095 +138120475 +2685072838 +3228373358 +2552662027 +28069284 +314728824 +2426995424 +649430792 +2352053910 +2291666758 +940013010 +3257519298 +143153873 +2445086935 +895972163 +2420598353 +573867732 +1148475689 +120727570 +874272160 +1499568331 +730384503 +2381214 +272910609 +2992637073 +253053713 +84832812 +2226240734 +3876274424 +18983620 +1268799900 +1348803766 +205671635 +2826229385 +660957935 +1646191083 +103509332 +1678012033 +2713914564 +2105972745 +14594356 +278969605 +3966027377 +46113154 +1246514745 +3316402942 +990363635 +2962749314 +524577371 +3903648383 +202779778 +3762835161 +2261224091 +3692935449 +90068990 +813864789 +3496510266 +3456387596 +143015350 +315738178 +4026606747 +2176794694 +2351395438 +2264420045 +68273726 +3627034496 +1856958854 +1350988020 +58099784 +4067096716 +100097690 +1012654471 +2271403796 +1141174688 +2164427209 +562335369 +549995830 +416389002 +309413793 +11860448 +2231458885 +604433027 +251864294 +3498465912 +1401395398 +3022766621 +190641354 +139719433 +1619043956 +1125777754 +74067650 +4207624 +958432937 +1116985600 +79164300 +2419620443 +777581327 +1142807361 +63314936 +4130282535 +23324492 +554363587 +2992739718 +1208439855 +772634 +540021839 +2789338031 +163090632 +120839590 +1620336448 +2164918412 +1913539649 +141022634 +2660075661 +963507036 +2687451280 +1208246255 +2771730565 +69420323 +3233866653 +1241879628 +1723226915 +202266692 +2689359561 +1651839518 +3227502861 +78020380 +811821517 +2640397810 +18786699 +109454782 +3498917610 +542022675 +1621201984 +1220764211 +518079134 +106428047 +2150406528 +4213442838 +1712410802 +33957546 +2833255501 +1363466077 +2361205692 +238621598 +1081475811 +3290623399 +1645509834 +105086074 +1522806889 +959667661 +1344480514 +2894325459 +2637988048 +7641220 +3634424343 +2525971609 +1437315771 +174455456 +1926534907 +1080174481 +2914707278 +2355466320 +138587648 +2201502550 +3552082560 +2770463793 +818376469 +961820903 +1622385204 +3028513484 +318825118 +189698242 +3224822639 +898006137 +4135907579 +37993300 +1613862757 +1859348874 +2060448975 +35441046 +3966690161 +3037175409 +1654613515 +2255792831 +1335945969 +1023753955 +1688992272 +3938874011 +3642382007 +225770871 +2716500061 +207929882 +3426021282 +219580528 +3637400609 +3530004700 +1753898265 +166081018 +1019445811 +2555921818 +2201231873 +3422693765 +43214040 +587807866 +3506115085 +837243260 +2442251152 +240230417 +1077703104 +1327561358 +2265348349 diff --git a/new_R/tests/testthat/tests.R b/new_R/tests/testthat/tests.R new file mode 100644 index 0000000..59dc004 --- /dev/null +++ b/new_R/tests/testthat/tests.R @@ -0,0 +1,63 @@ +library(SyncRNG) +context("SyncRNG unit tests") + +test_that("test_randi", { + s <- SyncRNG(seed=123456) + expect_equal(s$randi(), 959852049) + expect_equal(s$randi(), 2314333085) + expect_equal(s$randi(), 2255782734) + expect_equal(s$randi(), 2921461239) + expect_equal(s$randi(), 1024197102) +}) + +test_that("test_rand", { + s <- SyncRNG(seed=123456) + expect_equal(s$rand(), 959852049 /(2**32)) + expect_equal(s$rand(), 2314333085/(2**32)) + expect_equal(s$rand(), 2255782734/(2**32)) + expect_equal(s$rand(), 2921461239/(2**32)) + expect_equal(s$rand(), 1024197102/(2**32)) +}) + +test_that("test_randbelow", { + s <- SyncRNG(seed=123456) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 0) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 4) + expect_equal(s$randbelow(5), 2) +}) + +test_that("test_shuffle", { + s <- SyncRNG(seed=123456) + x <- c(1, 2, 3, 4, 5) + y <- s$shuffle(x) + expect_equal(y, c(3, 4, 1, 2, 5)) +}) + +test_that("test_first_1000", { + s <- SyncRNG(seed=0) + fileName <- "./first_1000_seed_0.txt" + conn <- file(fileName, open="r") + linn <- readLines(conn) + for (i in 1:length(linn)) { + exp <- as.numeric(linn[i]) + expect_equal(exp, s$randi()) + } + close(conn) +}) + +printf <- function(...) invisible(cat(sprintf(...))); + +test_that("test_first_1000_unif", { + set.seed(0, 'user', 'user') + fileName <- "./first_1000_seed_0.txt" + conn <- file(fileName, open="r") + linn <- readLines(conn) + for (i in 1:length(linn)) { + exp <- as.numeric(linn[i]) + u <- as.numeric(runif(1)*(2**32 - 1)) + expect_equal(exp, u) + } + close(conn) +}) diff --git a/src/syncrng.c b/src/syncrng.c deleted file mode 100644 index 71fe58e..0000000 --- a/src/syncrng.c +++ /dev/null @@ -1,375 +0,0 @@ -#ifdef TARGETPYTHON -#include "Python.h" -#include -#endif - -#ifndef TARGETPYTHON -#define STRICT_R_HEADERS -#include -#include -#include -#include -#include -#include -#include -#endif - -/** - * @brief Generate a single random number using the capped Tausworthe RNG - * - * @details - * This generates random numbers according to the process described in [1]. As - * an additional step, the resulting random number is capped to 0xFFFFFFFF - * using a bitwise and. This is done to yield the range [0, 2^32-1]. On - * return, the state variables are updated. - * - * [1]: @article{l1996maximally, - * title={Maximally equidistributed combined Tausworthe generators}, - * author={L’ecuyer, Pierre}, - * journal={Mathematics of Computation of the American Mathematical - * Society}, - * volume={65}, - * number={213}, - * pages={203--213}, - * year={1996} - * } - * - * @param[in,out] state pointer to current state array - * - * @return a generated random number - */ -uint32_t lfsr113(uint64_t **state) -{ - uint64_t z1, z2, z3, z4; - uint64_t b; - - z1 = (*state)[0]; - z2 = (*state)[1]; - z3 = (*state)[2]; - z4 = (*state)[3]; - - b = (((z1 << 6) ^ z1) >> 13); - z1 = (((z1 & 4294967294) << 18) ^ b); - - b = (((z2 << 2) ^ z2) >> 27); - z2 = (((z2 & 4294967288) << 2) ^ b); - - b = (((z3 << 13) ^ z3) >> 21); - z3 = (((z3 & 4294967280) << 7) ^ b); - - b = (((z4 << 3) ^ z4) >> 12); - z4 = (((z4 & 4294967168) << 13) ^ b); - - b = (z1 ^ z2 ^ z3 ^ z4); - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; - - b = b & 0xFFFFFFFF; - - return((uint32_t) b); -} - -/** - * @brief Seed the Tausworthe RNG using a seed value - * - * @details - * This function seeds the state array using a supplied seed value. As noted - * in [1] (see lfsr113()), the values of z1, z2, z3, and z4 should be larger - * than 1, 7, 15, and 127 respectively. - * - * @param[in] seed user supplied seed value for the RNG - * @param[out] state state of the RNG - */ -void lfsr113_seed(uint32_t seed, uint64_t **state) -{ - uint64_t z1 = 2, - z2 = 8, - z3 = 16, - z4 = 128; - - z1 = (z1 * (seed + 1)); - z2 = (z2 * (seed + 1)); - z3 = (z3 * (seed + 1)); - z4 = (z4 * (seed + 1)); - - z1 = (z1 > 1) ? z1 : z1 + 1; - z2 = (z2 > 7) ? z2 : z2 + 7; - z3 = (z3 > 15) ? z3 : z3 + 15; - z4 = (z4 > 127) ? z4 : z4 + 127; - - if (*state == NULL) { - (*state) = malloc(sizeof(uint64_t)*4); - } - - (*state)[0] = z1; - (*state)[1] = z2; - (*state)[2] = z3; - (*state)[3] = z4; -} - -#ifdef TARGETPYTHON -/* - * - * Start of Python code - * - */ - -static PyObject *syncrng_seed(PyObject *self, PyObject *args) -{ - uint32_t seed; - uint64_t *state = NULL; - - if (!PyArg_ParseTuple(args, "k", &seed)) - return NULL; - - lfsr113_seed(seed, &state); - - PyObject *pystate = Py_BuildValue("[k, k, k, k]", - state[0], state[1], state[2], state[3]); - free(state); - return pystate; -} - -static PyObject *syncrng_rand(PyObject *self, PyObject *args) -{ - uint32_t i, value, numints; - uint64_t *localstate; - - PyObject *listObj; - PyObject *intObj; - - if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &listObj)) - return NULL; - - // we're just assuming you would never pass more than 4 values - localstate = malloc(sizeof(uint32_t)*5); - numints = PyList_Size(listObj); - for (i=0; i= 3 - static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "syncrng", - "Python interface to SyncRNG", - -1, - SyncRNGMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - - -static PyObject * -moduleinit(void) -{ - PyObject *m; - - #if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); - #else - m = Py_InitModule3("syncrng", SyncRNGMethods, - "Python interface to SyncRNG"); - #endif - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC -PyInit_syncrng(void) -{ - return moduleinit(); -} -#else -PyMODINIT_FUNC -initsyncrng(void) -{ - moduleinit(); -} -#endif -#endif - -#ifndef TARGETPYTHON - -/* - * - * Start of R code - * - */ - -SEXP R_syncrng_seed(SEXP seed); -SEXP R_syncrng_rand(SEXP state); - -R_CallMethodDef callMethods[] = { - {"R_syncrng_seed", (DL_FUNC) &R_syncrng_seed, 1}, - {"R_syncrng_rand", (DL_FUNC) &R_syncrng_seed, 1}, - {NULL, NULL, 0} -}; -R_CMethodDef cMethods[] = { - {NULL, NULL, 0} -}; - -void R_init_myLib(DllInfo *info) -{ - R_registerRoutines(info, cMethods, callMethods, NULL, NULL); - R_useDynamicSymbols(info, TRUE); -} - -// Set the seed for the generator from the reference class -SEXP R_syncrng_seed(SEXP seed) -{ - int i; - double *pseed = REAL(seed), - *pstate = NULL; - uint32_t useed = (uint32_t) *pseed; - uint64_t *state = NULL; - - lfsr113_seed(useed, &state); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - for (i=0; i<4; i++) { - pstate[i] = (double) state[i]; - } - pstate[4] = -1.0; - free(state); - - UNPROTECT(1); - return Rstate; -} - -// get a random number from the reference class -SEXP R_syncrng_rand(SEXP state) -{ - uint64_t *localstate = malloc(sizeof(uint64_t)*4); - double *pstate = REAL(state); - int i; - for (i=0; i<4; i++) { - localstate[i] = (uint64_t) pstate[i]; - } - - uint32_t rand = lfsr113(&localstate); - - SEXP Rstate = PROTECT(allocVector(REALSXP, 5)); - pstate = REAL(Rstate); - - for (i=0; i<4; i++) { - pstate[i] = (double) localstate[i]; - } - pstate[4] = (double) rand; - UNPROTECT(1); - - free(localstate); - - return Rstate; -} - -/* - * The following code is used to make SyncRNG a real "user-defined" RNG - * follwing .Random.user documentation. - * - */ - -static uint32_t global_R_seed; -static int global_R_nseed = 1; -static double global_R_result_uniform; -static double global_R_result_normal; -static uint64_t *global_R_state = NULL; - -double *user_unif_rand() -{ - if (global_R_state == NULL) { - // if it's not seeded yet we seed it with 0 - global_R_seed = 0; - lfsr113_seed(global_R_seed, &global_R_state); - } - - uint32_t rand = lfsr113(&global_R_state); - global_R_result_uniform = rand * 2.3283064365387e-10; - return &global_R_result_uniform; -} - -// see: https://stackoverflow.com/q/47824450/1154005 -Int32 _unscramble(Int32 scram) -{ - int j; - for (j=0; j<50; j++) { - scram = ((scram - 1) * 2783094533); - } - return scram; -} - -// note that Int32 is "unsigned int" which is not necessarily 32 bit -void user_unif_init(Int32 seed_in) -{ - global_R_seed = seed_in; - uint32_t useed = _unscramble(seed_in); - - // destroy the previous state, we're reseeding the RNG - if (global_R_state != NULL) { - free(global_R_state); - global_R_state = NULL; - } - lfsr113_seed(useed, &global_R_state); -} - -int *user_unif_nseed() -{ - return &global_R_nseed; -} - -int *user_unif_seedloc() -{ - return (int *) &global_R_seed; -} - -double *user_norm_rand() -{ - double u, v, z, x; - do { - u = *user_unif_rand(); - v = 0.857764 * (2. * (*user_unif_rand()) - 1); - x = v/u; - z = 0.25 * x * x; - if (z < 1. - u) - break; - if (z > 0.259/u + 0.35) - continue; - } while (z > -log(u)); - global_R_result_normal = x; - return &global_R_result_normal; -} - -/* - * - * End of R code - * - */ -#endif diff --git a/tests/testthat.R b/tests/testthat.R deleted file mode 100644 index b1f5cc8..0000000 --- a/tests/testthat.R +++ /dev/null @@ -1,4 +0,0 @@ -library(testthat) -library(SyncRNG) - -test_check("SyncRNG") diff --git a/tests/testthat/first_1000_seed_0.txt b/tests/testthat/first_1000_seed_0.txt deleted file mode 100644 index 50aef45..0000000 --- a/tests/testthat/first_1000_seed_0.txt +++ /dev/null @@ -1,1000 +0,0 @@ -1574944 -268744 -33556004 -8390676 -16851968 -2147582472 -134350084 -1074315269 -2097666 -2693283843 -50598144 -402792448 -536872117 -2281705500 -2097216 -67127296 -1192 -4097 -413712 -68096 -537198610 -9502976 -1077936653 -23069188 -256 -271065282 -1375735819 -1075056808 -137344 -537396752 -71370760 -134520872 -3196164 -24836 -2164785857 -2183397387 -269344 -41977872 -943785105 -2195975 -2283815708 -3170454 -68182051 -2281710785 -34344960 -1074024480 -460824 -839122944 -7438364 -155238412 -2166440334 -67126401 -3489693830 -1124336267 -537284650 -8392144 -805381657 -2165408 -29452 -2146516 -33704323 -2148282537 -19138624 -1619267616 -33754640 -671155715 -549519625 -3422584857 -7889684 -12289 -3223323809 -302387200 -1334448 -12654616 -940410368 -69321472 -205808168 -2167956679 -422150 -3506449091 -3263561808 -1350900792 -6425240 -809550976 -543263112 -203481359 -2146694 -1196512 -3355967617 -61734977 -8853552 -46403088 -704741917 -540082961 -2365612954 -2149671132 -117458370 -2147925124 -59121344 -1342640170 -4362072 -805610753 -5308846 -37785610 -20730196 -28992 -2952790235 -1082458123 -466480 -10487956 -1006651158 -11135872 -1241543311 -3229405863 -84162883 -2687116417 -308610137 -1217697952 -34756884 -940057617 -2757853260 -2281750584 -2117046 -8536213 -2432762497 -2200211979 -143004704 -9555090 -541402267 -2688090691 -140792396 -18901124 -34619827 -2281975939 -1126991882 -1611028540 -1510426 -570433665 -4261976 -201367560 -2151409932 -159745 -2416476396 -36078209 -545545526 -47188314 -570525328 -540398565 -2231400988 -2688182423 -359426 -3489672937 -10915924 -1409751076 -8104090 -805697154 -1089569002 -1296220170 -23228310 -71304648 -3357573835 -1402388746 -68628924 -2161655515 -571323533 -1144329024 -226905022 -807660740 -123848654 -3507419777 -2206633420 -1879528495 -39521946 -675329344 -4260201 -2342551838 -4160788 -1080928 -2952791293 -42848321 -350126 -2159872543 -1023504852 -4190932 -171990682 -1631541431 -19363907 -3758286790 -1113949782 -1845794863 -948310 -536886913 -3764488345 -17297420 -2279406 -81939869 -2349451169 -18637697 -243556660 -3263987441 -705043609 -3232571140 -3385285445 -946061980 -106022815 -2149881281 -2466519302 -1645367474 -918576 -546053696 -877659196 -216334888 -154739468 -70398851 -3707790308 -1107714240 -41949434 -3234631865 -960994496 -271830786 -205637392 -2285371587 -68563108 -3355977792 -2192441361 -1367412784 -40143408 -981517841 -543196563 -2367734299 -2283872410 -1344 -2181071879 -2206859904 -553846898 -549654344 -805609997 -2163104 -71332746 -86007956 -117991874 -3490064554 -25562218 -1879511088 -4425864 -541165322 -146901518 -1242620175 -75297540 -2148145409 -2687242416 -1386547200 -1515192 -312547844 -879347469 -606675077 -2315539260 -3292288180 -84170823 -2701271680 -3259307090 -1208409120 -1231108 -805578376 -2691760719 -141869068 -86001956 -76571121 -2298545346 -53381707 -142892072 -278219778 -574726163 -2150205781 -151286350 -2250360974 -101086355 -3490494661 -1661242064 -1074073654 -34738122 -945816717 -608289773 -2232988060 -104487366 -1141132385 -3506572416 -1610914817 -12933420 -416320010 -980706718 -10825792 -3443551182 -2776525524 -335138 -3231722194 -44532831 -1421335228 -142342666 -811120154 -1147218925 -2367611246 -69654868 -4222348 -3624435928 -3551840523 -77967668 -2463755847 -706032790 -1077262534 -2376231880 -925059286 -125304554 -3624333504 -1940823454 -1887737903 -6262158 -578073551 -106029822 -182235594 -2252236174 -1678131760 -3909323963 -847760523 -552000424 -2629422019 -795718747 -3090656 -3271585593 -3845708012 -19353971 -2966053808 -1212416724 -1312070453 -235870850 -3091824202 -3269792698 -152819996 -98860412 -820192477 -2369799568 -1396620160 -244589602 -3498863850 -574856834 -3829239105 -159603286 -1067697294 -39236251 -2432997826 -721684755 -1644254266 -955946 -2695372509 -356835194 -211485320 -238662558 -1076233167 -3307891111 -3794546048 -37949562 -3637088288 -863193421 -271789329 -761391063 -205299928 -67378860 -2158013456 -3599194065 -1907079858 -174119784 -1624289467 -7483173 -2759382862 -224727064 -134258952 -3543155069 -2441640202 -2174979241 -851922069 -542448292 -3253137 -2080458461 -54616262 -252468170 -3223217159 -665218426 -4028018793 -4626772 -1748803383 -709060767 -3121149182 -56479134 -3893141625 -2686933815 -2995214218 -2162482869 -262490641 -1011561522 -549060114 -3932247987 -3223024295 -152321631 -3101843551 -1280099225 -3358647209 -252846296 -3524154097 -2187760847 -3909680653 -2179387890 -1015137433 -3494929304 -50606464 -3901100357 -9850320 -940382251 -2699631292 -3087385960 -9538500 -234958491 -272389742 -220260678 -2684647653 -43257408 -4027072178 -28810004 -2101495309 -18607774 -134280454 -3223347501 -1376157898 -3222543805 -22419610 -973776048 -83221848 -218483748 -2685071319 -134550656 -3506980865 -2173075612 -2483766325 -66860762 -138671625 -1075841013 -2367832091 -2247808 -38814954 -3490485897 -60737793 -604469508 -2153524819 -536917141 -1074075984 -12724890 -2972321868 -23188040 -1074423975 -1117820684 -1879381029 -1739586 -939530176 -5327050 -58757130 -2151669013 -67532608 -3087534325 -2474001 -277224382 -2191034903 -1057240535 -549434183 -3405807240 -1618369262 -86191107 -2955045761 -308647117 -1578408101 -3139990 -806116500 -3831595195 -155443373 -19022846 -98715033 -2634272139 -3275515777 -512124196 -3230432369 -575086366 -3225228801 -199711444 -942108876 -121867967 -2819529105 -2200767815 -1921129010 -36410428 -780163669 -274212015 -2376151708 -3359123316 -20068231 -2349001203 -2185655880 -973119224 -3235762297 -755212101 -2956716003 -103138961 -3376199891 -92680340 -3758301290 -3236398675 -1090770984 -4196670 -813793301 -16288768 -1277219531 -140550882 -25313600 -3257601090 -2477397505 -429066492 -583196168 -671646619 -2754150662 -2399163262 -69629076 -101346518 -3775145624 -3282507882 -1619334952 -6457996 -637846925 -676180878 -175175818 -1698451828 -2233162017 -3087408874 -49089607 -478663992 -280881932 -945942552 -3224705271 -151407497 -607767788 -80172123 -3624479885 -1110753748 -2013690146 -2184431875 -709117454 -2692553290 -2157242825 -874605844 -86108881 -2567065312 -1092017287 -344356159 -2425400907 -574662615 -1084594274 -1262643867 -929455814 -56999307 -2821124246 -858115549 -1888834109 -2150800911 -627861145 -6024170 -228373816 -1178327534 -1093027685 -3624421308 -3798255747 -449290167 -2597181707 -926243929 -2687439124 -254107214 -3829027460 -93803542 -3968018064 -1388720668 -1151812149 -1214147364 -844558349 -1080633195 -2350576007 -2368200508 -97528200 -2365796063 -2476535242 -1017242931 -3503925127 -852957056 -3492589682 -115795988 -925186774 -40237656 -4094491891 -1906813406 -1611043710 -1115295490 -787740617 -652006269 -3420228435 -1736435170 -1628768048 -3173066342 -1659370060 -502667371 -3701617539 -971219790 -3559002171 -3372410256 -2218574844 -14962797 -2680285584 -2318530008 -1580611180 -3962509653 -2995731663 -3262644231 -3386622672 -832903192 -826852989 -2339061594 -52616487 -319161836 -848007203 -713596765 -405804387 -2343674302 -2393126614 -2268412740 -3959609298 -3943003701 -1375818464 -3492713455 -3041590872 -1028634474 -69944722 -1329116577 -3238922414 -3508802651 -2688827650 -432118456 -181619625 -1020588554 -2158511183 -3996414429 -3430521601 -92558330 -4085981271 -3335052120 -1094411888 -943803286 -2019381420 -612050958 -739046845 -40203708 -160356556 -3241366485 -3011934011 -2552681725 -46401557 -544316860 -2897832596 -1064122014 -34062854 -3390969819 -4180831325 -2007854337 -3762749433 -174296912 -1678023203 -39792904 -3137637515 -3780663668 -688110716 -3769355130 -46416140 -3162873767 -230484689 -571417648 -3770011349 -1611628070 -2703187687 -147275591 -2556554365 -236196063 -3627157681 -2268570387 -3524220149 -2196407803 -683730648 -832718794 -958399385 -2289805767 -1393849733 -3560321216 -2190933457 -570506109 -1190464059 -855891340 -815207364 -727755671 -959944786 -2399256258 -2955296368 -2226474309 -4248919733 -54373041 -4255540140 -1079558374 -758297126 -3494062195 -172905473 -3660879546 -2169485331 -3171064613 -2734421278 -239124661 -1636792719 -1032199552 -3022143494 -1238328860 -2755367096 -1172068287 -2416030799 -1111231360 -1162238438 -136341168 -936511690 -3697688233 -2310946572 -1017208991 -3260655066 -2861019521 -4085782611 -3269494883 -820892676 -610312130 -873064187 -444719755 -1077221226 -1178295173 -2928297301 -123238584 -1803717266 -3778860833 -622164036 -2906858569 -3462751317 -230473195 -3229782038 -4056351409 -4062480954 -157481248 -15888294 -1022616105 -2251826379 -236458376 -3468433827 -3859679691 -4169609282 -3270154816 -3638739572 -3024095882 -811148317 -3261183116 -1325974504 -589588966 -546263216 -4039391440 -1001817745 -16154680 -165750980 -2788265304 -2620478124 -3439592229 -1654681662 -3608040307 -3777078995 -994394444 -1014396095 -138120475 -2685072838 -3228373358 -2552662027 -28069284 -314728824 -2426995424 -649430792 -2352053910 -2291666758 -940013010 -3257519298 -143153873 -2445086935 -895972163 -2420598353 -573867732 -1148475689 -120727570 -874272160 -1499568331 -730384503 -2381214 -272910609 -2992637073 -253053713 -84832812 -2226240734 -3876274424 -18983620 -1268799900 -1348803766 -205671635 -2826229385 -660957935 -1646191083 -103509332 -1678012033 -2713914564 -2105972745 -14594356 -278969605 -3966027377 -46113154 -1246514745 -3316402942 -990363635 -2962749314 -524577371 -3903648383 -202779778 -3762835161 -2261224091 -3692935449 -90068990 -813864789 -3496510266 -3456387596 -143015350 -315738178 -4026606747 -2176794694 -2351395438 -2264420045 -68273726 -3627034496 -1856958854 -1350988020 -58099784 -4067096716 -100097690 -1012654471 -2271403796 -1141174688 -2164427209 -562335369 -549995830 -416389002 -309413793 -11860448 -2231458885 -604433027 -251864294 -3498465912 -1401395398 -3022766621 -190641354 -139719433 -1619043956 -1125777754 -74067650 -4207624 -958432937 -1116985600 -79164300 -2419620443 -777581327 -1142807361 -63314936 -4130282535 -23324492 -554363587 -2992739718 -1208439855 -772634 -540021839 -2789338031 -163090632 -120839590 -1620336448 -2164918412 -1913539649 -141022634 -2660075661 -963507036 -2687451280 -1208246255 -2771730565 -69420323 -3233866653 -1241879628 -1723226915 -202266692 -2689359561 -1651839518 -3227502861 -78020380 -811821517 -2640397810 -18786699 -109454782 -3498917610 -542022675 -1621201984 -1220764211 -518079134 -106428047 -2150406528 -4213442838 -1712410802 -33957546 -2833255501 -1363466077 -2361205692 -238621598 -1081475811 -3290623399 -1645509834 -105086074 -1522806889 -959667661 -1344480514 -2894325459 -2637988048 -7641220 -3634424343 -2525971609 -1437315771 -174455456 -1926534907 -1080174481 -2914707278 -2355466320 -138587648 -2201502550 -3552082560 -2770463793 -818376469 -961820903 -1622385204 -3028513484 -318825118 -189698242 -3224822639 -898006137 -4135907579 -37993300 -1613862757 -1859348874 -2060448975 -35441046 -3966690161 -3037175409 -1654613515 -2255792831 -1335945969 -1023753955 -1688992272 -3938874011 -3642382007 -225770871 -2716500061 -207929882 -3426021282 -219580528 -3637400609 -3530004700 -1753898265 -166081018 -1019445811 -2555921818 -2201231873 -3422693765 -43214040 -587807866 -3506115085 -837243260 -2442251152 -240230417 -1077703104 -1327561358 -2265348349 diff --git a/tests/testthat/tests.R b/tests/testthat/tests.R deleted file mode 100644 index 59dc004..0000000 --- a/tests/testthat/tests.R +++ /dev/null @@ -1,63 +0,0 @@ -library(SyncRNG) -context("SyncRNG unit tests") - -test_that("test_randi", { - s <- SyncRNG(seed=123456) - expect_equal(s$randi(), 959852049) - expect_equal(s$randi(), 2314333085) - expect_equal(s$randi(), 2255782734) - expect_equal(s$randi(), 2921461239) - expect_equal(s$randi(), 1024197102) -}) - -test_that("test_rand", { - s <- SyncRNG(seed=123456) - expect_equal(s$rand(), 959852049 /(2**32)) - expect_equal(s$rand(), 2314333085/(2**32)) - expect_equal(s$rand(), 2255782734/(2**32)) - expect_equal(s$rand(), 2921461239/(2**32)) - expect_equal(s$rand(), 1024197102/(2**32)) -}) - -test_that("test_randbelow", { - s <- SyncRNG(seed=123456) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 0) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 4) - expect_equal(s$randbelow(5), 2) -}) - -test_that("test_shuffle", { - s <- SyncRNG(seed=123456) - x <- c(1, 2, 3, 4, 5) - y <- s$shuffle(x) - expect_equal(y, c(3, 4, 1, 2, 5)) -}) - -test_that("test_first_1000", { - s <- SyncRNG(seed=0) - fileName <- "./first_1000_seed_0.txt" - conn <- file(fileName, open="r") - linn <- readLines(conn) - for (i in 1:length(linn)) { - exp <- as.numeric(linn[i]) - expect_equal(exp, s$randi()) - } - close(conn) -}) - -printf <- function(...) invisible(cat(sprintf(...))); - -test_that("test_first_1000_unif", { - set.seed(0, 'user', 'user') - fileName <- "./first_1000_seed_0.txt" - conn <- file(fileName, open="r") - linn <- readLines(conn) - for (i in 1:length(linn)) { - exp <- as.numeric(linn[i]) - u <- as.numeric(runif(1)*(2**32 - 1)) - expect_equal(exp, u) - } - close(conn) -}) -- cgit v1.2.3 From 3409fc9201cc8ca460d36b77fb65f09b3d2f3be9 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Thu, 14 Jan 2021 17:15:54 +0000 Subject: bump roxygen --- new_R/DESCRIPTION | 2 +- new_R/man/SyncRNG-class.Rd | 7 ++++--- new_R/man/syncrng-package.Rd | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/new_R/DESCRIPTION b/new_R/DESCRIPTION index 12c5191..141743a 100644 --- a/new_R/DESCRIPTION +++ b/new_R/DESCRIPTION @@ -12,4 +12,4 @@ Imports: methods Suggests: testthat -RoxygenNote: 5.0.1 +RoxygenNote: 7.1.1 diff --git a/new_R/man/SyncRNG-class.Rd b/new_R/man/SyncRNG-class.Rd index 7a2c69b..92316da 100644 --- a/new_R/man/SyncRNG-class.Rd +++ b/new_R/man/SyncRNG-class.Rd @@ -2,8 +2,8 @@ % Please edit documentation in R/SyncRNG.R \docType{class} \name{SyncRNG-class} -\alias{SyncRNG} \alias{SyncRNG-class} +\alias{SyncRNG} \title{A Reference Class for SyncRNG} \description{ See \link{syncrng-package} for package documentation. @@ -16,6 +16,7 @@ See \link{syncrng-package} for package documentation. \item{\code{state}}{The current state of the RNG, should not be modified by the user} }} + \section{Methods}{ \describe{ @@ -29,10 +30,10 @@ user} \item{\code{shuffle(x)}}{Randomly shuffle a provided array of values} }} + \examples{ s <- SyncRNG(seed=123456) for (i in 1:10) - cat(s$randi(), '\\n') + cat(s$randi(), '\n') } - diff --git a/new_R/man/syncrng-package.Rd b/new_R/man/syncrng-package.Rd index a1b3d32..f8cfe02 100644 --- a/new_R/man/syncrng-package.Rd +++ b/new_R/man/syncrng-package.Rd @@ -21,6 +21,7 @@ numbers are generated using the object methods. It can also be used as a user-defined random number generator using the strategy outlined in .Random.user. See the examples section below. } + \examples{ library(SyncRNG) @@ -41,12 +42,11 @@ s$rand() s$rand() # [1] 6.257184e-05 +} +\references{ +URL: \url{https://github.com/GjjvdBurg/SyncRNG} } \author{ Gerrit J.J. van den Burg\cr Maintainer: Gerrit J.J. van den Burg } -\references{ -URL: \url{https://github.com/GjjvdBurg/SyncRNG} -} - -- cgit v1.2.3