├── .Rbuildignore ├── .editorconfig ├── .github └── workflows │ ├── pkgdown.yml │ ├── r-cmd-check.yml │ └── revdep-check.yml ├── .gitignore ├── .ignore ├── .lintr ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── Condition.R ├── Design.R ├── Domain.R ├── Domain_methods.R ├── NoDefault.R ├── ParamDbl.R ├── ParamFct.R ├── ParamInt.R ├── ParamLgl.R ├── ParamSet.R ├── ParamSetCollection.R ├── ParamUty.R ├── Sampler.R ├── Sampler1D.R ├── SamplerHierarchical.R ├── SamplerJointIndep.R ├── SamplerUnif.R ├── asserts.R ├── default_values.R ├── generate_design_grid.R ├── generate_design_lhs.R ├── generate_design_random.R ├── generate_design_sobol.R ├── helper.R ├── ps.R ├── ps_replicate.R ├── ps_union.R ├── reexports.R ├── to_tune.R └── zzz.R ├── README.Rmd ├── README.md ├── attic ├── Dependency.R ├── OptPath.R ├── ParamS6.R ├── ParamSetCollectionTrafo.R ├── ParamSet_add.R ├── S6ObjectCache.R ├── demo.R ├── helper_03_OptPath.R ├── helper_r6.R ├── paramset.Rmd ├── paramset.md ├── performance.R ├── samplers_visual_checks.R ├── sugar.R ├── test_OptPath.R ├── trafo.R ├── vectoralgorithm.R └── vectoralgorithm_ii.R ├── man-roxygen ├── field_constraint.R ├── field_deps.R ├── field_extra_trafo.R ├── field_is_bounded.R ├── field_levels.R ├── field_lower.R ├── field_nlevels.R ├── field_params.R ├── field_storage_type.R ├── field_tags.R ├── field_upper.R ├── field_values.R ├── param_custom_check.R ├── param_default.R ├── param_id.R ├── param_levels.R ├── param_lower.R ├── param_param.R ├── param_param_set.R ├── param_special_vals.R ├── param_tags.R ├── param_tolerance.R └── param_upper.R ├── man ├── Condition.Rd ├── Design.Rd ├── Domain.Rd ├── NO_DEF.Rd ├── ParamSet.Rd ├── ParamSetCollection.Rd ├── Sampler.Rd ├── Sampler1D.Rd ├── Sampler1DCateg.Rd ├── Sampler1DNormal.Rd ├── Sampler1DRfun.Rd ├── Sampler1DUnif.Rd ├── SamplerHierarchical.Rd ├── SamplerJointIndep.Rd ├── SamplerUnif.Rd ├── assert_param_set.Rd ├── default_values.Rd ├── domain_check.Rd ├── domain_is_bounded.Rd ├── domain_is_categ.Rd ├── domain_is_number.Rd ├── domain_nlevels.Rd ├── domain_qunif.Rd ├── domain_sanitize.Rd ├── generate_design_grid.Rd ├── generate_design_lhs.Rd ├── generate_design_random.Rd ├── generate_design_sobol.Rd ├── paradox-package.Rd ├── ps.Rd ├── ps_replicate.Rd ├── ps_union.Rd ├── psc.Rd ├── reexports.Rd └── to_tune.Rd ├── paradox.Rproj ├── pkgdown ├── _pkgdown.yml └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── tests ├── testthat.R └── testthat │ ├── helper.R │ ├── helper_01_params.R │ ├── helper_02_ParamSet.R │ ├── helper_03_domain.R │ ├── helper_compat.R │ ├── setup.R │ ├── teardown.R │ ├── test_Condition.R │ ├── test_Design.R │ ├── test_Param.R │ ├── test_ParamDbl.R │ ├── test_ParamFct.R │ ├── test_ParamInt.R │ ├── test_ParamLgl.R │ ├── test_ParamSet.R │ ├── test_ParamSetCollection.R │ ├── test_ParamUty.R │ ├── test_Param_rep.R │ ├── test_default_values.R │ ├── test_deps.R │ ├── test_domain.R │ ├── test_generate_design.R │ ├── test_param_vals.R │ ├── test_sampler.R │ ├── test_to_tune.R │ └── test_trafo.R └── vignettes └── indepth.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE$ 2 | .github 3 | .gitignore 4 | .ignore 5 | .Rproj.user 6 | ^.*\.Rproj$ 7 | ^.*\.sublime-project$ 8 | ^.*\.sublime-workspace$ 9 | ^.editorconfig$ 10 | ^\.Rproj\.user$ 11 | ^_pkgdown\.yml$ 12 | ^pkgdown$ 13 | ^appveyor\.yml$ 14 | ^docs$ 15 | ^README-.*\.png$ 16 | ^README\.Rmd$ 17 | ^README\.html$ 18 | ^attic$ 19 | ^\.ccache$ 20 | ^\.github$ 21 | ^man-roxygen$ 22 | ^.travis.yml$ 23 | ^.lintr$ 24 | ^revdep$ 25 | 26 | ^cran-comments\.md$ 27 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # See http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = space 9 | trim_trailing_whitespace = true 10 | 11 | [*.{r,R,md,Rmd}] 12 | indent_size = 2 13 | 14 | [*.{c,h}] 15 | indent_size = 4 16 | 17 | [*.{cpp,hpp}] 18 | indent_size = 4 19 | 20 | [{NEWS.md,DESCRIPTION,LICENSE}] 21 | max_line_length = 80 22 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yml: -------------------------------------------------------------------------------- 1 | # pkgdown workflow of the mlr3 ecosystem v0.1.0 2 | # https://github.com/mlr-org/actions 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | release: 11 | types: 12 | - published 13 | workflow_dispatch: 14 | 15 | name: pkgdown 16 | 17 | jobs: 18 | pkgdown: 19 | runs-on: ubuntu-latest 20 | 21 | concurrency: 22 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 23 | env: 24 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 25 | steps: 26 | - uses: actions/checkout@v3 27 | 28 | - uses: r-lib/actions/setup-pandoc@v2 29 | 30 | - uses: r-lib/actions/setup-r@v2 31 | 32 | - uses: r-lib/actions/setup-r-dependencies@v2 33 | with: 34 | extra-packages: any::pkgdown, local::. 35 | needs: website 36 | 37 | - name: Install template 38 | run: pak::pkg_install("mlr-org/mlr3pkgdowntemplate") 39 | shell: Rscript {0} 40 | 41 | - name: Build site 42 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 43 | shell: Rscript {0} 44 | 45 | - name: Deploy 46 | if: github.event_name != 'pull_request' 47 | uses: JamesIves/github-pages-deploy-action@v4.4.1 48 | with: 49 | clean: false 50 | branch: gh-pages 51 | folder: docs 52 | -------------------------------------------------------------------------------- /.github/workflows/r-cmd-check.yml: -------------------------------------------------------------------------------- 1 | # r cmd check workflow of the mlr3 ecosystem v0.1.0 2 | # https://github.com/mlr-org/actions 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | name: r-cmd-check 13 | 14 | jobs: 15 | r-cmd-check: 16 | runs-on: ${{ matrix.config.os }} 17 | 18 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 19 | 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | config: 27 | - {os: ubuntu-latest, r: 'devel'} 28 | - {os: ubuntu-latest, r: 'release'} 29 | 30 | steps: 31 | - uses: actions/checkout@v3 32 | 33 | - uses: r-lib/actions/setup-r@v2 34 | with: 35 | r-version: ${{ matrix.config.r }} 36 | 37 | - uses: r-lib/actions/setup-r-dependencies@v2 38 | with: 39 | extra-packages: any::rcmdcheck 40 | needs: check 41 | 42 | - uses: r-lib/actions/check-r-package@v2 43 | -------------------------------------------------------------------------------- /.github/workflows/revdep-check.yml: -------------------------------------------------------------------------------- 1 | # r cmd check workflow of the mlr3 ecosystem v0.1.0 2 | # https://github.com/mlr-org/actions 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | name: revdep-check 13 | 14 | jobs: 15 | revdep-check: 16 | runs-on: ${{ matrix.config.os }} 17 | 18 | name: revdep ${{ matrix.config.pkg }} (${{ matrix.config.os }}, ${{ matrix.config.r }}) 19 | 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | config: 27 | - {os: ubuntu-latest, r: 'release', pkg: 'mlr-org/mlr3'} 28 | - {os: ubuntu-latest, r: 'release', pkg: 'mlr-org/mlr3pipelines'} 29 | - {os: ubuntu-latest, r: 'release', pkg: 'mlr-org/bbotk'} 30 | - {os: ubuntu-latest, r: 'release', pkg: 'mlr-org/miesmuschel'} 31 | - {os: ubuntu-latest, r: 'release', pkg: 'mlr-org/mlr3mbo'} 32 | - {os: ubuntu-latest, r: 'release', pkg: 'mb706/mlrintermbo'} 33 | 34 | steps: 35 | - uses: actions/checkout@v4 36 | with: 37 | repository: ${{ matrix.config.pkg }} 38 | 39 | - uses: r-lib/actions/setup-pandoc@v2 40 | if: matrix.config.pkg == 'mlr-org/mlr3mbo' 41 | 42 | - uses: r-lib/actions/setup-r@v2 43 | with: 44 | r-version: ${{ matrix.config.r }} 45 | 46 | - uses: supercharge/redis-github-action@1.7.0 47 | if: contains(fromJSON('["mlr-org/bbotk", "mlr-org/mlr3mbo"]'), matrix.config.pkg) 48 | with: 49 | redis-version: 7 50 | 51 | - uses: r-lib/actions/setup-r-dependencies@v2 52 | with: 53 | extra-packages: any::rcmdcheck 54 | needs: check 55 | 56 | - name: Install dev versions 57 | run: pak::pkg_install('${{ github.repository }}@${{ github.sha }}') 58 | shell: Rscript {0} 59 | 60 | - uses: r-lib/actions/check-r-package@v2 61 | name: Normal check 62 | if: ${{ !contains(fromJSON('["mlr-org/bbotk", "mlr-org/mlr3mbo"]'), matrix.config.pkg) }} 63 | 64 | - uses: r-lib/actions/check-r-package@v2 65 | name: bbotk check 66 | if: contains(fromJSON('["mlr-org/bbotk", "mlr-org/mlr3mbo"]'), matrix.config.pkg) 67 | with: 68 | args: 'c("--no-manual")' # "--as-cran" prevents to start external processes 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # User-specific files 9 | .Ruserdata 10 | 11 | # Example code in package build process 12 | *-Ex.R 13 | 14 | # Output files from R CMD build 15 | /*.tar.gz 16 | 17 | # Output files from R CMD check 18 | /*.Rcheck/ 19 | 20 | # RStudio files 21 | .Rproj.user/ 22 | 23 | # produced vignettes 24 | vignettes/*.html 25 | vignettes/*.pdf 26 | 27 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 28 | .httr-oauth 29 | 30 | # knitr and R markdown default cache directories 31 | *_cache/ 32 | /cache/ 33 | 34 | # Temporary files created by R markdown 35 | *.utf8.md 36 | *.knit.md 37 | 38 | # R Environment Variables 39 | .Renviron 40 | 41 | # pkgdown site 42 | docs/ 43 | 44 | # General 45 | .DS_Store 46 | .AppleDouble 47 | .LSOverride 48 | 49 | # Icon must end with two \r 50 | Icon 51 | 52 | 53 | 54 | # Thumbnails 55 | ._* 56 | 57 | # Files that might appear in the root of a volume 58 | .DocumentRevisions-V100 59 | .fseventsd 60 | .Spotlight-V100 61 | .TemporaryItems 62 | .Trashes 63 | .VolumeIcon.icns 64 | .com.apple.timemachine.donotpresent 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | # Windows thumbnail cache files 74 | Thumbs.db 75 | Thumbs.db:encryptable 76 | ehthumbs.db 77 | ehthumbs_vista.db 78 | 79 | # Dump file 80 | *.stackdump 81 | 82 | # Folder config file 83 | [Dd]esktop.ini 84 | 85 | # Recycle Bin used on file shares 86 | $RECYCLE.BIN/ 87 | 88 | # Windows Installer files 89 | *.cab 90 | *.msi 91 | *.msix 92 | *.msm 93 | *.msp 94 | 95 | # Windows shortcuts 96 | *.lnk 97 | 98 | .vscode/* 99 | !.vscode/settings.json 100 | !.vscode/tasks.json 101 | !.vscode/launch.json 102 | !.vscode/extensions.json 103 | *.code-workspace 104 | .vscode 105 | 106 | # Autosaves and Temp files 107 | .#* 108 | *~ 109 | \#*# 110 | *.swp 111 | 112 | README.html 113 | cran-comments\.md 114 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | man/ 2 | docs/ 3 | attic/ 4 | pkgdown/ 5 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: linters_with_defaults( 2 | # lintr defaults: https://lintr.r-lib.org/reference/default_linters.html 3 | # the following setup changes/removes certain linters 4 | assignment_linter = NULL, # do not force using <- for assignments 5 | object_name_linter = object_name_linter(c("snake_case", "CamelCase")), # only allow snake case and camel case object names 6 | cyclocomp_linter = NULL, # do not check function complexity 7 | commented_code_linter = NULL, # allow code in comments 8 | line_length_linter = line_length_linter(120L) 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # OS --------------------------------------------------------------------------- 2 | os: linux 3 | 4 | # meta ------------------------------------------------------------------------- 5 | language: r 6 | cache: packages 7 | latex: false 8 | branches: 9 | only: 10 | - master 11 | 12 | # Stages ----------------------------------------------------------------------- 13 | 14 | install: true 15 | script: 16 | - Rscript -e 'if (!requireNamespace("lintr")) install.packages("lintr")' 17 | - Rscript -e 'if (!requireNamespace("remotes")) install.packages("remotes")' 18 | - Rscript -e 'remotes::install_deps()' 19 | - R CMD build . 20 | - R CMD INSTALL *.tar.gz 21 | - Rscript -e 'lintr::lint_package()' 22 | 23 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Type: Package 2 | Package: paradox 3 | Title: Define and Work with Parameter Spaces for Complex 4 | Algorithms 5 | Version: 1.0.1-9000 6 | Authors@R: 7 | c(person(given = "Michel", 8 | family = "Lang", 9 | role = "aut", 10 | email = "michellang@gmail.com", 11 | comment = c(ORCID = "0000-0001-9754-0393")), 12 | person(given = "Bernd", 13 | family = "Bischl", 14 | role = "aut", 15 | email = "bernd_bischl@gmx.net", 16 | comment = c(ORCID = "0000-0001-6002-6980")), 17 | person(given = "Jakob", 18 | family = "Richter", 19 | role = "aut", 20 | email = "jakob1richter@gmail.com", 21 | comment = c(ORCID = "0000-0003-4481-5554")), 22 | person(given = "Xudong", 23 | family = "Sun", 24 | role = "aut", 25 | email = "smilesun.east@gmail.com", 26 | comment = c(ORCID = "0000-0003-3269-2307")), 27 | person(given = "Martin", 28 | family = "Binder", 29 | role = c("aut", "cre"), 30 | email = "mlr.developer@mb706.com"), 31 | person(given = "Marc", 32 | family = "Becker", 33 | role = "ctb", 34 | email = "marcbecker@posteo.de", 35 | comment = c(ORCID = "0000-0002-8115-0400"))) 36 | Description: Define parameter spaces, constraints and 37 | dependencies for arbitrary algorithms, to program on such spaces. Also 38 | includes statistical designs and random samplers. Objects are 39 | implemented as 'R6' classes. 40 | License: LGPL-3 41 | URL: https://paradox.mlr-org.com, 42 | https://github.com/mlr-org/paradox 43 | BugReports: https://github.com/mlr-org/paradox/issues 44 | Imports: 45 | backports, 46 | checkmate, 47 | data.table, 48 | methods, 49 | mlr3misc (>= 0.9.4), 50 | R6 51 | Suggests: 52 | rmarkdown, 53 | mlr3learners, 54 | e1071, 55 | knitr, 56 | lhs, 57 | spacefillr, 58 | testthat 59 | Encoding: UTF-8 60 | Config/testthat/edition: 3 61 | Config/testthat/parallel: false 62 | NeedsCompilation: no 63 | Roxygen: list(markdown = TRUE, r6 = TRUE) 64 | RoxygenNote: 7.3.2 65 | VignetteBuilder: knitr 66 | Collate: 67 | 'Condition.R' 68 | 'Design.R' 69 | 'Domain.R' 70 | 'Domain_methods.R' 71 | 'NoDefault.R' 72 | 'ParamDbl.R' 73 | 'ParamFct.R' 74 | 'ParamInt.R' 75 | 'ParamLgl.R' 76 | 'ParamSet.R' 77 | 'ParamSetCollection.R' 78 | 'ParamUty.R' 79 | 'Sampler.R' 80 | 'Sampler1D.R' 81 | 'SamplerHierarchical.R' 82 | 'SamplerJointIndep.R' 83 | 'SamplerUnif.R' 84 | 'asserts.R' 85 | 'default_values.R' 86 | 'generate_design_grid.R' 87 | 'generate_design_lhs.R' 88 | 'generate_design_random.R' 89 | 'generate_design_sobol.R' 90 | 'helper.R' 91 | 'ps.R' 92 | 'ps_replicate.R' 93 | 'ps_union.R' 94 | 'reexports.R' 95 | 'to_tune.R' 96 | 'zzz.R' 97 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("$",Constructor) 4 | S3method(as.data.table,ParamSet) 5 | S3method(c,ParamSet) 6 | S3method(condition_as_string,Condition) 7 | S3method(condition_test,CondAnyOf) 8 | S3method(condition_test,CondEqual) 9 | S3method(default_values,ParamSet) 10 | S3method(domain_check,ParamDbl) 11 | S3method(domain_check,ParamFct) 12 | S3method(domain_check,ParamInt) 13 | S3method(domain_check,ParamLgl) 14 | S3method(domain_check,ParamUty) 15 | S3method(domain_is_bounded,Domain) 16 | S3method(domain_is_bounded,ParamDbl) 17 | S3method(domain_is_bounded,ParamFct) 18 | S3method(domain_is_bounded,ParamInt) 19 | S3method(domain_is_bounded,ParamLgl) 20 | S3method(domain_is_bounded,ParamUty) 21 | S3method(domain_is_categ,Domain) 22 | S3method(domain_is_categ,ParamDbl) 23 | S3method(domain_is_categ,ParamFct) 24 | S3method(domain_is_categ,ParamInt) 25 | S3method(domain_is_categ,ParamLgl) 26 | S3method(domain_is_categ,ParamUty) 27 | S3method(domain_is_number,Domain) 28 | S3method(domain_is_number,ParamDbl) 29 | S3method(domain_is_number,ParamFct) 30 | S3method(domain_is_number,ParamInt) 31 | S3method(domain_is_number,ParamLgl) 32 | S3method(domain_is_number,ParamUty) 33 | S3method(domain_nlevels,Domain) 34 | S3method(domain_nlevels,ParamDbl) 35 | S3method(domain_nlevels,ParamFct) 36 | S3method(domain_nlevels,ParamInt) 37 | S3method(domain_nlevels,ParamLgl) 38 | S3method(domain_nlevels,ParamUty) 39 | S3method(domain_qunif,Domain) 40 | S3method(domain_qunif,ParamDbl) 41 | S3method(domain_qunif,ParamFct) 42 | S3method(domain_qunif,ParamInt) 43 | S3method(domain_qunif,ParamLgl) 44 | S3method(domain_qunif,ParamUty) 45 | S3method(domain_sanitize,Domain) 46 | S3method(domain_sanitize,ParamDbl) 47 | S3method(domain_sanitize,ParamInt) 48 | S3method(format,Condition) 49 | S3method(print,Condition) 50 | S3method(print,Domain) 51 | S3method(print,FullTuneToken) 52 | S3method(print,InternalTuneToken) 53 | S3method(print,ObjectTuneToken) 54 | S3method(print,RangeTuneToken) 55 | S3method(rd_info,ParamSet) 56 | export(CondAnyOf) 57 | export(CondEqual) 58 | export(Condition) 59 | export(Design) 60 | export(NO_DEF) 61 | export(ParamSet) 62 | export(ParamSetCollection) 63 | export(Sampler) 64 | export(Sampler1D) 65 | export(Sampler1DCateg) 66 | export(Sampler1DNormal) 67 | export(Sampler1DRfun) 68 | export(Sampler1DUnif) 69 | export(SamplerHierarchical) 70 | export(SamplerJointIndep) 71 | export(SamplerUnif) 72 | export(as.data.table) 73 | export(assert_param_set) 74 | export(condition_as_string) 75 | export(default_values) 76 | export(domain_assert) 77 | export(domain_check) 78 | export(domain_is_bounded) 79 | export(domain_is_categ) 80 | export(domain_is_number) 81 | export(domain_nlevels) 82 | export(domain_qunif) 83 | export(domain_sanitize) 84 | export(domain_test) 85 | export(generate_design_grid) 86 | export(generate_design_lhs) 87 | export(generate_design_random) 88 | export(generate_design_sobol) 89 | export(p_dbl) 90 | export(p_fct) 91 | export(p_int) 92 | export(p_lgl) 93 | export(p_uty) 94 | export(ps) 95 | export(ps_replicate) 96 | export(ps_union) 97 | export(psc) 98 | export(to_tune) 99 | import(checkmate) 100 | import(data.table) 101 | import(mlr3misc) 102 | importFrom(R6,R6Class) 103 | importFrom(R6,is.R6Class) 104 | importFrom(data.table,as.data.table) 105 | importFrom(methods,is) 106 | importFrom(stats,rnorm) 107 | importFrom(stats,runif) 108 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # paradox 1.0.1-9000 2 | 3 | * `ParamSetCollection$flatten()` now detaches `$extra_trafo` completely from original ParamSetCollection. 4 | * Option to postfix, instead of prefix, in `ParamSetCollection`, `c()`/`ps_union()`, and `ps_replicate()`. 5 | 6 | # paradox 1.0.1 7 | 8 | * Performance improvements. 9 | 10 | # paradox 1.0.0 11 | 12 | * Removed `Param` objects. `ParamSet` now uses a `data.table` internally; individual parameters are more like `Domain` objects now. `ParamSets` should be constructed using the `ps()` shorthand and `Domain` objects. This entails the following major changes: 13 | * `ParamSet` now supports `extra_trafo` natively; it behaves like `.extra_trafo` of the `ps()` call. 14 | * `ParamSet` has `$constraint` 15 | * `ParamSet` objects are now less mutable. The only properties that can be changed are `values`, `tags`, `deps`, `constraint` and `extra_trafo`. 16 | * `ParamSet$is_bounded` is a vector with an entry for each parameter. Use `$all_bounded` for the previous behavior. 17 | * `Condition` objects are now S3 objects and can be constructed with `CondEqual()` and `CondAnyOf()`, instead of `CondXyz$new()`. (It is recommended to use the `Domain` interface for conditions, which has not changed) 18 | * `ParamSet` has new fields `$is_logscale`, `$has_trafo_param` (per-param), and `$has_trafo_param` (scalar for the whole set). 19 | * Added a vignette which was previously a chapter in the `mlr3book` 20 | * feat: added support for `InternalTuneToken`s 21 | 22 | # paradox 0.11.1 23 | 24 | * Minor bug fixes. 25 | 26 | # paradox 0.11.0 27 | 28 | * feat: The function `generate_design_sobol()` generates a space-filling Sobol sequence design. 29 | * refactor: `$set_values` returns the parameter set invisible. 30 | 31 | # paradox 0.10.0 32 | 33 | * Reset `.has_extra_trafo` to `FALSE` when trafo is set to `NULL`. 34 | * `rd_info.ParamSet` collapses vector with `"\n"` due changes in roxygen 7.2.0 35 | * Add method `set_values()` to conveniently add parameter values. 36 | 37 | # paradox 0.9.0 38 | 39 | * Added `default_values()` function to extract default values from `ParamSet` 40 | objects. 41 | 42 | # paradox 0.8.0 43 | 44 | * Parameters now have a new (optional) field `description`. 45 | * Improved printing of parameters in documentation (#355). 46 | * A warning is now signaled if the package `ParamHelpers` is also loaded. 47 | * Fixed some links. 48 | 49 | # paradox 0.7.1 50 | 51 | * `Sampler1D` also accept `ParamSet`s with one `Param` now (#335). 52 | * Fixed sampling zero rows in `Sampler1DRfun` (#338). 53 | * `to_tune()`, `p_dbl()`, and `p_int()` accept `logscale` argument for tuning on 54 | a logarithmic scale. 55 | * `to_tune` can be called with only `lower` or only `upper` now and will infer 56 | the other bound if possible. 57 | 58 | # paradox 0.7.0 59 | 60 | * `ParamSet$get_values()` checks whether all required parameter values are set. 61 | Required parameter are not checked anymore when new values are added to the 62 | parameter set. 63 | * `ParamSet$check_dt()` accepts `data.frame`s. 64 | * Rename `is_numeric` and `is_categorical` to `all_numeric` and 65 | `all_categorical`. 66 | * Rename `requires` to `depends`. 67 | 68 | # paradox 0.6.0 69 | 70 | * `ps()` shortcuts for `ParamSet` construction, with new `Domain` construct and 71 | constructors `p_dbl`, `p_int`, `p_lgl`, `p_fct`, and `p_uty`. 72 | * `ParamSet$search_space()` method that constructs tunable `ParamSet` from 73 | `TuneToken` objects, which are constructed with `to_tune()`. 74 | 75 | # paradox 0.5.0 76 | 77 | * Compact in-memory representation of R6 objects to save space when 78 | saving objects via saveRDS(), serialize() etc. 79 | * Improved performance for `ParamSetCollection`. 80 | 81 | # paradox 0.4.0 82 | 83 | * New public methods `is_numeric()` and `is_categorical()` for parameter sets. 84 | * Fixed a test for upcoming release of `data.table()`. 85 | * Added a helper function to format parameter sets in Rd files. 86 | 87 | # paradox 0.3.0 88 | 89 | * New function `transpose()` converts `data.table` of parameter values to a list 90 | of lists. 91 | * New methods `ParamSet$check_dt()`, `$assert_dt()` and `test_dt()` can check a 92 | `data.table` for valid parameter values. 93 | * Documentation updated. 94 | * Unified style for object printers. 95 | 96 | # paradox 0.2.0 97 | 98 | * Fixed warnings about partial argument matching. 99 | * Enforce integer bounds in ParamInt (#258). 100 | * Reexport `data.table::as.data.table()`. 101 | * Deep cloning of `ParamSet$values` (#273). 102 | 103 | # paradox 0.1.0 104 | 105 | * Initial release. 106 | -------------------------------------------------------------------------------- /R/Condition.R: -------------------------------------------------------------------------------- 1 | # -- class methods 2 | 3 | #' @describeIn Condition 4 | #' 5 | #' Used internally. Tests whether a value satisfies a given condition. 6 | #' Vectorizes when `x` is atomic. 7 | #' 8 | #' @param cond (`Condition`)\cr 9 | #' `Condition` to use 10 | #' @param x (`any`)\cr 11 | #' Value to test 12 | #' @export 13 | condition_test = function(cond, x) { 14 | UseMethod("condition_test") 15 | } 16 | 17 | #' @describeIn Condition 18 | #' 19 | #' Used internally. Returns a string that represents the condition for pretty 20 | #' printing, in the form `" "`, e.g. `"x == 3"` or 21 | #' `"param %in% {1, 2, 10}"`. 22 | #' 23 | #' @param cond (`Condition`)\cr 24 | #' `Condition` to use 25 | #' @param lhs_chr (`character(1)`)\cr 26 | #' Symbolic representation to use for `` in the returned string. 27 | #' @export 28 | condition_as_string = function(cond, lhs_chr = "x") { 29 | assert_string(lhs_chr) 30 | UseMethod("condition_as_string") 31 | } 32 | 33 | # -- Condition 34 | 35 | #' @title Dependency Condition 36 | #' 37 | #' @description 38 | #' Condition object, to specify the condition in a dependency. 39 | #' 40 | #' @param rhs (`any`)\cr 41 | #' Right-hand-side of the condition. 42 | #' @param condition_format_string (`character(1)`)\cr 43 | #' Format-string for representing the condition when pretty-printing 44 | #' in [`condition_as_string()`]. 45 | #' Should contain two `%s`, as it is used in an `sprintf()`-call with 46 | #' two further string values. 47 | #' 48 | #' @section Currently implemented simple conditions: 49 | #' * `CondEqual(rhs)` \cr 50 | #' Value must be equal to `rhs`. 51 | #' * `CondAnyOf(rhs)` \cr 52 | #' Value must be any value of `rhs`. 53 | #' 54 | #' @aliases CondEqual CondAnyOf 55 | #' @export 56 | Condition = function(rhs, condition_format_string) { 57 | assert_string(condition_format_string) 58 | structure(list(rhs = rhs, condition_format_string = condition_format_string), class = "Condition") 59 | } 60 | 61 | #' @export 62 | condition_as_string.Condition = function(cond, lhs_chr = "x") { 63 | sprintf(cond$condition_format_string, lhs_chr, str_collapse(cond$rhs)) 64 | } 65 | 66 | #' @export 67 | format.Condition = function(x, ...) { 68 | sprintf("", class(x)[[1L]]) 69 | } 70 | 71 | #' @export 72 | print.Condition = function(x, ...) { 73 | catf("%s: %s", class(x)[[1L]], condition_as_string(x)) 74 | } 75 | 76 | # -- CondEqual 77 | 78 | #' @export 79 | CondEqual = function(rhs) { 80 | assert_atomic(rhs, any.missing = FALSE, len = 1) 81 | cond = Condition(rhs, "%s == %s") 82 | set_class(cond, c("CondEqual", class(cond))) 83 | } 84 | 85 | #' @export 86 | condition_test.CondEqual = function(cond, x) { 87 | !is.na(x) & x == cond$rhs 88 | } 89 | 90 | #' @export 91 | CondAnyOf = function(rhs) { 92 | assert_atomic(rhs, any.missing = FALSE, min.len = 1, unique = TRUE) 93 | cond = Condition(rhs, "%s %%in%% {%s}") 94 | set_class(cond, c("CondAnyOf", class(cond))) 95 | } 96 | 97 | #' @export 98 | condition_test.CondAnyOf = function(cond, x) { 99 | !is.na(x) & x %in% cond$rhs 100 | } 101 | 102 | # FIXME: the following makes `condition$new()` possible for paradox transition 103 | # should give a deprecated warning at some point. 104 | #' @export 105 | `$.Constructor` = function(e1, e2) { 106 | if (!identical(e2, "new")) { 107 | stop("only 'new' element can be accessed.") 108 | } else { 109 | e1 110 | } 111 | } 112 | 113 | CondEqual = structure(CondEqual, class = c("Constructor", "function")) 114 | CondAnyOf = structure(CondAnyOf, class = c("Constructor", "function")) 115 | -------------------------------------------------------------------------------- /R/Design.R: -------------------------------------------------------------------------------- 1 | #' @title Design of Configurations 2 | #' 3 | #' @description 4 | #' A lightweight wrapper around a [ParamSet] and a [data.table::data.table()], where the 5 | #' latter is a design of configurations produced from the former - e.g., 6 | #' by calling a [generate_design_grid()] or by sampling. 7 | #' 8 | #' @export 9 | Design = R6Class("Design", 10 | public = list( 11 | #' @field param_set ([ParamSet]). 12 | param_set = NULL, 13 | 14 | #' @field data ([data.table::data.table()])\cr 15 | #' Stored `data`. 16 | data = NULL, 17 | 18 | #' @description 19 | #' Creates a new instance of this [R6][R6::R6Class] class. 20 | #' 21 | #' @param param_set ([ParamSet]). 22 | #' @param data ([data.table::data.table()])\cr 23 | #' Stored `data`. 24 | #' @param remove_dupl (`logical(1)`)\cr 25 | #' Remove duplicates? 26 | initialize = function(param_set, data, remove_dupl) { 27 | 28 | assert_param_set(param_set) 29 | assert_data_table(data, ncols = param_set$length) 30 | assert_names(colnames(data), permutation.of = param_set$ids()) 31 | self$param_set = param_set 32 | # FIXME: this works in general but is not really fast, as we generate the col first, then overwrite it, 33 | # OTOH this is really robust 34 | # set fixed param vals to their constant values 35 | # FIXME: this might also be problematic for LHS 36 | # do we still create an LHS like this? 37 | imap(param_set$values, function(v, n) set(data, j = n, value = v)) 38 | self$data = data 39 | if (param_set$has_deps) { 40 | private$set_deps_to_na() 41 | } 42 | # NB: duplicated rows can happen to to NA setting 43 | if (remove_dupl) { 44 | self$data = unique(self$data) 45 | } # remove duplicated rows 46 | }, 47 | 48 | 49 | #' @description 50 | #' Helper for print outputs. 51 | #' @param ... (ignored). 52 | format = function(...) { 53 | sprintf("<%s>", class(self)[1L]) 54 | }, 55 | 56 | #' @description 57 | #' Printer. 58 | #' 59 | #' @param ... (ignored). 60 | print = function(...) { 61 | # simply print the included dt 62 | catf(" with %i rows:", nrow(self$data)) 63 | print(self$data) 64 | }, 65 | 66 | #' @description 67 | #' Converts `data` into a list of lists of row-configurations, 68 | #' possibly removes `NA` entries of inactive parameter values due to unsatisfied dependencies, 69 | #' and possibly calls the `trafo` function of the [ParamSet]. 70 | #' 71 | #' @param filter_na (`logical(1)`)\cr 72 | #' Should `NA` entries of inactive parameter values due to unsatisfied 73 | #' dependencies be removed? 74 | #' @param trafo (`logical(1)`)\cr 75 | #' Should the `trafo` function of the [ParamSet] be called? 76 | transpose = function(filter_na = TRUE, trafo = TRUE) { 77 | assert_flag(filter_na) 78 | assert_flag(trafo) 79 | ps = self$param_set 80 | xs = transpose_list(self$data) 81 | if (filter_na) { 82 | xs = map(xs, function(x) Filter(Negate(is_scalar_na), x)) 83 | } 84 | if (ps$has_trafo && trafo) { 85 | xs = map(xs, function(x) ps$trafo(x)) 86 | } 87 | return(xs) 88 | } 89 | ), 90 | 91 | private = list( 92 | # function to set unsatisfied deps to NA in the design dt "data": 93 | # walk thru all params, toposorted order, then walk thru all deps 94 | # and set values in x to NA which where the dep is not OK 95 | set_deps_to_na = function(remove_dupl) { 96 | 97 | ps = self$param_set 98 | graph = ps$deps[, 1:2] 99 | colnames(graph) = c("id", "parents") 100 | # we need to make sure that every param has a (maybe empty) row in the graph table 101 | fillin = data.table(id = ps$ids(), parents = list(character(0L))) 102 | graph = rbind(graph, fillin[fillin$id %nin% graph$id, ]) 103 | graph = graph[, list("parents" = list(unlist(get("parents"), use.names = FALSE))), by = "id"] 104 | topo = topo_sort(graph) 105 | pids_sorted = topo$id 106 | storage_types = ps$storage_type 107 | for (param_id in pids_sorted) { 108 | dd = ps$deps[get("id") == param_id, ] 109 | for (j in seq_row(dd)) { 110 | pcol = self$data[[dd$on[j]]] 111 | # we are ok if parent was active and cond on parent is OK 112 | not_ok = which(is.na(pcol) | !condition_test(dd$cond[[j]], pcol)) 113 | set(self$data, not_ok, j = param_id, value = as_type(NA, storage_types[[param_id]])) 114 | } 115 | } 116 | } 117 | ) 118 | ) 119 | -------------------------------------------------------------------------------- /R/NoDefault.R: -------------------------------------------------------------------------------- 1 | #' @title Extra data type for "no default value" 2 | #' 3 | #' @description 4 | #' Special new data type for no-default. 5 | #' Not often needed by the end-user, mainly internal. 6 | #' 7 | #' * `NO_DEF`: Singleton object for type, used in [`Domain`] when no default is given. 8 | #' * `is_nodefault()`: Is an object the 'no default' object? 9 | #' 10 | #' @name NO_DEF 11 | #' @aliases NoDefault is_nodefault 12 | NULL 13 | 14 | #' @export 15 | NO_DEF = structure(list(), class = "NoDefault") # nolint 16 | is_nodefault = function(x) identical(x, NO_DEF) 17 | -------------------------------------------------------------------------------- /R/ParamDbl.R: -------------------------------------------------------------------------------- 1 | #' @rdname Domain 2 | #' @export 3 | p_dbl = function(lower = -Inf, upper = Inf, special_vals = list(), default = NO_DEF, tags = character(), tolerance = sqrt(.Machine$double.eps), depends = NULL, trafo = NULL, logscale = FALSE, init, aggr = NULL, in_tune_fn = NULL, disable_in_tune = NULL) { 4 | assert_number(tolerance, lower = 0) 5 | assert_number(lower) 6 | assert_number(upper) 7 | assert_true(lower <= upper) 8 | if (assert_flag(logscale)) { 9 | if (!is.null(trafo)) stop("When a trafo is given then logscale must be FALSE") 10 | if (assert_number(lower) <= 0) stop("When logscale is TRUE then lower bound must be strictly greater than 0") 11 | trafo = exp 12 | # at this point we don't want to overwrite 'lower' and 'upper, since they get used for the representation 13 | real_lower = log(lower) 14 | real_upper = log(assert_number(upper)) 15 | } else { 16 | real_lower = lower 17 | real_upper = upper 18 | } 19 | 20 | cargo = list() 21 | if (logscale) cargo$logscale = TRUE 22 | cargo$aggr = aggr 23 | cargo$in_tune_fn = in_tune_fn 24 | cargo$disable_in_tune = disable_in_tune 25 | Domain(cls = "ParamDbl", grouping = "ParamDbl", lower = real_lower, upper = real_upper, special_vals = special_vals, default = default, tags = tags, tolerance = tolerance, trafo = trafo, storage_type = "numeric", 26 | depends_expr = substitute(depends), init = init, cargo = if (length(cargo)) cargo) 27 | } 28 | 29 | #' @export 30 | domain_check.ParamDbl = function(param, values, internal = FALSE) { 31 | lower = param$lower - param$tolerance * pmax(1, abs(param$lower)) 32 | upper = param$upper + param$tolerance * pmax(1, abs(param$upper)) 33 | if (qtestr(values, "N1")) { 34 | values_num = as.numeric(values) 35 | if (all(values_num >= lower) && all(values_num <= upper)) return(TRUE) 36 | } 37 | check_domain_vectorize(param$id, values, check_number, more_args = list(lower = lower, upper = upper)) 38 | } 39 | 40 | #' @export 41 | domain_sanitize.ParamDbl = function(param, values) { 42 | values = as.numeric(values) 43 | values[values < param$lower] = param$lower 44 | values[values > param$upper] = param$upper 45 | as.list(values) 46 | } 47 | 48 | #' @export 49 | domain_nlevels.ParamDbl = function(param) ifelse(param$upper == param$lower, 1, Inf) 50 | #' @export 51 | domain_is_bounded.ParamDbl = function(param) is.finite(param$lower) & is.finite(param$upper) 52 | #' @export 53 | domain_qunif.ParamDbl = function(param, x) { 54 | pmax(pmin(x * param$upper - (x-1) * param$lower, param$upper), param$lower) # extra careful here w/ rounding errors 55 | } 56 | 57 | #' @export 58 | domain_is_number.ParamDbl = function(param) TRUE 59 | #' @export 60 | domain_is_categ.ParamDbl = function(param) FALSE 61 | -------------------------------------------------------------------------------- /R/ParamFct.R: -------------------------------------------------------------------------------- 1 | #' @rdname Domain 2 | #' @export 3 | p_fct = function(levels, special_vals = list(), default = NO_DEF, tags = character(), depends = NULL, trafo = NULL, init, aggr = NULL, in_tune_fn = NULL, disable_in_tune = NULL) { 4 | assert_function(aggr, null.ok = TRUE, nargs = 1L) 5 | constargs = as.list(match.call()[-1]) 6 | levels = eval.parent(constargs$levels) 7 | if (!is.character(levels)) { 8 | # if the "levels" argument is not a character vector, then 9 | # we add a trafo. 10 | assert(check_atomic_vector(levels), check_list(levels)) 11 | if (is.null(names(levels))) { 12 | names(levels) = as.character(levels) 13 | } 14 | trafo = crate(function(x) { 15 | x = levels[[x]] 16 | if (!is.null(trafo)) x = trafo(x) 17 | x 18 | }, trafo, levels) 19 | real_levels = names(levels) 20 | } else { 21 | real_levels = levels 22 | } 23 | # group p_fct by levels, so the group can be checked in a vectorized fashion. 24 | # We escape '"' and '\' to '\"' and '\\', respectively. 25 | cargo = list() 26 | cargo$disable_in_tune = disable_in_tune 27 | cargo$aggr = aggr 28 | cargo$in_tune_fn = in_tune_fn 29 | grouping = str_collapse(gsub("([\\\\\"])", "\\\\\\1", sort(real_levels)), quote = '"', sep = ",") 30 | Domain(cls = "ParamFct", grouping = grouping, levels = real_levels, special_vals = special_vals, 31 | default = default, tags = tags, trafo = trafo, storage_type = "character", 32 | depends_expr = substitute(depends), init = init, cargo = if (length(cargo)) cargo) 33 | } 34 | 35 | #' @export 36 | domain_check.ParamFct = function(param, values, internal = FALSE) { 37 | if (qtestr(values, "S1")) { 38 | values_str = as.character(values) 39 | if (all(values_str %in% param$levels[[1]])) return(TRUE) # this works because we have the grouping -- all 'levels' are the same here. 40 | } 41 | check_domain_vectorize(param$id, values, check_choice, more_args = list(choices = param$levels)) 42 | } 43 | 44 | #' @export 45 | domain_nlevels.ParamFct = function(param) map_dbl(param$levels, length) 46 | #' @export 47 | domain_is_bounded.ParamFct = function(param) rep(TRUE, nrow(param)) 48 | #' @export 49 | domain_qunif.ParamFct = function(param, x) { 50 | nlevels = domain_nlevels(param) 51 | z = pmin(floor(x * nlevels) + 1, nlevels) # make sure we dont map to upper+1 52 | as.character(pmap(list(param$levels, z), `[[`)) 53 | } 54 | 55 | #' @export 56 | domain_is_number.ParamFct = function(param) FALSE 57 | #' @export 58 | domain_is_categ.ParamFct = function(param) TRUE 59 | -------------------------------------------------------------------------------- /R/ParamInt.R: -------------------------------------------------------------------------------- 1 | 2 | #' @rdname Domain 3 | #' @export 4 | p_int = function(lower = -Inf, upper = Inf, special_vals = list(), default = NO_DEF, tags = character(), tolerance = sqrt(.Machine$double.eps), depends = NULL, trafo = NULL, logscale = FALSE, init, aggr = NULL, in_tune_fn = NULL, disable_in_tune = NULL) { 5 | assert_number(tolerance, lower = 0, upper = 0.5) 6 | # assert_int will stop for `Inf` values, which we explicitly allow as lower / upper bound 7 | if (!isTRUE(is.infinite(lower))) assert_int(lower, tol = 1e-300) else assert_number(lower) 8 | if (!isTRUE(is.infinite(upper))) assert_int(upper, tol = 1e-300) else assert_number(upper) 9 | assert_true(lower <= upper) 10 | if (assert_flag(logscale)) { 11 | if (!is.null(trafo)) stop("When a trafo is given then logscale must be FALSE") 12 | if (lower < 0) stop("When logscale is TRUE then lower bound must be greater or equal 0") 13 | trafo = crate(function(x) as.integer(max(min(exp(x), upper), lower)), lower, upper) 14 | # at this point we don't want to overwrite 'lower' and 'upper, since they get used for the representation 15 | real_lower = log(max(lower, 0.5)) 16 | real_upper = log(upper + 1) 17 | cls = "ParamDbl" 18 | storage_type = "numeric" 19 | } else { 20 | cls = "ParamInt" 21 | storage_type = "integer" 22 | real_lower = lower 23 | real_upper = upper 24 | } 25 | 26 | cargo = list() 27 | if (logscale) cargo$logscale = TRUE 28 | cargo$aggr = aggr 29 | cargo$in_tune_fn = in_tune_fn 30 | cargo$disable_in_tune = disable_in_tune 31 | 32 | Domain(cls = cls, grouping = cls, lower = real_lower, upper = real_upper, special_vals = special_vals, default = default, tags = tags, tolerance = tolerance, trafo = trafo, 33 | storage_type = storage_type, 34 | depends_expr = substitute(depends), init = init, cargo = if (length(cargo)) cargo) 35 | } 36 | 37 | #' @export 38 | domain_check.ParamInt = function(param, values, internal = FALSE) { 39 | if (!qtestr(values, "N1()")) { 40 | return(check_domain_vectorize(param$id, values, check_int, 41 | more_args = list(lower = param$lower - 0.5, upper = param$upper + 0.5, # be lenient with bounds, because they would refer to the rounded values 42 | tol = .51) # we don't know the tolerances of individual values, but we do know that some values are not even (non-missing, finite) numerics 43 | )) 44 | } 45 | 46 | values_num = as.numeric(values) 47 | 48 | rounded = round(values_num) 49 | if (all(abs(values_num - rounded) <= param$tolerance & 50 | rounded >= param$lower & 51 | rounded <= param$upper)) { 52 | return(TRUE) 53 | } 54 | 55 | check_domain_vectorize(param$id, values_num, check_int, 56 | more_args = list(lower = param$lower - 0.5, upper = param$upper + 0.5, # be lenient with bounds, because they would refer to the rounded values 57 | tol = pmax(1e-300, param$tolerance + 2 * abs(values_num) * .Machine$double.eps)) # want to have inclusive tolerance bounds. Not sure if 2* is necessary. 58 | ) 59 | } 60 | 61 | #' @export 62 | domain_sanitize.ParamInt = function(param, values) { 63 | as.list(as.integer(round(as.numeric(values)))) 64 | } 65 | 66 | #' @export 67 | domain_nlevels.ParamInt = function(param) (param$upper - param$lower) + 1 68 | #' @export 69 | domain_is_bounded.ParamInt = function(param) is.finite(param$lower) & is.finite(param$upper) 70 | #' @export 71 | domain_qunif.ParamInt = function(param, x) { 72 | # extra careful here w/ rounding errors and the x == 1 case 73 | # note that as.integer alone rounds towards 0 and can not be used without 'floor' here 74 | as.integer(floor(pmax(pmin(x * (param$upper + 1) - (x - 1) * param$lower, param$upper), param$lower))) 75 | } 76 | 77 | #' @export 78 | domain_is_number.ParamInt = function(param) TRUE 79 | #' @export 80 | domain_is_categ.ParamInt = function(param) FALSE 81 | -------------------------------------------------------------------------------- /R/ParamLgl.R: -------------------------------------------------------------------------------- 1 | #' @rdname Domain 2 | #' @export 3 | p_lgl = function(special_vals = list(), default = NO_DEF, tags = character(), depends = NULL, trafo = NULL, init, aggr = NULL, in_tune_fn = NULL, disable_in_tune = NULL) { 4 | cargo = list() 5 | cargo$aggr = aggr 6 | cargo$in_tune_fn = in_tune_fn 7 | cargo$disable_in_tune = disable_in_tune 8 | Domain(cls = "ParamLgl", grouping = "ParamLgl", levels = c(TRUE, FALSE), special_vals = special_vals, default = default, 9 | tags = tags, trafo = trafo, storage_type = "logical", depends_expr = substitute(depends), init = init, cargo = if (length(cargo)) cargo) 10 | } 11 | 12 | #' @export 13 | domain_check.ParamLgl = function(param, values, internal = FALSE) { 14 | if (qtestr(values, "B1")) { 15 | return(TRUE) 16 | } 17 | check_domain_vectorize(param$id, values, check_flag) 18 | } 19 | 20 | #' @export 21 | domain_nlevels.ParamLgl = function(param) rep(2, nrow(param)) 22 | #' @export 23 | domain_is_bounded.ParamLgl = function(param) rep(TRUE, nrow(param)) 24 | #' @export 25 | domain_qunif.ParamLgl = function(param, x) { 26 | x < 0.5 27 | } 28 | 29 | #' @export 30 | domain_is_number.ParamLgl = function(param) FALSE 31 | #' @export 32 | domain_is_categ.ParamLgl = function(param) TRUE 33 | -------------------------------------------------------------------------------- /R/ParamUty.R: -------------------------------------------------------------------------------- 1 | 2 | #' @rdname Domain 3 | #' @export 4 | p_uty = function(custom_check = NULL, special_vals = list(), default = NO_DEF, tags = character(), depends = NULL, trafo = NULL, repr = substitute(default), init, aggr = NULL, in_tune_fn = NULL, disable_in_tune = NULL) { 5 | assert_function(custom_check, null.ok = TRUE) 6 | if (!is.null(custom_check)) { 7 | custom_check_result = custom_check(1) 8 | assert(check_true(custom_check_result), check_string(custom_check_result), .var.name = "The result of 'custom_check()'") 9 | } 10 | repr = if (!is_nodefault(default)) { 11 | deparse(repr)[[1]] 12 | } else { 13 | "NoDefault" 14 | } 15 | cargo = list(custom_check = custom_check, repr = repr) 16 | cargo$aggr = aggr 17 | cargo$in_tune_fn = in_tune_fn 18 | cargo$disable_in_tune = disable_in_tune 19 | 20 | Domain(cls = "ParamUty", grouping = "ParamUty", cargo = cargo, special_vals = special_vals, default = default, tags = tags, trafo = trafo, storage_type = "list", depends_expr = substitute(depends), init = init) 21 | } 22 | 23 | #' @export 24 | domain_check.ParamUty = function(param, values, internal = FALSE) { 25 | cargo = map(param$cargo, "custom_check") 26 | subset = !map_lgl(cargo, is.null) 27 | if (!any(subset)) return(TRUE) 28 | values = values[subset] 29 | check_domain_vectorize(param$id[subset], values, cargo[subset]) 30 | } 31 | 32 | #' @export 33 | domain_nlevels.ParamUty = function(param) rep(Inf, nrow(param)) 34 | #' @export 35 | domain_is_bounded.ParamUty = function(param) rep(FALSE, nrow(param)) 36 | #' @export 37 | domain_qunif.ParamUty = function(param, x) stop("undefined") 38 | 39 | #' @export 40 | domain_is_number.ParamUty = function(param) FALSE 41 | #' @export 42 | domain_is_categ.ParamUty = function(param) FALSE 43 | -------------------------------------------------------------------------------- /R/Sampler.R: -------------------------------------------------------------------------------- 1 | #' @title Sampler Class 2 | #' 3 | #' @description 4 | #' This is the abstract base class for sampling objects like [Sampler1D], [SamplerHierarchical] or [SamplerJointIndep]. 5 | #' 6 | #' @template param_param_set 7 | #' 8 | #' @family Sampler 9 | #' @export 10 | Sampler = R6Class("Sampler", 11 | public = list( 12 | #' @field param_set ([`ParamSet`])\cr 13 | #' Domain / support of the distribution we want to sample from. 14 | param_set = NULL, 15 | 16 | #' @description 17 | #' Creates a new instance of this [R6][R6::R6Class] class. 18 | #' 19 | #' Note that this object is typically constructed via derived classes, 20 | #' e.g., [Sampler1D]. 21 | #' @param param_set ([`ParamSet`])\cr 22 | #' The [`ParamSet`] to associated with this `Sampler`. 23 | initialize = function(param_set) { 24 | assert_param_set(param_set, no_untyped = TRUE) 25 | self$param_set = param_set$clone(deep = TRUE) 26 | }, 27 | 28 | #' @description 29 | #' Sample `n` values from the distribution. 30 | #' 31 | #' @param n (`integer(1)`). 32 | #' @return [`Design`]. 33 | sample = function(n) { 34 | assert_count(n) # we do argcheck on toplevel 35 | Design$new(self$param_set, private$.sample(n), remove_dupl = FALSE) # user wants n points, dont remove 36 | }, 37 | 38 | #' @description 39 | #' Helper for print outputs. 40 | #' @param ... (ignored). 41 | format = function(...) { 42 | sprintf("<%s>", class(self)[1L]) 43 | }, 44 | 45 | #' @description 46 | #' Printer. 47 | #' 48 | #' @param ... (ignored). 49 | print = function(...) { 50 | catf(format(self)) 51 | catf("For params: %s", str_trunc(str_collapse(self$param_set$ids()), width = 40L)) 52 | private$.print() 53 | } 54 | ), 55 | private = list( 56 | .sample = function(n) stop("abstract"), # inheriting classes have to implement this 57 | .print = function() { 58 | } # inheriting classes can overwrite to add lines 59 | ) 60 | ) 61 | -------------------------------------------------------------------------------- /R/SamplerHierarchical.R: -------------------------------------------------------------------------------- 1 | #' @title SamplerHierarchical Class 2 | #' 3 | #' @description 4 | #' Hierarchical sampling for arbitrary param sets with dependencies, where the user specifies 1D samplers per param. 5 | #' Dependencies are topologically sorted, parameters are then sampled in topological order, 6 | #' and if dependencies do not hold, values are set to `NA` in the resulting `data.table`. 7 | #' 8 | #' @template param_param_set 9 | #' 10 | #' @family Sampler 11 | #' @include Sampler.R 12 | #' @export 13 | SamplerHierarchical = R6Class("SamplerHierarchical", inherit = Sampler, 14 | public = list( 15 | #' @field samplers (`list()`)\cr 16 | #' List of [`Sampler1D`] objects that gives a Sampler for each dimension in the `param_set`. 17 | samplers = NULL, 18 | 19 | #' @description 20 | #' Creates a new instance of this [R6][R6::R6Class] class. 21 | #' 22 | #' @param param_set ([`ParamSet`])\cr 23 | #' The [`ParamSet`] to associated with this `SamplerHierarchical`. 24 | #' @param samplers (`list()`)\cr 25 | #' List of [`Sampler1D`] objects that gives a Sampler for each dimension in the `param_set`. 26 | initialize = function(param_set, samplers) { 27 | assert_param_set(param_set, no_untyped = TRUE) 28 | assert_list(samplers, types = "Sampler1D") 29 | ids1 = param_set$ids() 30 | ids2 = map_chr(samplers, function(s) s$param$ids()) 31 | if (!setequal(ids1, ids2)) { 32 | stop("IDs of params in samplers to not correspond to IDs of params in set!") 33 | } 34 | super$initialize(param_set) 35 | self$samplers = samplers 36 | } 37 | ), 38 | private = list( 39 | # samples independently from the 1d distributions 40 | # dependencies are actually handled when in "sample" we create the Design, then set entries to NA 41 | .sample = function(n) map_dtc(self$samplers, function(s) s$sample(n)$data) 42 | ) 43 | ) 44 | -------------------------------------------------------------------------------- /R/SamplerJointIndep.R: -------------------------------------------------------------------------------- 1 | #' @title SamplerJointIndep Class 2 | #' 3 | #' @description 4 | #' Create joint, independent sampler out of multiple other samplers. 5 | #' 6 | #' @family Sampler 7 | #' @include Sampler.R 8 | #' @export 9 | SamplerJointIndep = R6Class("SamplerJointIndep", inherit = Sampler, 10 | public = list( 11 | #' @field samplers (`list()`)\cr 12 | #' List of [`Sampler`] objects. 13 | samplers = NULL, 14 | 15 | #' @description 16 | #' Creates a new instance of this [R6][R6::R6Class] class. 17 | #' 18 | #' @param samplers (`list()`)\cr 19 | #' List of [`Sampler`] objects. 20 | initialize = function(samplers) { 21 | assert_list(samplers, types = "Sampler") 22 | self$samplers = samplers 23 | pss = map(samplers, "param_set") 24 | # FIXME: maybe we should use a paramset collection here? 25 | self$param_set = ps_union(pss) 26 | # must_bounded and untyped should be check by the sapler, or if the sampler still works, then ok 27 | assert_param_set(self$param_set, no_deps = TRUE) 28 | } 29 | ), 30 | 31 | private = list( 32 | # FIXME: would be nice if we could call .sample here instead of sample, for less type 33 | # conversion and peed, but .sample is private. make it public? also not great... 34 | .sample = function(n) map_dtc(self$samplers, function(s) s$sample(n)$data), 35 | .print = function() catf("Independent comps: %i", length(self$samplers)) 36 | ) 37 | ) 38 | -------------------------------------------------------------------------------- /R/SamplerUnif.R: -------------------------------------------------------------------------------- 1 | #' @title SamplerUnif Class 2 | #' 3 | #' @description 4 | #' Uniform random sampling for an arbitrary (bounded) [ParamSet]. 5 | #' Constructs 1 uniform sampler per parameter, then passes them to [SamplerHierarchical]. 6 | #' Hence, also works for [ParamSet]s sets with dependencies. 7 | #' 8 | #' @template param_param_set 9 | #' 10 | #' @family Sampler 11 | #' @include SamplerHierarchical.R 12 | #' @export 13 | SamplerUnif = R6Class("SamplerUnif", inherit = SamplerHierarchical, 14 | public = list( 15 | #' @description 16 | #' Creates a new instance of this [R6][R6::R6Class] class. 17 | #' @param param_set ([`ParamSet`])\cr 18 | #' The [`ParamSet`] to associated with this `SamplerUnif`. 19 | initialize = function(param_set) { 20 | assert_param_set(param_set, must_bounded = TRUE, no_deps = FALSE, no_untyped = TRUE) 21 | samplers = lapply(param_set$subspaces(), Sampler1DUnif$new) 22 | super$initialize(param_set, samplers) 23 | } 24 | ) 25 | ) 26 | -------------------------------------------------------------------------------- /R/asserts.R: -------------------------------------------------------------------------------- 1 | #' @title Assertions for Params and ParamSets 2 | #' 3 | #' @param param_set ([`ParamSet`]). 4 | #' @param cl (`character()`)\cr 5 | #' Allowed subclasses. 6 | #' @param no_untyped (`logical(1)`)\cr 7 | #' Are untyped [`Domain`]s allowed? 8 | #' @param must_bounded (`logical(1)`)\cr 9 | #' Only bounded [`Domain`]s allowed? 10 | #' @param no_deps (`logical(1)`)\cr 11 | #' Are dependencies allowed? 12 | #' @return The checked object, invisibly. 13 | #' @export 14 | assert_param_set = function(param_set, cl = NULL, no_untyped = FALSE, must_bounded = FALSE, no_deps = FALSE) { 15 | assert_r6(param_set, "ParamSet") 16 | if (!is.null(cl)) { 17 | if (!all(param_set$class %in% cl)) stopf("Only classes %s allowed", str_collapse(cl)) 18 | } 19 | if (no_untyped && !all(param_set$class %in% c("ParamLgl", "ParamInt", "ParamFct", "ParamDbl"))) { 20 | stop("ParamSet contains untyped params!") 21 | } 22 | if (must_bounded && !all(param_set$is_bounded)) { 23 | stop("ParamSet contains unbounded params!") 24 | } 25 | if (no_deps && param_set$has_deps) { 26 | stop("ParamSet contains dependencies!") 27 | } 28 | invisible(param_set) 29 | } 30 | -------------------------------------------------------------------------------- /R/default_values.R: -------------------------------------------------------------------------------- 1 | #' @title Extract Parameter Default Values 2 | #' 3 | #' @description 4 | #' Extract parameter default values. 5 | #' 6 | #' @param x (`any`)\cr 7 | #' Object to extract default values from. 8 | #' @param ... (any)\cr 9 | #' Additional arguments. 10 | #' 11 | #' @return `list()`. 12 | #' @export 13 | default_values = function(x, ...) { # nolint 14 | UseMethod("default_values") 15 | } 16 | 17 | #' @export 18 | #' @rdname default_values 19 | default_values.ParamSet = function(x, ...) { 20 | x$default 21 | } 22 | -------------------------------------------------------------------------------- /R/generate_design_grid.R: -------------------------------------------------------------------------------- 1 | #' @title Generate a Grid Design 2 | #' 3 | #' @description 4 | #' Generate a grid with a specified resolution in the parameter space. 5 | #' The resolution for categorical parameters is ignored, these parameters 6 | #' always produce a grid over all their valid levels. 7 | #' For number params the endpoints of the params are always included in the grid. 8 | #' 9 | #' @param param_set ([`ParamSet`]). 10 | #' @param resolution (`integer(1)`)\cr 11 | #' Global resolution for all parameters. 12 | #' @param param_resolutions (named `integer()`)\cr 13 | #' Resolution per [`Domain`], named by parameter ID. 14 | #' @return [`Design`]. 15 | #' 16 | #' @family generate_design 17 | #' @export 18 | #' @examples 19 | #' pset = ps( 20 | #' ratio = p_dbl(lower = 0, upper = 1), 21 | #' letters = p_fct(levels = letters[1:3]) 22 | #' ) 23 | #' generate_design_grid(pset, 10) 24 | generate_design_grid = function(param_set, resolution = NULL, param_resolutions = NULL) { 25 | 26 | assert_param_set(param_set, no_untyped = TRUE) 27 | ids = param_set$ids() 28 | ids_num = ids[param_set$is_number] 29 | 30 | par_res = integer(0L) # here we construct the resolution for each param 31 | if (length(ids_num) > 0L) { # if only categ we dont need to check 32 | if (is.null(resolution) && is.null(param_resolutions)) { 33 | stop("You must specify 'resolution' or 'param_resolutions'!") 34 | } 35 | if (!is.null(resolution)) { 36 | # create param_resolutions list, constant entry, same length as ids and named with ids 37 | resolution = assert_count(resolution, coerce = TRUE) 38 | par_res = set_names(rep.int(resolution, param_set$length), ids) 39 | } 40 | if (!is.null(param_resolutions)) { 41 | assert_integerish(param_resolutions, lower = 1L, any.missing = FALSE, coerce = TRUE) 42 | # user only needs to pass num params (categ resolutions are overwritten anyway) 43 | assert_names(names(param_resolutions), subset.of = ids_num) 44 | par_res = insert_named(par_res, param_resolutions) 45 | } 46 | ids_miss = setdiff(ids_num, names(par_res)) 47 | if (length(ids_miss) > 0L) { 48 | stopf("Resolution settings missing for some numerical params: %s", str_collapse(ids_miss)) 49 | } 50 | } 51 | # overwrite the resolution for categorical stuff with the number of levels they have 52 | isc = param_set$is_categ 53 | par_res = insert_named(par_res, param_set$nlevels[isc]) 54 | # generate regular grid from 0,1 then map it to the values of the param, 55 | # then do a crossproduct 56 | grid_vec = lapply(par_res, function(r) seq(0, 1, length.out = r)) 57 | res = imap(grid_vec, function(value, id) param_set$qunif(setnames(data.table(value), id))[[1]]) 58 | res = cross_join(res, sorted = FALSE) 59 | Design$new(param_set, res, remove_dupl = TRUE) # user wants no dupls, remove 60 | } 61 | -------------------------------------------------------------------------------- /R/generate_design_lhs.R: -------------------------------------------------------------------------------- 1 | #' @title Generate a Space-Filling LHS Design 2 | #' 3 | #' @description 4 | #' Generate a space-filling design using Latin hypercube sampling. Dependent 5 | #' parameters whose constraints are unsatisfied generate `NA` entries in 6 | #' their respective columns. 7 | #' 8 | #' @param param_set ([`ParamSet`]). 9 | #' @param n (`integer(1)`) \cr 10 | #' Number of points to sample. 11 | #' @param lhs_fun (`function(n, k)`)\cr 12 | #' Function to use to generate a LHS sample, with n samples and k values per param. 13 | #' LHS functions are implemented in package \pkg{lhs}, default is to use [lhs::maximinLHS()]. 14 | #' @return [`Design`]. 15 | #' 16 | #' @family generate_design 17 | #' @export 18 | #' @examples 19 | #' pset = ps( 20 | #' ratio = p_dbl(lower = 0, upper = 1), 21 | #' letters = p_fct(levels = letters[1:3]) 22 | #' ) 23 | #' 24 | #' if (requireNamespace("lhs", quietly = TRUE)) { 25 | #' generate_design_lhs(pset, 10) 26 | #' } 27 | generate_design_lhs = function(param_set, n, lhs_fun = NULL) { 28 | if (is.null(lhs_fun)) { 29 | require_namespaces("lhs") 30 | lhs_fun = lhs::maximinLHS 31 | } 32 | assert_param_set(param_set, no_untyped = TRUE) 33 | n = assert_count(n, coerce = TRUE) 34 | assert_function(lhs_fun, args = c("n", "k")) 35 | 36 | ids = param_set$ids() 37 | if (n == 0) { 38 | d = matrix(numeric(0), nrow = 0, ncol = param_set$length) 39 | } else { 40 | d = lhs_fun(n, k = param_set$length) 41 | } 42 | colnames(d) = ids 43 | d = param_set$qunif(d) 44 | Design$new(param_set, d, remove_dupl = FALSE) # user wants n-points, dont remove 45 | } 46 | -------------------------------------------------------------------------------- /R/generate_design_random.R: -------------------------------------------------------------------------------- 1 | #' @title Generate a Random Design 2 | #' 3 | #' @description 4 | #' Generates a design with randomly drawn points. 5 | #' Internally uses [`SamplerUnif`], hence, also works for [ParamSet]s with dependencies. 6 | #' If dependencies do not hold, values are set to `NA` in the resulting data.table. 7 | #' 8 | #' @param param_set ([`ParamSet`]). 9 | #' @param n (`integer(1)`)\cr 10 | #' Number of points to draw randomly. 11 | #' @return [`Design`]. 12 | #' 13 | #' @family generate_design 14 | #' @export 15 | #' @examples 16 | #' pset = ps( 17 | #' ratio = p_dbl(lower = 0, upper = 1), 18 | #' letters = p_fct(levels = letters[1:3]) 19 | #' ) 20 | #' generate_design_random(pset, 10) 21 | generate_design_random = function(param_set, n) { 22 | # arg checks done by SamplerUnif and sample 23 | SamplerUnif$new(param_set)$sample(n) 24 | } 25 | -------------------------------------------------------------------------------- /R/generate_design_sobol.R: -------------------------------------------------------------------------------- 1 | #' @title Generate a Space-Filling Sobol Sequence Design 2 | #' 3 | #' @description 4 | #' Generate a space-filling design using a Sobol sequence. Dependent 5 | #' parameters whose constraints are unsatisfied generate `NA` entries in 6 | #' their respective columns. 7 | #' 8 | #' Uses [spacefillr::generate_sobol_set]. 9 | #' 10 | #' Note that non determinism is achieved by sampling the seed argument via 11 | #' `sample(.Machine$integer.max, size = 1L)`. 12 | #' 13 | #' @param param_set ([`ParamSet`]). 14 | #' @param n (`integer(1)`) \cr 15 | #' Number of points to sample. 16 | #' @return [`Design`]. 17 | #' 18 | #' @family generate_design 19 | #' @export 20 | #' @examples 21 | #' pset = ps( 22 | #' ratio = p_dbl(lower = 0, upper = 1), 23 | #' letters = p_fct(levels = letters[1:3]) 24 | #' ) 25 | #' 26 | #' if (requireNamespace("spacefillr", quietly = TRUE)) { 27 | #' generate_design_sobol(pset, 10) 28 | #' } 29 | generate_design_sobol = function(param_set, n) { 30 | require_namespaces("spacefillr") 31 | assert_param_set(param_set, no_untyped = TRUE) 32 | n = assert_count(n, coerce = TRUE) 33 | 34 | ids = param_set$ids() 35 | if (n == 0) { 36 | d = matrix(numeric(0), nrow = 0, ncol = param_set$length) 37 | } else { 38 | seed = sample(.Machine$integer.max, size = 1L) 39 | d = spacefillr::generate_sobol_set(n, dim = param_set$length, seed = seed) 40 | } 41 | colnames(d) = ids 42 | d = param_set$qunif(d) 43 | Design$new(param_set, set_names(d, ids), remove_dupl = FALSE) # user wants n-points, dont remove 44 | } 45 | -------------------------------------------------------------------------------- /R/helper.R: -------------------------------------------------------------------------------- 1 | #' @title transpose 2 | #' 3 | #' @description 4 | #' Converts [data.table::data.table] into a list of lists of points, possibly 5 | #' removes `NA` entries of inactive parameter values due to unsatisfied 6 | #' dependencies, and possibly calls the `trafo` function of the [ParamSet]. 7 | #' 8 | #' @param data ([data.table::data.table])\cr 9 | #' Rows are points and columns are parameters. 10 | #' 11 | #' @param ps ([`ParamSet`])\cr 12 | #' If `trafo = TRUE`, used to call trafo function. 13 | #' 14 | #' @param filter_na (`logical(1)`)\cr 15 | #' Should `NA` entries of inactive parameter values be removed due to 16 | #' unsatisfied dependencies? 17 | #' 18 | #' @param trafo (`logical(1)`)\cr 19 | #' Should the `trafo` function of the [ParamSet] be called? 20 | #' @noRd 21 | transpose = function(data, ps = NULL, filter_na = TRUE, trafo = TRUE) { 22 | assert_data_table(data) 23 | assert_flag(filter_na) 24 | assert_flag(trafo) 25 | xs = transpose_list(data) 26 | if (filter_na) { 27 | xs = map(xs, function(x) Filter(Negate(is_scalar_na), x)) 28 | } 29 | if (!is.null(ps) && trafo) { 30 | if (ps$has_trafo) xs = map(xs, function(x) ps$trafo(x, ps)) 31 | } 32 | return(xs) 33 | } 34 | 35 | repr = function(x) { 36 | str_collapse(utils::capture.output(print(x)), "\n") 37 | } 38 | 39 | as_type = function(x, type) { 40 | switch(type, 41 | logical = as.logical(x), 42 | integer = as.integer(x), 43 | numeric = as.numeric(x), 44 | character = as.character(x), 45 | list = as.list(x), 46 | stopf("Invalid storage type '%s'", type) 47 | ) 48 | } 49 | 50 | # column to named list 51 | col_to_nl = function(dt, col = 1, idcol = 2) { 52 | data = dt[[col]] 53 | names(data) = dt[[idcol]] 54 | data 55 | } 56 | 57 | 58 | # rbindlist, but 59 | # (1) some optimization if only one table given and we know it is a data.table 60 | # (2) if no table is given, return a prototype table. 61 | # Input is potentially not copied, so input should be copied itself if by-reference-modification could be an issue! 62 | rbindlist_proto = function(l, prototype) { 63 | tbls_given = which(lengths(l) != 0) 64 | if (length(tbls_given) == 0) return(prototype) 65 | if (length(tbls_given) == 1) return(l[[tbls_given]]) 66 | rbindlist(l, use.names = TRUE) 67 | } 68 | -------------------------------------------------------------------------------- /R/ps.R: -------------------------------------------------------------------------------- 1 | #' @include helper.R 2 | 3 | #' @title Construct a ParamSet using Short Forms 4 | #' 5 | #' @description 6 | #' The `ps()` short form constructor uses [`Domain`] objects (`p_dbl`, `p_fct`, ...) to construct [`ParamSet`]s in a 7 | #' succinct and readable way. 8 | #' 9 | #' For more specifics also see the documentation of [`Domain`]. 10 | #' 11 | #' @param ... ([`Domain`])\cr 12 | #' Named arguments of [`Domain`] objects. The [`ParamSet`] will be constructed of the given [`Domain`]s, 13 | #' The names of the arguments will be used as `$id()` in the resulting [`ParamSet`]. 14 | #' @param .extra_trafo (`function(x, param_set)`)\cr 15 | #' Transformation to set the resulting [`ParamSet`]'s `$trafo` value to. This is in addition to any `trafo` of 16 | #' [`Domain`] objects given in `...`, and will be run *after* transformations of individual parameters were performed. 17 | #' @param .constraint (`function(x)`)\cr 18 | #' Constraint function. 19 | #' When given, this function must evaluate a named `list()` of values and determine whether it satisfies 20 | #' constraints, returning a scalar `logical(1)` value. 21 | #' @param .allow_dangling_dependencies (`logical`)\cr 22 | #' Whether dependencies depending on parameters that are not present should be allowed. A parameter `x` having 23 | #' `depends = y == 0` if `y` is not present in the `ps()` call would usually throw an error, but if dangling 24 | #' dependencies are allowed, the dependency is added regardless. This is usually a bad idea and mainly for internal 25 | #' use. Dependencies between [`ParamSet`]s when using [`to_tune()`] can be realized using this. 26 | #' @return A [`ParamSet`] object. 27 | #' @examples 28 | #' pars = ps( 29 | #' a = p_int(0, 10), 30 | #' b = p_int(upper = 20), 31 | #' c = p_dbl(), 32 | #' e = p_fct(letters[1:3]), 33 | #' f = p_uty(custom_check = checkmate::check_function) 34 | #' ) 35 | #' print(pars) 36 | #' 37 | #' pars = ps( 38 | #' a = p_dbl(0, 1, trafo = exp), 39 | #' b = p_dbl(0, 1, trafo = exp), 40 | #' .extra_trafo = function(x, ps) { 41 | #' x$c <- x$a + x$b 42 | #' x 43 | #' } 44 | #' ) 45 | #' 46 | #' # See how the addition happens after exp()ing: 47 | #' pars$trafo(list(a = 0, b = 0)) 48 | #' 49 | #' pars$values = list( 50 | #' a = to_tune(ps(x = p_int(0, 1), 51 | #' .extra_trafo = function(x, param_set) list(a = x$x) 52 | #' )), 53 | #' # make 'y' depend on 'x', but they are defined in different ParamSets 54 | #' # Therefore we need to allow dangling dependencies here. 55 | #' b = to_tune(ps(y = p_int(0, 1, depends = x == 1), 56 | #' .extra_trafo = function(x, param_set) list(b = x$y), 57 | #' .allow_dangling_dependencies = TRUE 58 | #' )) 59 | #' ) 60 | #' 61 | #' pars$search_space() 62 | #' @family ParamSet construction helpers 63 | #' @export 64 | ps = function(..., .extra_trafo = NULL, .constraint = NULL, .allow_dangling_dependencies = FALSE) { 65 | param_set = ParamSet$new(list(...), allow_dangling_dependencies = .allow_dangling_dependencies) 66 | param_set$extra_trafo = .extra_trafo 67 | param_set$constraint = .constraint 68 | param_set 69 | } 70 | 71 | #' @title Create a ParamSet Collection 72 | #' 73 | #' @description 74 | #' Creates a [`ParamSetCollection`]. 75 | #' 76 | #' @param ... (any)\cr 77 | #' The [`ParamSet`]s from which to create the collection. 78 | #' @export 79 | psc = function(...) { 80 | ParamSetCollection$new(list(...)) 81 | } 82 | -------------------------------------------------------------------------------- /R/ps_replicate.R: -------------------------------------------------------------------------------- 1 | #' @title Create a ParamSet by Repeating a Given ParamSet 2 | #' 3 | #' @description 4 | #' Repeat a [`ParamSet`] a given number of times and thus create a larger [`ParamSet`]. 5 | #' By default, the resulting parameters are prefixed with the string `"repX.", where `X` counts up from 1. 6 | #' It is also possible to tag parameters by their original name and by their prefix, making grouped retrieval e.g. using `$get_values()` easier. 7 | #' 8 | #' @param set ([`ParamSet`])\cr 9 | #' [`ParamSet`] to use as template. 10 | #' @param times (`integer(1)`)\cr 11 | #' Number of times to repeat `set`. 12 | #' Should not be given if `affixes` is provided. 13 | #' @param affixes (`character`)\cr 14 | #' A `character` vector indicating the prefixes / postfixes to use for each repetition of `set`. 15 | #' Per default, these are prefixes; if `postfix` is `TRUE`, these values are postfixed instead. 16 | #' If this is given, `times` is inferred from `length(affixes)` and should not be given separately. 17 | #' If `times` is given, this defaults to `"repX"`, with `X` counting up from 1. 18 | #' @param postfix (`logical(1)`)\cr 19 | #' Whether to use `affixes` as a postfix instead of a prefix. 20 | #' Default `FALSE` (use prefixes). 21 | #' @param tag_sets (`logical(1)`)\cr 22 | #' Whether to add a tag of the form `"set_"` to each parameter in the result, indicating the repetition each parameter belongs to. 23 | #' @param tag_params (`logical(1)`)\cr 24 | #' Whether to add a tag of the form `"param_"` to each parameter in the result, indicating the original parameter ID inside `set`. 25 | #' @examples 26 | #' pset = ps( 27 | #' i = p_int(), 28 | #' z = p_lgl() 29 | #' ) 30 | #' 31 | #' ps_replicate(pset, 3) 32 | #' 33 | #' ps_replicate(pset, affixes = c("first", "last")) 34 | #' 35 | #' ps_replicate(pset, affixes = c("first", "last"), postfix = TRUE) 36 | #' 37 | #' pset$values = list(i = 1, z = FALSE) 38 | #' 39 | #' psr = ps_replicate(pset, 2, tag_sets = TRUE, tag_params = TRUE) 40 | #' 41 | #' # observe the effect of tag_sets, tag_params: 42 | #' psr$tags 43 | #' 44 | #' # note that values are repeated as well 45 | #' psr$values 46 | #' 47 | #' psr$set_values(rep1.i = 10, rep2.z = TRUE) 48 | #' psr$values 49 | #' 50 | #' # use `any_tags` to get subset of values. 51 | #' # `any_tags = ` is preferable to `tags = `, since parameters 52 | #' # could also have other tags. `tags = ` would require the 53 | #' # selected params to have the given tags exclusively. 54 | #' 55 | #' # get all values associated with the original parameter `i` 56 | #' psr$get_values(any_tags = "param_i") 57 | #' 58 | #' # get all values associated with the first repetition "rep1" 59 | #' psr$get_values(any_tags = "set_rep1") 60 | #' @export 61 | ps_replicate = function(set, times = length(affixes), affixes = sprintf("rep%s", seq_len(times)), postfix = FALSE, tag_sets = FALSE, tag_params = FALSE) { 62 | assert_count(times) 63 | assert_character(affixes, any.missing = FALSE, unique = TRUE, len = times) 64 | assert_flag(postfix) 65 | 66 | ps_union(named_list(affixes, set), postfix_names = postfix, tag_sets = tag_sets, tag_params = tag_params) 67 | } 68 | -------------------------------------------------------------------------------- /R/ps_union.R: -------------------------------------------------------------------------------- 1 | #' @title Create a ParamSet from a list of ParamSets 2 | #' 3 | #' @description 4 | #' This emulates `ParamSetCollection$new(sets)`, except that the result is a flat [`ParamSet`], not a [`ParamSetCollection`]. 5 | #' The resulting object is decoupled from the input [`ParamSet`] objects: Unlike [`ParamSetCollection`], changing `$values` of 6 | #' the resulting object will not change the input [`ParamSet`] `$values` by reference. 7 | #' 8 | #' This emulates `ParamSetCollection$new(sets)`, which in particular means that the resulting [`ParamSet`] has all the [`Domain`]s 9 | #' from the input `sets`, but some `$id`s are changed: If the [`ParamSet`] is given in `sets` with a name, then the [`Domain`]s will 10 | #' have their `` changed to `.`. This is also reflected in deps. 11 | #' 12 | #' The `c()` operator, applied to [`ParamSet`]s, is a synony for `ps_union()`. 13 | #' The named arguments `tag_sets`, `tag_params`, and `postfix_names` are also available in the `c()` operator, but need to be 14 | #' used with a preceding dot instead: `.tag_sets`, `.tag_params`, and `.postfix_names`. 15 | #' @param sets (`list` of [`ParamSet`])\cr 16 | #' This may be a named list, in which case non-empty names are prefixed to parameters in the corresponding [`ParamSet`]. 17 | #' @param tag_sets (`logical(1)`)\cr 18 | #' Whether to add tags of the form `"set_"` to each parameter originating from a given `ParamSet` given with name ``. 19 | #' @param tag_params (`logical(1)`)\cr 20 | #' Whether to add tags of the form `"param_"` to each parameter with original ID ``. 21 | #' @param postfix_names (`logical(1)`)\cr 22 | #' Whether to use names in `sets` as postfixes, instead of prefixes. 23 | #' Default `FALSE`. 24 | #' @examples 25 | #' ps1 = ps(x = p_dbl()) 26 | #' ps1$values = list(x = 1) 27 | #' 28 | #' ps2 = ps(y = p_lgl()) 29 | #' 30 | #' pu = ps_union(list(ps1, ps2)) 31 | #' # same as: 32 | #' pu = c(ps1, ps2) 33 | #' 34 | #' pu 35 | #' 36 | #' pu$values 37 | #' 38 | #' pu$values$x = 2 39 | #' pu$values 40 | #' 41 | #' # p1 is unchanged: 42 | #' ps1$values 43 | #' 44 | #' # Prefixes automatically created for named elements. 45 | #' # This allows repeating components. 46 | #' pu2 = c(one = ps1, two = ps1, ps2) 47 | #' pu2 48 | #' 49 | #' pu2$values 50 | #' 51 | #' pu3 = c(one = ps1, two = ps1, ps2, .postfix_names = TRUE) 52 | #' pu3 53 | #' 54 | #' 55 | #' @export 56 | ps_union = function(sets, tag_sets = FALSE, tag_params = FALSE, postfix_names = FALSE) { 57 | assert_list(sets, types = "ParamSet") 58 | if (!length(sets)) return(ParamSet$new()) 59 | ParamSetCollection$new(sets, tag_sets = tag_sets, tag_params = tag_params, postfix_names = postfix_names)$flatten() 60 | } 61 | 62 | #' @export 63 | c.ParamSet = function(..., .tag_sets = FALSE, .tag_params = FALSE, .postfix_names = FALSE) { 64 | ps_union(list(...), tag_sets = .tag_sets, tag_params = .tag_params, postfix_names = .postfix_names) 65 | } 66 | -------------------------------------------------------------------------------- /R/reexports.R: -------------------------------------------------------------------------------- 1 | #' @importFrom data.table as.data.table 2 | #' @export 3 | data.table::as.data.table 4 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | #' @import data.table 2 | #' @import checkmate 3 | #' @import mlr3misc 4 | #' @importFrom R6 R6Class is.R6Class 5 | #' @importFrom stats runif rnorm 6 | #' @importFrom methods is 7 | "_PACKAGE" 8 | 9 | 10 | 11 | # data.table-variables to announce: 12 | # .init_given, .trafo 13 | 14 | utils::globalVariables(c("J", "id", "original_id", "owner_ps_index", ".tags", "tag", ".trafo", "trafo", ".", "cargo", "default", "cls", "cond", "on")) 15 | 16 | .onLoad = function(libname, pkgname) { # nolint 17 | # nocov start 18 | backports::import(pkgname) 19 | 20 | register_namespace_callback(pkgname, "ParamHelpers", function(...) { 21 | warning("Packages 'paradox' and 'ParamHelpers' are conflicting and should not be loaded in the same session") 22 | }) 23 | } # nocov end 24 | 25 | leanify_package() 26 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | # paradox 6 | 7 | Package website: [release](https://paradox.mlr-org.com/) | [dev](https://paradox.mlr-org.com/dev/) 8 | 9 | Universal Parameter Space Description and Tools. 10 | 11 | 12 | [![r-cmd-check](https://github.com/mlr-org/paradox/actions/workflows/r-cmd-check.yml/badge.svg)](https://github.com/mlr-org/paradox/actions/workflows/r-cmd-check.yml) 13 | [![CRAN Status](https://www.r-pkg.org/badges/version/paradox)](https://CRAN.R-project.org/package=paradox) 14 | [![StackOverflow](https://img.shields.io/badge/stackoverflow-mlr3-orange.svg)](https://stackoverflow.com/questions/tagged/mlr3) 15 | [![Mattermost](https://img.shields.io/badge/chat-mattermost-orange.svg)](https://lmmisld-lmu-stats-slds.srv.mwn.de/mlr_invite/) 16 | 17 | 18 | ```{r setup, include=FALSE} 19 | set.seed(123) 20 | knitr::opts_chunk$set(cache = FALSE, collapse = TRUE, comment = "#>") 21 | options(datatable.print.class = FALSE, datatable.print.keys = FALSE) 22 | library(paradox) 23 | ``` 24 | 25 | ## Installation 26 | 27 | ```{r inst, eval=FALSE} 28 | remotes::install_github("mlr-org/paradox") 29 | ``` 30 | 31 | ## Usage 32 | 33 | Create a simple ParamSet using all supported Parameter Types: 34 | 35 | * integer numbers (`"int"`) 36 | * real-valued numbers (`"dbl"`) 37 | * truth values `TRUE` or `FALSE` (`"lgl"`) 38 | * categorical values from a set of possible strings (`"fct"`) 39 | * further types are only possible by using transformations. 40 | 41 | ```{r ps} 42 | pset = ps( 43 | z = p_int(lower = 1, upper = 3), 44 | x = p_dbl(lower = -10, upper = 10), 45 | flag = p_lgl(), 46 | methods = p_fct(c("a","b","c")) 47 | ) 48 | ``` 49 | 50 | Draw random samples / create random design: 51 | 52 | ```{r pssample} 53 | generate_design_random(pset, 3) 54 | ``` 55 | 56 | Generate LHS Design: 57 | 58 | ```{r pslhs} 59 | requireNamespace("lhs") 60 | generate_design_lhs(pset, 3) 61 | ``` 62 | 63 | Generate Grid Design: 64 | 65 | ```{r psgrid, R.options=list(max.print=30)} 66 | generate_design_grid(pset, resolution = 2) 67 | ``` 68 | 69 | Properties of the parameters within the `ParamSet`: 70 | 71 | ```{r psprobs} 72 | pset$ids() 73 | pset$levels 74 | pset$nlevels 75 | pset$is_number 76 | pset$lower 77 | pset$upper 78 | ``` 79 | 80 | ### Parameter Checks 81 | 82 | Check that a parameter satisfies all conditions of a `ParamSet`, using `$test()` (returns `FALSE` on mismatch), `$check()` (returns error description on mismatch), and `$assert()` (throws error on mismatch): 83 | 84 | ```{r, error = TRUE} 85 | pset$test(list(z = 1, x = 1)) 86 | pset$test(list(z = -1, x = 1)) 87 | pset$check(list(z = -1, x = 1)) 88 | pset$assert(list(z = -1, x = 1)) 89 | ``` 90 | 91 | ### Transformations 92 | 93 | Transformations are functions with a fixed signature. 94 | 95 | * `x` A named list of parameter values 96 | * `param_set` the `ParamSet` used to create the design 97 | 98 | Transformations can be used to change the distributions of sampled parameters. 99 | For example, to sample values between $2^-3$ and $2^3$ in a $log_2$-uniform distribution, one can sample uniformly between -3 and 3 and exponentiate the random value inside the transformation. 100 | Alternatively, `logscale = TRUE` can be set; in this case, `lower` and `upper` represent the values *after* the transformation. 101 | 102 | ```{r pstransscale} 103 | pset = ps( 104 | z = p_int(lower = -3, upper = 3), 105 | x = p_dbl(lower = 2^-3, upper = 2^3, logscale = TRUE) 106 | ) 107 | pset$extra_trafo = function(x, param_set) { 108 | x$z = 2^x$z 109 | return(x) 110 | } 111 | pset_smplr = SamplerUnif$new(pset) 112 | x = pset_smplr$sample(2) 113 | xst = x$transpose() 114 | xst 115 | ``` 116 | 117 | Further documentation can be found in the [in-depth tutorial](https://paradox.mlr-org.com/dev/articles/indepth.html) 118 | 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # paradox 2 | 3 | Package website: [release](https://paradox.mlr-org.com/) | [dev](https://paradox.mlr-org.com/dev/) 4 | 5 | Universal Parameter Space Description and Tools. 6 | 7 | 8 | [![r-cmd-check](https://github.com/mlr-org/paradox/actions/workflows/r-cmd-check.yml/badge.svg)](https://github.com/mlr-org/paradox/actions/workflows/r-cmd-check.yml) 9 | [![CRAN Status](https://www.r-pkg.org/badges/version/paradox)](https://CRAN.R-project.org/package=paradox) 10 | [![StackOverflow](https://img.shields.io/badge/stackoverflow-mlr3-orange.svg)](https://stackoverflow.com/questions/tagged/mlr3) 11 | [![Mattermost](https://img.shields.io/badge/chat-mattermost-orange.svg)](https://lmmisld-lmu-stats-slds.srv.mwn.de/mlr_invite/) 12 | 13 | 14 | 15 | 16 | ## Installation 17 | 18 | 19 | ```r 20 | remotes::install_github("mlr-org/paradox") 21 | ``` 22 | 23 | ## Usage 24 | 25 | Create a simple ParamSet using all supported Parameter Types: 26 | 27 | * integer numbers (`"int"`) 28 | * real-valued numbers (`"dbl"`) 29 | * truth values `TRUE` or `FALSE` (`"lgl"`) 30 | * categorical values from a set of possible strings (`"fct"`) 31 | * further types are only possible by using transformations. 32 | 33 | 34 | ```r 35 | pset = ps( 36 | z = p_int(lower = 1, upper = 3), 37 | x = p_dbl(lower = -10, upper = 10), 38 | flag = p_lgl(), 39 | methods = p_fct(c("a","b","c")) 40 | ) 41 | ``` 42 | 43 | Draw random samples / create random design: 44 | 45 | 46 | ```r 47 | generate_design_random(pset, 3) 48 | #> with 3 rows: 49 | #> z x flag methods 50 | #> 1: 1 7.660348 FALSE b 51 | #> 2: 3 8.809346 FALSE c 52 | #> 3: 2 -9.088870 FALSE b 53 | ``` 54 | 55 | Generate LHS Design: 56 | 57 | 58 | ```r 59 | requireNamespace("lhs") 60 | #> Loading required namespace: lhs 61 | generate_design_lhs(pset, 3) 62 | #> with 3 rows: 63 | #> z x flag methods 64 | #> 1: 1 -3.984673 TRUE b 65 | #> 2: 2 7.938035 FALSE a 66 | #> 3: 3 1.969783 TRUE c 67 | ``` 68 | 69 | Generate Grid Design: 70 | 71 | 72 | ```r 73 | generate_design_grid(pset, resolution = 2) 74 | #> with 24 rows: 75 | #> z x flag methods 76 | #> 1: 1 -10 TRUE a 77 | #> 2: 1 -10 TRUE b 78 | #> 3: 1 -10 TRUE c 79 | #> 4: 1 -10 FALSE a 80 | #> 5: 1 -10 FALSE b 81 | #> 6: 1 -10 FALSE c 82 | #> 7: 1 10 TRUE a 83 | #> [ reached getOption("max.print") -- omitted 18 rows ] 84 | ``` 85 | 86 | Properties of the parameters within the `ParamSet`: 87 | 88 | 89 | ```r 90 | pset$ids() 91 | #> [1] "z" "x" "flag" "methods" 92 | pset$levels 93 | #> $z 94 | #> NULL 95 | #> 96 | #> $x 97 | #> NULL 98 | #> 99 | #> $flag 100 | #> [1] TRUE FALSE 101 | #> 102 | #> $methods 103 | #> [1] "a" "b" "c" 104 | pset$nlevels 105 | #> z x flag methods 106 | #> 3 Inf 2 3 107 | pset$is_number 108 | #> z x flag methods 109 | #> TRUE TRUE FALSE FALSE 110 | pset$lower 111 | #> z x flag methods 112 | #> 1 -10 NA NA 113 | pset$upper 114 | #> z x flag methods 115 | #> 3 10 NA NA 116 | ``` 117 | 118 | ### Parameter Checks 119 | 120 | Check that a parameter satisfies all conditions of a `ParamSet`, using `$test()` (returns `FALSE` on mismatch), `$check()` (returns error description on mismatch), and `$assert()` (throws error on mismatch): 121 | 122 | 123 | ```r 124 | pset$test(list(z = 1, x = 1)) 125 | #> [1] TRUE 126 | pset$test(list(z = -1, x = 1)) 127 | #> [1] FALSE 128 | pset$check(list(z = -1, x = 1)) 129 | #> [1] "z: Element 1 is not >= 0.5" 130 | pset$assert(list(z = -1, x = 1)) 131 | #> Error in pset$assert(list(z = -1, x = 1)): Assertion on 'list(z = -1, x = 1)' failed: z: Element 1 is not >= 0.5. 132 | ``` 133 | 134 | ### Transformations 135 | 136 | Transformations are functions with a fixed signature. 137 | 138 | * `x` A named list of parameter values 139 | * `param_set` the `ParamSet` used to create the design 140 | 141 | Transformations can be used to change the distributions of sampled parameters. 142 | For example, to sample values between $2^-3$ and $2^3$ in a $log_2$-uniform distribution, one can sample uniformly between -3 and 3 and exponentiate the random value inside the transformation. 143 | Alternatively, `logscale = TRUE` can be set; in this case, `lower` and `upper` represent the values *after* the transformation. 144 | 145 | 146 | ```r 147 | pset = ps( 148 | z = p_int(lower = -3, upper = 3), 149 | x = p_dbl(lower = 2^-3, upper = 2^3, logscale = TRUE) 150 | ) 151 | pset$extra_trafo = function(x, param_set) { 152 | x$z = 2^x$z 153 | return(x) 154 | } 155 | pset_smplr = SamplerUnif$new(pset) 156 | x = pset_smplr$sample(2) 157 | xst = x$transpose() 158 | xst 159 | #> [[1]] 160 | #> [[1]]$z 161 | #> [1] 0.125 162 | #> 163 | #> [[1]]$x 164 | #> [1] 0.6985067 165 | #> 166 | #> 167 | #> [[2]] 168 | #> [[2]]$z 169 | #> [1] 0.5 170 | #> 171 | #> [[2]]$x 172 | #> [1] 0.5795772 173 | ``` 174 | 175 | Further documentation can be found in the [in-depth tutorial](https://paradox.mlr-org.com/dev/articles/indepth.html) 176 | 177 | -------------------------------------------------------------------------------- /attic/Dependency.R: -------------------------------------------------------------------------------- 1 | #' @title Param Dependency 2 | #' 3 | #' @usage NULL 4 | #' @format [R6::R6Class] object inheriting from [Param] 5 | #' 6 | #' @description 7 | #' A dependency object for a parameter, connects a subordinate parameter with 8 | #' its superordinate parent, and stores a condition on the parents value. In 9 | #' simpler words: we can encode stuff like "foo is only valid, if bar='a'". 10 | #' Constructor is mainly internally called, regular user-entry point is 11 | #' `add_dep` of [ParamSet], the param set maintains an internal list of 12 | #' Dependency objects. 13 | #' 14 | #' @section Construction: 15 | #' 16 | #' ``` 17 | #' d = Dependency$new(param, parent, cond) 18 | #' ``` 19 | #' 20 | #' * `param` :: [Param] \cr 21 | #' The dependent param. 22 | #' * `parent` :: [Param] \cr 23 | #' The (categorical) param this param depends on. 24 | #' * `cond` :: [Condition] \cr 25 | #' Condition of the dependency. 26 | #' 27 | #' @name Dependency 28 | #' @export 29 | Dependency = R6Class("Dependency", 30 | public = list( 31 | param = NULL, 32 | parent = NULL, 33 | cond = NULL, 34 | 35 | initialize = function(param, parent, cond) { 36 | self$param = assert_param(param) 37 | self$parent = assert_param(parent) 38 | self$cond = assert_r6(cond, "Condition") 39 | }, 40 | 41 | print = function(...) { 42 | catf("Dependency: For='%s', on='%s', cond='%s'", self$param$id, self$parent$id, self$cond$type) 43 | } 44 | ) 45 | ) 46 | -------------------------------------------------------------------------------- /attic/ParamS6.R: -------------------------------------------------------------------------------- 1 | 2 | #' @rdname Domain 3 | #' @export 4 | p_s6 = function(support, special_vals = list(), default = NO_DEF, tags = character(), depends = NULL, trafo = NULL, init) { 5 | set = S6Cache$canonicalize(support) 6 | support_description = if (is.character(support)) support else S6Cache$set6_sane_repr(object) 7 | 8 | if ((("power" %in% names(set)) && set$power != 1) || set$class %nin% c("numeric", "integer")) { 9 | storage_type = "list" 10 | } else { 11 | storage_type = set$class 12 | } 13 | 14 | Domain(cls = "ParamSet6", grouping = support_description, 15 | cargo = set, 16 | lower = suppressWarnings(as.numeric(set$lower)), 17 | upper = suppressWarnings(as.numeric(set$upper)), 18 | levels = as.list(set$elements), 19 | special_vals = special_vals, 20 | default = default, 21 | tags = tags, 22 | trafo = trafo, 23 | storage_type = storage_type, 24 | depends_expr = substitute(depends), 25 | init = init) 26 | } 27 | 28 | #' @export 29 | domain_check.ParamSet6 = function(param, values) { 30 | # we can rely on 'grouping' always giving us the same class 31 | set = set6_cache_get(param$grouping[[1]]) 32 | if (set$contains(values, all = TRUE)) { 33 | return(TRUE) 34 | } 35 | nomatches = param$id[!set$contains(values, all = FALSE)] 36 | sprintf("%s: not contained in %s.", str_collapse(nomatches, sep = ", "), set$strprint()) 37 | } 38 | 39 | #' @export 40 | domain_nlevels.ParamSet6 = function(param) { 41 | # we can rely on 'grouping' always giving us the same class 42 | set = set6_cache_get(param$grouping[[1]]) 43 | card = set$properties$cardinality 44 | card = if (!is.numeric(card)) Inf 45 | rep(card, nrow(param)) 46 | } 47 | #' @export 48 | domain_is_bounded.ParamSet6 = function(param) { 49 | # we can rely on 'grouping' always giving us the same class 50 | set = set6_cache_get(param$grouping[[1]]) 51 | card = set$properties$cardinality 52 | card = if (!is.numeric(card)) Inf 53 | boundedness = is.finite(card) || (is.finite(set$lower) && is.finite(set$upper)) 54 | rep(boundedness, nrow(param)) 55 | } 56 | #' @export 57 | domain_qunif.ParamSet6 = function(param, x) stop("undefined") 58 | 59 | 60 | #' @export 61 | domain_is_number.ParamSet6 = function(param) { 62 | param$storage_type[[1]] != "list" 63 | } 64 | #' @export 65 | domain_is_categ.ParamSet6 = function(param) { 66 | set = set6_cache_get(param$grouping[[1]]) 67 | categness = ("power" %nin% names(set) || set$power == 1) && 68 | set$class %nin% c("numeric", "integer") && is.finite(set$properties$cardinality) 69 | 70 | categness 71 | } 72 | -------------------------------------------------------------------------------- /attic/ParamSetCollectionTrafo.R: -------------------------------------------------------------------------------- 1 | active = list( 2 | #' @field trafo 3 | trafo = function() { 4 | if (!self$has_trafo) return(NULL) 5 | sets = map(private$.sets, function(s) { 6 | psids = names(s$params) 7 | if (s$set_id != "") { 8 | psids = sprintf("%s.%s", s$set_id, psids) 9 | } 10 | list( 11 | set_id = s$set_id, 12 | trafo = s$trafo, 13 | psids = psids 14 | ) 15 | }) 16 | allnames = unlist(map(sets, "psids")) 17 | crate(function(x, param_set) { 18 | results = list() 19 | for (s in sets) { 20 | trafo = s$trafo 21 | pv = x[intersect(s$psids, names(x))] 22 | if (!is.null(trafo)) { 23 | # retrieve sublist for each set, then assign it in set (after removing prefix) 24 | if (s$set_id != "") { 25 | names(pv) = substr(names(pv), nchar(s$set_id) + 2, nchar(names(pv))) 26 | } 27 | pv = trafo(pv) 28 | if (s$set_id != "") { 29 | names(pv) = sprintf("%s.%s", s$set_id, names(pv)) 30 | } 31 | } 32 | results[[length(results) + 1]] = pv 33 | } 34 | res <- c(x[setdiff(names(x), allnames)], unlist(results, recursive = FALSE)) 35 | res[c(intersect(names(res), names(x)), setdiff(names(res), names(x)))] # put the names of unchanged parameters to the front 36 | }, sets, allnames) 37 | }, 38 | 39 | has_trafo = function() { 40 | any(map_lgl(private$.sets, "has_trafo")) 41 | } 42 | ) 43 | -------------------------------------------------------------------------------- /attic/ParamSet_add.R: -------------------------------------------------------------------------------- 1 | 2 | #' @description 3 | #' Adds a single param or another set to this set, all params are cloned on-demand, 4 | #' so the input does not need to be cloned. 5 | #' 6 | #' @param p ([Param] | [ParamSet]). 7 | add = function(p) { 8 | 9 | assert_multi_class(p, c("Param", "ParamSet")) 10 | if (inherits(p, "Param")) { # level-up param to set 11 | pparams = structure(list(p), names = p$id) 12 | if (!is.null(private$.tags)) ptags = structure(list(p$param_tags), names = p$id) 13 | ptrafo = NULL 14 | pvalues = NULL 15 | pdeps = NULL 16 | } else { 17 | pparams = p$params_unid 18 | if (!is.null(private$.tags)) ptags = p$tags 19 | ptrafo = p$trafo 20 | pvalues = p$values 21 | pdeps = p$deps 22 | } 23 | 24 | nn = c(names(private$.params_unid), names(pparams)) 25 | assert_names(nn, type = "strict") 26 | if (!is.null(ptrafo)) { 27 | stop("Cannot add a param set with a trafo.") 28 | } 29 | private$.params_unid = c(private$.params_unid, pparams) 30 | private$.values = c(private$.values, pvalues) 31 | if (!is.null(private$.tags)) private$.tags = c(private$.tags, ptags) 32 | private$.deps = rbind(private$.deps, pdeps) 33 | invisible(self) 34 | }, 35 | 36 | ############## ParamSetCollection 37 | 38 | #' @description 39 | #' Adds a set to this collection. 40 | #' 41 | #' @param p ([ParamSet]). 42 | add = function(p) { 43 | assert_r6(p, "ParamSet") 44 | setnames = names(private$.sets) %??% map_chr(private$.sets, "set_id") 45 | if (p$set_id == "") { 46 | unnamed_set_parnames = map(private$.sets[setnames == ""], function(x) names(x$params_unid)) 47 | } else if (p$set_id %in% setnames) { 48 | stopf("Setid '%s' already present in collection!", p$set_id) 49 | } 50 | if (p$has_trafo) { 51 | stop("Building a collection out sets, where a ParamSet has a trafo is currently unsupported!") 52 | } 53 | pnames = names(p$params_unid) 54 | nameclashes = intersect( 55 | ifelse(p$set_id != "", sprintf("%s.%s", p$set_id, pnames), pnames), 56 | names(self$params_unid) 57 | ) 58 | if (length(nameclashes)) { 59 | stopf("Adding parameter set would lead to nameclashes: %s", str_collapse(nameclashes)) 60 | } 61 | set_addition = list(p) 62 | if (!is.null(names(private$.sets))) { 63 | # ignoring the other ParamSet's set_id in favor of names(private$.sets), so add the name here as well. 64 | names(set_addition) = p$set_id 65 | } 66 | 67 | tagsaddition = p$tags 68 | names(tagsaddition) = sprintf("%s.%s", p$set_id, names(tagsaddition)) 69 | private$.tags = c(private$.tags, tagsaddition) 70 | 71 | private$.sets = c(private$.sets, set_addition) 72 | invisible(self) 73 | }, 74 | -------------------------------------------------------------------------------- /attic/demo.R: -------------------------------------------------------------------------------- 1 | 2 | p_dbl(0, 1, init = 1) 3 | 4 | p = ps(prob = p_dbl(0, 1, init = 1), param = p_int(0, logscale = TRUE)) 5 | 6 | p$values 7 | p$values$prob = 0.5 8 | p$values 9 | p$values$param = 0 10 | p$values$param = -100 11 | 12 | 13 | -------------------------------------------------------------------------------- /attic/helper_03_OptPath.R: -------------------------------------------------------------------------------- 1 | # OptPath 2 | 3 | th_opt_path_full = function() { 4 | 5 | op = OptPath$new(param_set = th_paramset_full()) 6 | 7 | for (i in 1:10) { 8 | s = SamplerUnif$new(op$param_set) 9 | x = s$sample(1) 10 | xx = list( 11 | x = x, 12 | y = i, 13 | message = sprintf("message: %i", i), 14 | exec_time = i, 15 | extra = list(th_ex1 = i, th_ex2 = "th_ex2.string") 16 | ) 17 | # first half of optpath is without error, send 5 elements have error 18 | if (i >= 6L) 19 | xx$error = sprintf("error: %i", i) 20 | do.call(op$add, xx) 21 | } 22 | 23 | return(op) 24 | } 25 | 26 | # Multi-objective opt_path with transformations 27 | 28 | th_opt_path_multiobjective = function() { 29 | op = OptPath$new(param_set = th_paramset_repeated(), y_names = c('y1.min', 'y2.max'), minimize = c(TRUE, FALSE)) 30 | for (i in 1:10) { 31 | s = SamplerUnif$new(op$param_set) 32 | x = s$sample(1) 33 | op$add(x = x, y = c(y2.max = i, y1.min = 11-i)) 34 | } 35 | 36 | return(op) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /attic/helper_r6.R: -------------------------------------------------------------------------------- 1 | # Create a ParamSet from a list of ParamSets 2 | # This emulates `ParamSetCollection$new(sets)`, except that 3 | # - The result is a `ParamSet`, not a `ParamSetCollection` 4 | # - The ParamSets are allowed to have `$trafo`, which are collected together into a single function. 5 | # This emulates `ParamSetCollection$new(sets)`, which in particular means that the resulting ParamSet has all the Params 6 | # from the input `sets`, but some `$id`s are changed: If the ParamSet has a non-empty `set_id`, then the Params will 7 | # have their changed to .. This is also reflected in deps and in `$trafo`. 8 | # @param sets: list of ParamSet 9 | ps_union = function(sets, tag_set = FALSE, tag_params = FALSE) { 10 | assert_list(sets, types = "ParamSet") 11 | 12 | if (!ignore_ids) { 13 | names(sets) = map(sets, "set_id") 14 | } 15 | 16 | psc = ParamSetCollection$new(sets, ignore_ids = TRUE) 17 | 18 | newps = ParamSet$new()$add(psc) 19 | 20 | # This loop collects information that is needed by the trafo. 21 | # Resulting is a list of named lists, with one element per `sets` entry. Elements of the named lists are: 22 | # - trafo: trafo of the given ParamSet 23 | # - set_id: set_id of the given ParamSet 24 | # - forward_name_translation: named `character`. Names are the Param IDs of the resulting newps, 25 | # values are the Param IDs of the original Params in the `sets` argument. 26 | # E.g. if a single ParamSet with set_id "sid" and with one Param with id "pid" is given, 27 | # then this is a `c(sid.pid = "pid")`. 28 | # Why is this needed? If the $trafo() is given a value `list(sid.pid = 1)`, then 29 | # `forward_name_translation` can be used to rename this to `list(pid = 1)`, which is what the 30 | # original trafo expects. 31 | setinfo = unname(imap(keep(sets, function(x) x$has_trafo), function(s, n) { 32 | sparams = s$params_unid # avoid slow ParamSetCollection $params active binding 33 | sinfo = list( 34 | trafo = s$trafo, 35 | set_id = n, 36 | forward_name_translation = names2(sparams) 37 | ) 38 | psids = names2(sparams) 39 | if (n != "") { 40 | psids = sprintf("%s.%s", n, psids) 41 | } 42 | names(sinfo$forward_name_translation) = psids 43 | sinfo 44 | })) 45 | 46 | if (length(setinfo)) { 47 | # allnames: names of all parameters, as seen from the outside 48 | allnames = names2(unlist(map(setinfo, "forward_name_translation"))) 49 | assert_subset(allnames, names2(newps$params_unid)) # just check, this should always be the case 50 | 51 | newps$trafo = crate(function(x, param_set) { 52 | res = unlist(mlr3misc::map(setinfo, function(s) { 53 | trafo = s$trafo 54 | # get the parameter values that the current trafo should operate on, 55 | # as identified by the names in forward_name_translation 56 | pv = x[match(names(s$forward_name_translation), names(x), nomatch = 0)] 57 | 58 | # translate name from "." to "" 59 | names(pv) = s$forward_name_translation[names(pv)] 60 | pv = trafo(pv) 61 | 62 | # append prefix again. trafo() could have changed parameter names, so 63 | # we can't use any cached name_translation magic here 64 | if (s$set_id != "") { 65 | names(pv) = sprintf("%s.%s", s$set_id, names(pv)) 66 | } 67 | 68 | pv 69 | }), recursive = FALSE) 70 | 71 | # add the Params that were not translated at all, because the ParamSet doesn't know about them. 72 | res = c(mlr3misc::remove_named(x, allnames), res) 73 | 74 | res[c(intersect(names(res), names(x)), setdiff(names(res), names(x)))] # unchanged parameter names stay in order 75 | }, setinfo, allnames) 76 | } 77 | newps 78 | } 79 | -------------------------------------------------------------------------------- /attic/performance.R: -------------------------------------------------------------------------------- 1 | 2 | devtools::load_all() 3 | library("mlr3") 4 | devtools::load_all("../mlr3pipelines") 5 | 6 | 7 | microbenchmark::microbenchmark(as_learner(ppl("greplicate", po("subsample") %>>% lrn("classif.rpart"), 10) %>>% po("classifavg")), times = 10) 8 | # Original: 9 | ## min lq mean median uq max neval 10 | ## 8.053063 8.8598 9.449606 9.150274 9.858639 11.94355 10 11 | 12 | # Caching self$params access: 13 | ## min lq mean median uq max neval 14 | ## 1.401022 1.545326 1.738911 1.628105 1.9469 2.173466 10 15 | # (Median improved 5.6x) 16 | 17 | # Avoiding self$ids() call: 18 | ## min lq mean median uq max neval 19 | ## 1.013816 1.034226 1.119859 1.076886 1.243257 1.276072 10 20 | # (Median further improved 1.5x) 21 | 22 | profvis::profvis(as_learner(ppl("greplicate", po("subsample") %>>% lrn("classif.rpart"), 10) %>>% po("classifavg"))) 23 | # Original: 24 | # 7690 ms 25 | # Caching self$params access: 26 | # 1490 ms 27 | # Avoiding self$ids(): 28 | # 1020 ms 29 | # Most of the runtime is spent in construction and `%>>%` now. 30 | 31 | profvis::profvis(as_learner(ppl("greplicate", po("subsample") %>>% lrn("classif.rpart"), 30) %>>% po("classifavg")), interval = 0.005) 32 | 33 | -------------------------------------------------------------------------------- /attic/samplers_visual_checks.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | devtools::load_all() 4 | 5 | 6 | ps = ParamSet$new( 7 | list( 8 | ParamDbl$new("test_cnt", lower = 0, upper = 1, special_vals = list("a"), default = "a", tags = letters[1:2]), 9 | ParamInt$new("test_int", lower = 0, upper = 10, special_vals = list("b"), default = 2, tags = letters[1:4]), 10 | ParamFct$new("test_dsc", values = letters[1:3], default = "d", special_vals = list("d"), tags = letters[2:3]), 11 | ParamLgl$new("test_lgl", special_vals = list("c"), default = FALSE, tags = letters[3:4]) 12 | ) 13 | ) 14 | 15 | ps2 = ps$clone(deep = TRUE) 16 | ps2$params$test_lgl$id = "test_lgl_2" 17 | SamplerUnif$new(ps2) # XXX 18 | 19 | # ------ 20 | 21 | s = SamplerUnif$new(ps)$sample(1000) 22 | hist(s$test_cnt, freq = TRUE) 23 | plot(table(s$test_int)) 24 | plot(table(s$test_lgl)) 25 | plot(table(s$test_dsc)) 26 | 27 | s = generate_design_lhs(ps, 1000) 28 | hist(s$test_cnt) 29 | plot(table(s$test_int)) 30 | plot(table(s$test_lgl)) 31 | plot(table(s$test_dsc)) 32 | 33 | # ------ 34 | 35 | ps2 = ParamSet$new( 36 | list( 37 | ParamDbl$new("test_cnt", lower = 0, upper = 10), 38 | ParamDbl$new("test_cnt", lower = 0, upper = 10) 39 | ) 40 | ) # FIXME: should give an error, but doesn.t 41 | 42 | # ------ 43 | 44 | ps2 = ParamSet$new( 45 | list( 46 | ParamDbl$new("test_cnt", lower = 0, upper = 10) 47 | ) 48 | ) 49 | 50 | ps2$add(ParamDbl$new("test_cnt", lower = 0, upper = 10)) # should give an Error, and does, so good. 51 | 52 | # ------ 53 | 54 | ps2 = ParamSet$new( 55 | list( 56 | ParamDbl$new("test_cnt1", lower = 0, upper = 10), 57 | ParamDbl$new("test_cnt2", lower = 0, upper = 10) 58 | ) 59 | ) 60 | 61 | s = generate_design_lhs(ps2, 1000) 62 | plot(s$test_cnt1, s$test_cnt2) 63 | 64 | s = generate_design_random(ps2, 1000) 65 | plot(s$test_cnt1, s$test_cnt2) 66 | 67 | # ------ 68 | 69 | ps2 = ParamSet$new( 70 | list( 71 | ParamInt$new("test_int1", lower = 0, upper = 10), 72 | ParamInt$new("test_int2", lower = 0, upper = 10) 73 | ) 74 | ) 75 | 76 | s = generate_design_lhs(ps2, 8000) 77 | plot(s$test_int1 + rnorm(nrow(s), sd=.2), s$test_int2 + rnorm(nrow(s), sd=.2)) 78 | 79 | s = generate_design_random(ps2, 8000) 80 | plot(s$test_int1 + rnorm(nrow(s), sd=.2), s$test_int2 + rnorm(nrow(s), sd=.2)) 81 | 82 | 83 | # ------ 84 | 85 | ps3 = ParamSet$new( 86 | list( 87 | ParamFct$new("test_dsc", values = as.character(0:9)), 88 | ParamDbl$new("test_cnt", lower = 0, upper = 10) 89 | ) 90 | ) 91 | 92 | s = generate_design_lhs(ps3, 1000) 93 | plot(s$test_dsc, s$test_cnt) 94 | 95 | ps3$add_dep("test_dsc", on = "test_dsc", CondEqual$new("0")) # FIXME: should probably give an error? 96 | 97 | # ------ 98 | 99 | 100 | ps3 = ParamSet$new( 101 | list( 102 | ParamFct$new("test_dsc", values = as.character(0:9)), 103 | ParamDbl$new("test_cnt", lower = 0, upper = 10) 104 | ) 105 | ) 106 | 107 | ps3$add_dep("test_cnt", on = "test_dsc", CondEqual$new("0")) 108 | 109 | s = generate_design_random(ps3, 1000) 110 | plot(s$test_dsc, s$test_cnt) 111 | 112 | s$test_cnt[is.na(s$test_cnt)] = -2 + runif(sum(is.na(s$test_cnt))) 113 | plot(s$test_dsc, s$test_cnt) 114 | 115 | s$test_dsc = as.numeric(s$test_dsc) + runif(nrow(s)) / 2 116 | plot(s$test_dsc, s$test_cnt) 117 | 118 | # ------ 119 | 120 | 121 | ps = ParamSet$new( 122 | list( 123 | ParamDbl$new("test_cnt", lower = 0, upper = 1, special_vals = list("a"), default = "a", tags = letters[1:2]), 124 | ParamInt$new("test_int", lower = 0, upper = 10, special_vals = list("b"), default = 2, tags = letters[1:4]), 125 | ParamFct$new("test_dsc", values = letters[1:3], default = "d", special_vals = list("d"), tags = letters[2:3]), 126 | ParamLgl$new("test_lgl", special_vals = list("c"), default = FALSE, tags = letters[3:4]) 127 | ) 128 | ) 129 | 130 | plot(Sampler1DUnif$new(ps$params$test_cnt)$sample(10)) 131 | Sampler1DUnif$new(ps$params$test_int) 132 | Sampler1DUnif$new(ps$params$test_dsc) 133 | Sampler1DUnif$new(ps$params$test_lgl) 134 | 135 | Sampler1DCateg$new(ps$params$test_dsc) 136 | plot(Sampler1DCateg$new(ps$params$test_lgl, prob = c(.1, .9))$sample(1000)) 137 | 138 | Sampler1DTruncNorm$new(ps$params$test_int) # XXX 139 | 140 | sampler = Sampler1DTruncNorm$new(ps$params$test_cnt) 141 | rnd = sampler$sample(10000000)[[1]] 142 | hist(rnd, breaks=1000) 143 | 144 | sampler$mean = .2 145 | sampler$sd = 1 146 | rnd = sampler$sample(10000000)[[1]] 147 | hist(rnd, breaks=1000) 148 | 149 | sampler$mean = -.2 150 | sampler$sd = .1 151 | rnd = sampler$sample(10000000)[[1]] 152 | hist(rnd, breaks=1000) 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /attic/sugar.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | p_dbl = function(id, lower = -Inf, upper = Inf, 4 | special_vals = list(), default = NO_DEF, tags = character()) { 5 | ParamDbl$new(id, lower, upper, special_vals, default, tags) 6 | } 7 | 8 | p_int = function(id, lower = -Inf, upper = Inf, 9 | special_vals = list(), default = NO_DEF, tags = character()) { 10 | ParamInt$new(id, lower, upper, special_vals, default, tags) 11 | } 12 | 13 | p_fct = function(id, levels, 14 | special_vals = list(), default = NO_DEF, tags = character()) { 15 | ParamFct$new(id, levels, special_vals, default, tags) 16 | } 17 | 18 | p_lgl = function(id, 19 | special_vals = list(), default = NO_DEF, tags = character()) { 20 | ParamLgl$new(id, special_vals, default, tags) 21 | } 22 | 23 | p_uty = function(id, default = NO_DEF, tags = character(), custom_check = NULL) { 24 | ParamUty$new(id, default, tags, custom_check) 25 | } 26 | 27 | pss = function(params = named_list()) { 28 | ParamSet$new(params) 29 | } 30 | -------------------------------------------------------------------------------- /attic/test_OptPath.R: -------------------------------------------------------------------------------- 1 | context("OptPath") 2 | 3 | test_that("active bindings works", { 4 | op = th_opt_path_full() 5 | 6 | # test active bindings 7 | expect_equal(op$x_names, names(th_paramset_full()$params)) 8 | expect_equal(op$length, 10) 9 | expect_data_table(op$x) 10 | expect_equal(colnames(op$x), names(th_paramset_full()$params)) 11 | expect_data_table(op$y) 12 | expect_equal(op$y$y, 1:10) 13 | expect_equal(op$dim, 1) 14 | 15 | # sub-setting 16 | expect_class(op[dob < 6], "OptPath") 17 | expect_class(op[["timestamp"]], "POSIXct") 18 | 19 | # contents after data.frame conversion 20 | op_df = as.data.frame(op) 21 | expect_data_frame(op_df, nrow = 10, ncol = 13) 22 | expect_set_equal(colnames(op_df), c("dob", "message", "error", "transformed_x", "exec_time", "timestamp", "th_param_int", "th_param_dbl", "th_param_fct", "th_param_lgl", "y", "th_ex1", "th_ex2")) 23 | expect_equal(op_df$y, 1:10) 24 | expect_equal(op_df$th_ex1, 1:10) 25 | expect_class(op_df$timestamp, "POSIXct") 26 | }) 27 | 28 | test_that("multi-objective with trafos works", { 29 | op = th_opt_path_multiobjective() 30 | 31 | # test active bindings 32 | expect_equal(op$x_names, names(th_paramset_repeated()$params)) 33 | expect_equal(op$length, 10) 34 | expect_data_table(op$x) 35 | expect_equal(colnames(op$x), names(th_paramset_repeated()$params)) 36 | expect_data_table(op$y) 37 | expect_equal(op$y$y1.min, 10:1) 38 | expect_equal(op$y$y2.max, 1:10) 39 | expect_equal(op$dim, 2) 40 | 41 | # contents after data.frame conversion 42 | op_df = as.data.frame(op, include_extras = FALSE) 43 | expect_data_frame(op_df, nrow = 10, ncol = 7 + op$param_set$length + op$dim) 44 | expect_list(op_df$transformed_x, len = 10) 45 | }) 46 | 47 | test_that("printer works", { 48 | op = th_opt_path_full() 49 | expect_output(print(op), "x = 4") 50 | expect_output(print(op), "y = 1") 51 | expect_output(print(op), "Length = 10") 52 | expect_output(print(op), "errors: 5") 53 | }) 54 | 55 | -------------------------------------------------------------------------------- /attic/trafo.R: -------------------------------------------------------------------------------- 1 | # # usefull trafo objects 2 | # #' @export 3 | # trafo_2exp = function(x) 2^x 4 | # #' @export 5 | # trafo_exp = function(x) exp(x) 6 | # #' @export 7 | # trafo_10exp = function(x) 10^x 8 | # #' @export 9 | # trafo_log = function(x) log(x) 10 | # #' @export 11 | # trafo_getfun = function(x) get(x, mode = "function") 12 | # #' @export 13 | # trafo_getdict = function(x, dict) dict[x] 14 | -------------------------------------------------------------------------------- /attic/vectoralgorithm.R: -------------------------------------------------------------------------------- 1 | library("R6") 2 | library("paradox") 3 | library("checkmate") 4 | 5 | 6 | Strategy = R6Class("Strategy", 7 | public = list( 8 | initialize = function(param_set) { 9 | private$.param_set = param_set 10 | }, 11 | run = function(x) stop("abstract") 12 | ), 13 | active = list( 14 | param_set = function(v) { 15 | if (!missing(v) && !identical(v, private$.param_set)) stop("param_set is read-only") 16 | private$.param_set 17 | } 18 | ), 19 | private = list( 20 | .param_set = NULL 21 | ) 22 | ) 23 | 24 | StrategyVector = R6Class("StrategyVector", inherit = Strategy, 25 | public = list( 26 | components = NULL, 27 | initialize = function(components) { 28 | components = lapply(components, function(x) x$clone(deep = TRUE)) 29 | self$components = components 30 | params = lapply(seq_along(components), function(ci) { 31 | comp = components[[ci]] 32 | p = comp$param_set 33 | p$set_id = paste0("element", ci) 34 | p 35 | }) 36 | param_set = ParamSetCollection$new(params) 37 | super$initialize(param_set) 38 | }, 39 | run = function(x) { 40 | lapply(self$components, function(comp) comp$run(x)) 41 | }, 42 | run_vector = function(x) { 43 | assert_list(x, len = length(self$components)) 44 | Map(function(comp, xcomp) comp$run(xcomp), self$components, x) 45 | } 46 | ) 47 | ) 48 | 49 | c.Strategy = function(...) { 50 | components = list(...) 51 | assert_list(components, types = "Strategy") 52 | components = unlist(lapply(unname(components), function(cmp) { 53 | if (inherits(cmp, "StrategyVector")) cmp$components else list(cmp) 54 | }), recursive = FALSE) 55 | StrategyVector$new(components) 56 | } 57 | 58 | 59 | StrategyAdd = R6Class("StrategyAdd", inherit = Strategy, 60 | public = list( 61 | initialize = function() { 62 | super$initialize(ps(summand = p_dbl())) 63 | }, 64 | run = function(x) { 65 | self$param_set$get_values()$summand + x 66 | } 67 | ) 68 | ) 69 | 70 | StrategyMultiply = R6Class("StrategyMultiply", inherit = Strategy, 71 | public = list( 72 | initialize = function() { 73 | super$initialize(ps(factor = p_dbl())) 74 | }, 75 | run = function(x) { 76 | self$param_set$get_values()$factor * x 77 | } 78 | ) 79 | ) 80 | 81 | StrategyMultiplyAdd = R6Class("StrategyMultiplyAdd", inherit = Strategy, 82 | public = list( 83 | initialize = function() { 84 | super$initialize(ps(factor = p_dbl(), summand = p_dbl())) 85 | }, 86 | run = function(x) { 87 | self$param_set$get_values()$factor * x + self$param_set$get_values()$summand 88 | } 89 | ) 90 | ) 91 | 92 | 93 | 94 | sa = StrategyAdd$new() 95 | sa$param_set$values$summand = 10 96 | 97 | sm = StrategyMultiply$new() 98 | sm$param_set$values$factor = 2 99 | 100 | sam = StrategyMultiplyAdd$new() 101 | sam$param_set$values$summand = -1 102 | sam$param_set$values$factor = 4 103 | 104 | sa$run(100) # 110 105 | sm$run(100) # 200 106 | sam$run(100) # 399 107 | 108 | svec = StrategyVector$new(list(sa, sm, sam)) 109 | svec$run(100) # list(110, 200, 399) 110 | svec$run_vector(list(100, 200, 300)) # list(110, 400, 1199) 111 | 112 | c(svec, sa, sm)$run_vector(list(100, 200, 300, 400, 500)) # list(110, 400, 1199, 410, 1000) 113 | 114 | 115 | 116 | svec_long = StrategyVector$new(c( 117 | lapply(1:2000, function(x) { 118 | sa = StrategyAdd$new() 119 | sa$param_set$values$summand = x 120 | sa 121 | }), 122 | list(sm, sam) 123 | )) 124 | 125 | svec_long$run(100) 126 | # as.list(c(101:2100, 200, 399)) 127 | svec_long$run_vector(as.list(1:2002)) 128 | # as.list(c((1:2000) * 2, 4002, 8007)) 129 | 130 | 131 | -------------------------------------------------------------------------------- /attic/vectoralgorithm_ii.R: -------------------------------------------------------------------------------- 1 | library("R6") 2 | library("paradox") 3 | library("checkmate") 4 | 5 | Strategy = R6Class("Strategy", 6 | public = list( 7 | is_scalar = NULL, 8 | multiplicity = NULL, 9 | initialize = function(param_set, is_scalar = TRUE, multiplicity = FALSE) { 10 | self$is_scalar = assert_flag(is_scalar) 11 | self$multiplicity = assert_count(multiplicity, positive = TRUE) 12 | assert_true(!is_scalar || multiplicity == 1) 13 | private$param_set = param_set 14 | }, 15 | run = function(x) stop("abstract"), 16 | run_vector = function(x) { 17 | if (self$is_scalar) { 18 | stop("Scalar strategy does not vectorize.") 19 | } else { 20 | stop("abstract") 21 | } 22 | } 23 | ), 24 | active = list( 25 | param_set = function(v) { 26 | if (!missing(v) && !identical(v, private$.param_set)) stop("param_set is read-only") 27 | private$.param_set 28 | } 29 | ), 30 | private = list( 31 | .param_set = NULL 32 | ) 33 | ) 34 | 35 | 36 | StrategyHybridVector = R6Class("StrategyHybridVector", inherits = Strategy, 37 | public = list( 38 | initialize = function(param_set, multi_init = NULL) { 39 | assert_data_table(multi_init, min.rows = 1, null.ok = TRUE) 40 | if (!is.null(multi_init)) { 41 | param_set$vectorize = TRUE 42 | param_set$multiplicity = nrow(multi_init) 43 | param_set$values = multi_init 44 | is_scalar = FALSE 45 | multiplicity = param_set$multiplicity 46 | } else { 47 | is_scalar = TRUE 48 | multiplicity = 1 49 | } 50 | super$initialize(param_set, is_scalar = is_scalar, multiplicity = multiplicity) 51 | } 52 | ) 53 | ) 54 | 55 | ######## Making use of possible multiplicities 56 | StrategyVector = R6Class("Strategy", inherits = Strategy, 57 | public = list( 58 | components = NULL, 59 | chunksizes = NULL, 60 | initialize = function(components) { 61 | assert_list(components, types = "Strategy") 62 | self$components = unname(components) 63 | self$chunksizes = sapply(self$components, `[[`, "multiplicity") 64 | super$initialize(param_set = NULL, is_scalar = FALSE, multiplicity = sum(self$chunksizes) 65 | }, 66 | run = function(x) { 67 | result_listlist = lapply(self$components, function(comp) { 68 | if (comp$is_scalar) list(comp$run(x)) else comp$run(x) 69 | }) 70 | unlist(result_listlist, recursive = FALSE) 71 | }, 72 | run_vector = function(x) { 73 | assert_list(x, len = self$multiplicity) 74 | x = split(x, unname(rep(seq_along(x), self$chunksizes))) 75 | result_listlist = Map(self$components, x, f = function(comp, x) { 76 | if (comp$is_scalar) list(comp$run(x)) else comp$run(x) 77 | }) 78 | unlist(result_listlist, recursive = FALSE) 79 | } 80 | ) 81 | ) 82 | 83 | ######## as before 84 | c.Strategy = function(...) { 85 | components = list(...) 86 | assert_list(components, types = "Strategy") 87 | components = unlist(lapply(unname(components), function(cmp) { 88 | if (inherits(cmp, "StrategyVector")) cmp$components else list(cmp) 89 | }), recursive = FALSE) 90 | StrategyVector$new(components) 91 | } 92 | 93 | StrategyAdd = R6Class("StrategyAdd", inherit = StrategyHybridVector, 94 | public = list( 95 | initialize = function(multi_init = NULL) { 96 | super$initizlize(ps(summand = p_dbl()), multi_init = multi_init) 97 | }, 98 | run = function(x) { 99 | result = self$get_values()$summand + x 100 | if (!self$is_scalar) result = as.list(result) 101 | result 102 | }, 103 | run_vector = function(x) { 104 | if (self$is_scalar) stop("Scalar strategy does not vectorize.") 105 | self$run(x) 106 | } 107 | ) 108 | ) 109 | 110 | ######## quality of life 111 | c.StrategyAdd = function(...) { 112 | components = list(...) 113 | if (!test_list(components, types = "StrategyAdd")) NextMethod() 114 | StrategyAdd$new(multi_init = data.table::rbindlist(lapply(components, function(x) x$param_set$get_values(as_dt = TRUE)))) 115 | } 116 | 117 | ######## as before 118 | StrategyMultiply = R6Class("StrategyMultiply", inherit = Strategy, 119 | public = list( 120 | initialize = function() { 121 | super$initialize(ps(factor = p_dbl())) 122 | }, 123 | run = function(x) { 124 | self$get_values()$factor * x 125 | } 126 | ) 127 | ) 128 | 129 | ######## as before 130 | StrategyMultiplyAdd = R6Class("StrategyMultiplyAdd", inherit = Strategy, 131 | public = list( 132 | initialize = function() { 133 | super$initialize(ps(factor = p_dbl(), summand = p_dbl())) 134 | }, 135 | run = function(x) { 136 | self$get_values()$factor * x + self$get_values()$summand 137 | } 138 | ) 139 | ) 140 | 141 | 142 | sa = StrategyAdd$new() 143 | sa$param_set$values$summand = 10 144 | 145 | sm = StrategyMultiply$new() 146 | sm$param_set$values$factor = 2 147 | 148 | sam = StrategyMultiplyAdd$new() 149 | sam$param_set$values$summand = -1 150 | sam$param_set$values$factor = 4 151 | 152 | sa$run(100) # 110 153 | sm$run(100) # 200 154 | sam$run(100) # 399 155 | 156 | svec = StrategyVector$new(list(sa, sm, sam)) 157 | svec$run(100) # list(110, 200, 399) 158 | svec$run_vector(c(100, 200, 300)) # list(110, 400, 1199) 159 | 160 | c(svec, sa, sm)$run_vector(c(100, 200, 300, 400, 500)) # list(110, 400, 1199, 410, 1000) 161 | 162 | 163 | 164 | svec_long = StrategyVector$new(c( 165 | StrategyAdd$new(multi_init = data.table(summand = 1:2000)), 166 | list(sm, sam) 167 | )) 168 | 169 | svec_long$run(100) 170 | # as.list(c(101:2100, 200, 399)) 171 | svec_long$run_vector(1:2002) 172 | # as.list(c((1:2000) * 2, 4002, 8007)) 173 | 174 | 175 | -------------------------------------------------------------------------------- /man-roxygen/field_constraint.R: -------------------------------------------------------------------------------- 1 | #' @field constraint (`function(x)`)\cr 2 | #' Constraint function. Settable. 3 | #' This function must evaluate a named `list()` of values and determine whether it satisfies 4 | #' constraints, returning a scalar `logical(1)` value. 5 | -------------------------------------------------------------------------------- /man-roxygen/field_deps.R: -------------------------------------------------------------------------------- 1 | #' @field deps ([data.table::data.table()])\cr 2 | #' Table has cols `id` (`character(1)`) and `on` (`character(1)`) and `cond` ([Condition]). 3 | #' Lists all (direct) dependency parents of a param, through parameter IDs. 4 | #' Internally created by a call to `add_dep`. 5 | #' Settable, if you want to remove dependencies or perform other changes. 6 | -------------------------------------------------------------------------------- /man-roxygen/field_extra_trafo.R: -------------------------------------------------------------------------------- 1 | #' @field extra_trafo (`function(x, param_set)`)\cr 2 | #' Transformation function. Settable. 3 | #' User has to pass a `function(x)`, of the form\cr 4 | #' (named `list()`, [ParamSet]) -> named `list()`.\cr 5 | #' The function is responsible to transform a feasible configuration into another encoding, 6 | #' before potentially evaluating the configuration with the target algorithm. 7 | #' For the output, not many things have to hold. 8 | #' It needs to have unique names, and the target algorithm has to accept the configuration. 9 | #' For convenience, the self-paramset is also passed in, if you need some info from it (e.g. tags). 10 | #' Is NULL by default, and you can set it to NULL to switch the transformation off. 11 | -------------------------------------------------------------------------------- /man-roxygen/field_is_bounded.R: -------------------------------------------------------------------------------- 1 | #' @field is_bounded (`logical(1)`)\cr 2 | #' Are the bounds finite? 3 | #' Always `TRUE` for [`p_fct()`] and [`p_lgl()`]. 4 | #' Always `FALSE` for [`p_uty()`]. 5 | -------------------------------------------------------------------------------- /man-roxygen/field_levels.R: -------------------------------------------------------------------------------- 1 | #' @field levels (`character()` | `NULL`)\cr 2 | #' Set of allowed levels. 3 | #' Always `NULL` for [`p_dbl()`], [`p_int()`] and [`p_uty()`]. 4 | #' Always `c(TRUE, FALSE)` for [`p_lgl()`]. 5 | -------------------------------------------------------------------------------- /man-roxygen/field_lower.R: -------------------------------------------------------------------------------- 1 | #' @field lower (`numeric(1)`)\cr 2 | #' Lower bound. 3 | #' Always `NA` for [`p_fct()`], [`p_lgl()`] and [`p_uty()`]. 4 | -------------------------------------------------------------------------------- /man-roxygen/field_nlevels.R: -------------------------------------------------------------------------------- 1 | #' @field nlevels (`integer(1)` | `Inf`)\cr 2 | #' Number of categorical levels. 3 | #' Always `Inf` for [`p_dbl()`] and [`p_uty()`]. 4 | #' The number of integers in the range `[lower, upper]`, or `Inf` if unbounded for [`p_int()`]. 5 | #' Always `2` for [`p_lgl()`]. 6 | -------------------------------------------------------------------------------- /man-roxygen/field_params.R: -------------------------------------------------------------------------------- 1 | #' @field params (named `list()`)\cr 2 | #' `data.table` representing the combined [`Domain`] objects used to construct the [`ParamSet`]. 3 | #' Used for internal purpuses. 4 | #' Its use by external code is deprecated. 5 | -------------------------------------------------------------------------------- /man-roxygen/field_storage_type.R: -------------------------------------------------------------------------------- 1 | #' @field storage_type (`character(1)`)\cr 2 | #' Data type when values of this parameter are stored in a data table or sampled. 3 | #' Always `"numeric"` for [`p_dbl()`]. 4 | #' Always `"character"` for [`p_fct()`]. 5 | #' Always `"integer"` for [`p_int()`]. 6 | #' Always `"logical"` for [`p_lgl()`]. 7 | #' Always `"list"` for [`p_uty()`]. 8 | -------------------------------------------------------------------------------- /man-roxygen/field_tags.R: -------------------------------------------------------------------------------- 1 | #' @field tags (named `list()` of `character()`)\cr 2 | #' Can be used to group and subset parameters. 3 | #' Named with parameter IDs. 4 | 5 | -------------------------------------------------------------------------------- /man-roxygen/field_upper.R: -------------------------------------------------------------------------------- 1 | #' @field upper (`numeric(1)`)\cr 2 | #' Upper bound. 3 | #' Always `NA` for [`p_fct()`], [`p_lgl()`] and [`p_uty()`]. 4 | -------------------------------------------------------------------------------- /man-roxygen/field_values.R: -------------------------------------------------------------------------------- 1 | #' @field values (named `list()`)\cr 2 | #' Currently set / fixed parameter values. 3 | #' Settable, and feasibility of values will be checked when you set them. 4 | #' You do not have to set values for all parameters, but only for a subset. 5 | #' When you set values, all previously set values will be unset / removed. 6 | -------------------------------------------------------------------------------- /man-roxygen/param_custom_check.R: -------------------------------------------------------------------------------- 1 | #' @param custom_check (`function()`)\cr 2 | #' Custom function to check the feasibility. 3 | #' Function which checks the input. 4 | #' Must return 'TRUE' if the input is valid and a `character(1)` with the error message otherwise. 5 | #' This function should *not* throw an error. 6 | #' Defaults to `NULL`, which means that no check is performed. 7 | -------------------------------------------------------------------------------- /man-roxygen/param_default.R: -------------------------------------------------------------------------------- 1 | #' @param default (`any`)\cr 2 | #' Default value. Can be from the domain of the parameter or an element of 3 | #' `special_vals`. Has value [NO_DEF] if no default exists. `NULL` can be a 4 | #' valid default. 5 | #' The value has no effect on `ParamSet$values` or the behavior of 6 | #' `ParamSet$check()`, `$test()` or `$assert()`. 7 | #' The `default` is intended to be used for documentation purposes. 8 | #' ` 9 | -------------------------------------------------------------------------------- /man-roxygen/param_id.R: -------------------------------------------------------------------------------- 1 | #' @param id (`character(1)`)\cr 2 | #' Identifier of the object. 3 | -------------------------------------------------------------------------------- /man-roxygen/param_levels.R: -------------------------------------------------------------------------------- 1 | #' @param levels (`character`)\cr 2 | #' Allowed categorical values of the parameter. 3 | -------------------------------------------------------------------------------- /man-roxygen/param_lower.R: -------------------------------------------------------------------------------- 1 | #' @param lower (`numeric(1)`)\cr 2 | #' Lower bound, can be `-Inf`. 3 | -------------------------------------------------------------------------------- /man-roxygen/param_param.R: -------------------------------------------------------------------------------- 1 | #' @param param ([`ParamSet`])\cr 2 | #' Domain / support of the distribution we want to sample from. 3 | #' Must be one-dimensional. 4 | -------------------------------------------------------------------------------- /man-roxygen/param_param_set.R: -------------------------------------------------------------------------------- 1 | #' @param param_set ([ParamSet])\cr 2 | #' Domain / support of the distribution we want to sample from. 3 | #' ParamSet is cloned on construction. 4 | -------------------------------------------------------------------------------- /man-roxygen/param_special_vals.R: -------------------------------------------------------------------------------- 1 | #' @param special_vals (`list()`)\cr 2 | #' Arbitrary special values this parameter is allowed to take, to make it 3 | #' feasible. This allows extending the domain of the parameter. Note that 4 | #' these values are only used in feasibility checks, neither in generating 5 | #' designs nor sampling. 6 | -------------------------------------------------------------------------------- /man-roxygen/param_tags.R: -------------------------------------------------------------------------------- 1 | #' @param tags (`character()`)\cr 2 | #' Arbitrary tags to group and subset parameters. Some tags serve a special 3 | #' purpose:\cr 4 | #' * `"required"` implies that the parameters has to be given when setting 5 | #' `values` in [ParamSet]. 6 | -------------------------------------------------------------------------------- /man-roxygen/param_tolerance.R: -------------------------------------------------------------------------------- 1 | #' @param tolerance (`numeric(1)`)\cr 2 | #' Initializes the `$tolerance` field that determines the 3 | # tolerance of the `lower` and `upper` values. 4 | -------------------------------------------------------------------------------- /man-roxygen/param_upper.R: -------------------------------------------------------------------------------- 1 | #' @param upper (`numeric(1)`)\cr 2 | #' Upper bound can be `+Inf`. 3 | -------------------------------------------------------------------------------- /man/Condition.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Condition.R 3 | \name{condition_test} 4 | \alias{condition_test} 5 | \alias{condition_as_string} 6 | \alias{Condition} 7 | \alias{CondEqual} 8 | \alias{CondAnyOf} 9 | \title{Dependency Condition} 10 | \usage{ 11 | condition_test(cond, x) 12 | 13 | condition_as_string(cond, lhs_chr = "x") 14 | 15 | Condition(rhs, condition_format_string) 16 | } 17 | \arguments{ 18 | \item{cond}{(\code{Condition})\cr 19 | \code{Condition} to use} 20 | 21 | \item{x}{(\code{any})\cr 22 | Value to test} 23 | 24 | \item{lhs_chr}{(\code{character(1)})\cr 25 | Symbolic representation to use for \verb{} in the returned string.} 26 | 27 | \item{rhs}{(\code{any})\cr 28 | Right-hand-side of the condition.} 29 | 30 | \item{condition_format_string}{(\code{character(1)})\cr 31 | Format-string for representing the condition when pretty-printing 32 | in \code{\link[=condition_as_string]{condition_as_string()}}. 33 | Should contain two \verb{\%s}, as it is used in an \code{sprintf()}-call with 34 | two further string values.} 35 | } 36 | \description{ 37 | Condition object, to specify the condition in a dependency. 38 | } 39 | \section{Functions}{ 40 | \itemize{ 41 | \item \code{condition_test()}: Used internally. Tests whether a value satisfies a given condition. 42 | Vectorizes when \code{x} is atomic. 43 | 44 | \item \code{condition_as_string()}: Used internally. Returns a string that represents the condition for pretty 45 | printing, in the form \code{" "}, e.g. \code{"x == 3"} or 46 | \code{"param \%in\% {1, 2, 10}"}. 47 | 48 | }} 49 | \section{Currently implemented simple conditions}{ 50 | 51 | \itemize{ 52 | \item \code{CondEqual(rhs)} \cr 53 | Value must be equal to \code{rhs}. 54 | \item \code{CondAnyOf(rhs)} \cr 55 | Value must be any value of \code{rhs}. 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /man/Design.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Design.R 3 | \name{Design} 4 | \alias{Design} 5 | \title{Design of Configurations} 6 | \description{ 7 | A lightweight wrapper around a \link{ParamSet} and a \code{\link[data.table:data.table]{data.table::data.table()}}, where the 8 | latter is a design of configurations produced from the former - e.g., 9 | by calling a \code{\link[=generate_design_grid]{generate_design_grid()}} or by sampling. 10 | } 11 | \section{Public fields}{ 12 | \if{html}{\out{
}} 13 | \describe{ 14 | \item{\code{param_set}}{(\link{ParamSet}).} 15 | 16 | \item{\code{data}}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr 17 | Stored \code{data}.} 18 | } 19 | \if{html}{\out{
}} 20 | } 21 | \section{Methods}{ 22 | \subsection{Public methods}{ 23 | \itemize{ 24 | \item \href{#method-Design-new}{\code{Design$new()}} 25 | \item \href{#method-Design-format}{\code{Design$format()}} 26 | \item \href{#method-Design-print}{\code{Design$print()}} 27 | \item \href{#method-Design-transpose}{\code{Design$transpose()}} 28 | \item \href{#method-Design-clone}{\code{Design$clone()}} 29 | } 30 | } 31 | \if{html}{\out{
}} 32 | \if{html}{\out{}} 33 | \if{latex}{\out{\hypertarget{method-Design-new}{}}} 34 | \subsection{Method \code{new()}}{ 35 | Creates a new instance of this \link[R6:R6Class]{R6} class. 36 | \subsection{Usage}{ 37 | \if{html}{\out{
}}\preformatted{Design$new(param_set, data, remove_dupl)}\if{html}{\out{
}} 38 | } 39 | 40 | \subsection{Arguments}{ 41 | \if{html}{\out{
}} 42 | \describe{ 43 | \item{\code{param_set}}{(\link{ParamSet}).} 44 | 45 | \item{\code{data}}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr 46 | Stored \code{data}.} 47 | 48 | \item{\code{remove_dupl}}{(\code{logical(1)})\cr 49 | Remove duplicates?} 50 | } 51 | \if{html}{\out{
}} 52 | } 53 | } 54 | \if{html}{\out{
}} 55 | \if{html}{\out{}} 56 | \if{latex}{\out{\hypertarget{method-Design-format}{}}} 57 | \subsection{Method \code{format()}}{ 58 | Helper for print outputs. 59 | \subsection{Usage}{ 60 | \if{html}{\out{
}}\preformatted{Design$format(...)}\if{html}{\out{
}} 61 | } 62 | 63 | \subsection{Arguments}{ 64 | \if{html}{\out{
}} 65 | \describe{ 66 | \item{\code{...}}{(ignored).} 67 | } 68 | \if{html}{\out{
}} 69 | } 70 | } 71 | \if{html}{\out{
}} 72 | \if{html}{\out{}} 73 | \if{latex}{\out{\hypertarget{method-Design-print}{}}} 74 | \subsection{Method \code{print()}}{ 75 | Printer. 76 | \subsection{Usage}{ 77 | \if{html}{\out{
}}\preformatted{Design$print(...)}\if{html}{\out{
}} 78 | } 79 | 80 | \subsection{Arguments}{ 81 | \if{html}{\out{
}} 82 | \describe{ 83 | \item{\code{...}}{(ignored).} 84 | } 85 | \if{html}{\out{
}} 86 | } 87 | } 88 | \if{html}{\out{
}} 89 | \if{html}{\out{}} 90 | \if{latex}{\out{\hypertarget{method-Design-transpose}{}}} 91 | \subsection{Method \code{transpose()}}{ 92 | Converts \code{data} into a list of lists of row-configurations, 93 | possibly removes \code{NA} entries of inactive parameter values due to unsatisfied dependencies, 94 | and possibly calls the \code{trafo} function of the \link{ParamSet}. 95 | \subsection{Usage}{ 96 | \if{html}{\out{
}}\preformatted{Design$transpose(filter_na = TRUE, trafo = TRUE)}\if{html}{\out{
}} 97 | } 98 | 99 | \subsection{Arguments}{ 100 | \if{html}{\out{
}} 101 | \describe{ 102 | \item{\code{filter_na}}{(\code{logical(1)})\cr 103 | Should \code{NA} entries of inactive parameter values due to unsatisfied 104 | dependencies be removed?} 105 | 106 | \item{\code{trafo}}{(\code{logical(1)})\cr 107 | Should the \code{trafo} function of the \link{ParamSet} be called?} 108 | } 109 | \if{html}{\out{
}} 110 | } 111 | } 112 | \if{html}{\out{
}} 113 | \if{html}{\out{}} 114 | \if{latex}{\out{\hypertarget{method-Design-clone}{}}} 115 | \subsection{Method \code{clone()}}{ 116 | The objects of this class are cloneable with this method. 117 | \subsection{Usage}{ 118 | \if{html}{\out{
}}\preformatted{Design$clone(deep = FALSE)}\if{html}{\out{
}} 119 | } 120 | 121 | \subsection{Arguments}{ 122 | \if{html}{\out{
}} 123 | \describe{ 124 | \item{\code{deep}}{Whether to make a deep clone.} 125 | } 126 | \if{html}{\out{
}} 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /man/NO_DEF.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/NoDefault.R 3 | \name{NO_DEF} 4 | \alias{NO_DEF} 5 | \alias{NoDefault} 6 | \alias{is_nodefault} 7 | \title{Extra data type for "no default value"} 8 | \description{ 9 | Special new data type for no-default. 10 | Not often needed by the end-user, mainly internal. 11 | \itemize{ 12 | \item \code{NO_DEF}: Singleton object for type, used in \code{\link{Domain}} when no default is given. 13 | \item \code{is_nodefault()}: Is an object the 'no default' object? 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /man/Sampler.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler.R 3 | \name{Sampler} 4 | \alias{Sampler} 5 | \title{Sampler Class} 6 | \description{ 7 | This is the abstract base class for sampling objects like \link{Sampler1D}, \link{SamplerHierarchical} or \link{SamplerJointIndep}. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler1D}}, 12 | \code{\link{Sampler1DCateg}}, 13 | \code{\link{Sampler1DNormal}}, 14 | \code{\link{Sampler1DRfun}}, 15 | \code{\link{Sampler1DUnif}}, 16 | \code{\link{SamplerHierarchical}}, 17 | \code{\link{SamplerJointIndep}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Public fields}{ 22 | \if{html}{\out{
}} 23 | \describe{ 24 | \item{\code{param_set}}{(\code{\link{ParamSet}})\cr 25 | Domain / support of the distribution we want to sample from.} 26 | } 27 | \if{html}{\out{
}} 28 | } 29 | \section{Methods}{ 30 | \subsection{Public methods}{ 31 | \itemize{ 32 | \item \href{#method-Sampler-new}{\code{Sampler$new()}} 33 | \item \href{#method-Sampler-sample}{\code{Sampler$sample()}} 34 | \item \href{#method-Sampler-format}{\code{Sampler$format()}} 35 | \item \href{#method-Sampler-print}{\code{Sampler$print()}} 36 | \item \href{#method-Sampler-clone}{\code{Sampler$clone()}} 37 | } 38 | } 39 | \if{html}{\out{
}} 40 | \if{html}{\out{}} 41 | \if{latex}{\out{\hypertarget{method-Sampler-new}{}}} 42 | \subsection{Method \code{new()}}{ 43 | Creates a new instance of this \link[R6:R6Class]{R6} class. 44 | 45 | Note that this object is typically constructed via derived classes, 46 | e.g., \link{Sampler1D}. 47 | \subsection{Usage}{ 48 | \if{html}{\out{
}}\preformatted{Sampler$new(param_set)}\if{html}{\out{
}} 49 | } 50 | 51 | \subsection{Arguments}{ 52 | \if{html}{\out{
}} 53 | \describe{ 54 | \item{\code{param_set}}{(\code{\link{ParamSet}})\cr 55 | The \code{\link{ParamSet}} to associated with this \code{Sampler}.} 56 | } 57 | \if{html}{\out{
}} 58 | } 59 | } 60 | \if{html}{\out{
}} 61 | \if{html}{\out{}} 62 | \if{latex}{\out{\hypertarget{method-Sampler-sample}{}}} 63 | \subsection{Method \code{sample()}}{ 64 | Sample \code{n} values from the distribution. 65 | \subsection{Usage}{ 66 | \if{html}{\out{
}}\preformatted{Sampler$sample(n)}\if{html}{\out{
}} 67 | } 68 | 69 | \subsection{Arguments}{ 70 | \if{html}{\out{
}} 71 | \describe{ 72 | \item{\code{n}}{(\code{integer(1)}).} 73 | } 74 | \if{html}{\out{
}} 75 | } 76 | \subsection{Returns}{ 77 | \code{\link{Design}}. 78 | } 79 | } 80 | \if{html}{\out{
}} 81 | \if{html}{\out{}} 82 | \if{latex}{\out{\hypertarget{method-Sampler-format}{}}} 83 | \subsection{Method \code{format()}}{ 84 | Helper for print outputs. 85 | \subsection{Usage}{ 86 | \if{html}{\out{
}}\preformatted{Sampler$format(...)}\if{html}{\out{
}} 87 | } 88 | 89 | \subsection{Arguments}{ 90 | \if{html}{\out{
}} 91 | \describe{ 92 | \item{\code{...}}{(ignored).} 93 | } 94 | \if{html}{\out{
}} 95 | } 96 | } 97 | \if{html}{\out{
}} 98 | \if{html}{\out{}} 99 | \if{latex}{\out{\hypertarget{method-Sampler-print}{}}} 100 | \subsection{Method \code{print()}}{ 101 | Printer. 102 | \subsection{Usage}{ 103 | \if{html}{\out{
}}\preformatted{Sampler$print(...)}\if{html}{\out{
}} 104 | } 105 | 106 | \subsection{Arguments}{ 107 | \if{html}{\out{
}} 108 | \describe{ 109 | \item{\code{...}}{(ignored).} 110 | } 111 | \if{html}{\out{
}} 112 | } 113 | } 114 | \if{html}{\out{
}} 115 | \if{html}{\out{}} 116 | \if{latex}{\out{\hypertarget{method-Sampler-clone}{}}} 117 | \subsection{Method \code{clone()}}{ 118 | The objects of this class are cloneable with this method. 119 | \subsection{Usage}{ 120 | \if{html}{\out{
}}\preformatted{Sampler$clone(deep = FALSE)}\if{html}{\out{
}} 121 | } 122 | 123 | \subsection{Arguments}{ 124 | \if{html}{\out{
}} 125 | \describe{ 126 | \item{\code{deep}}{Whether to make a deep clone.} 127 | } 128 | \if{html}{\out{
}} 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /man/Sampler1D.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler1D.R 3 | \name{Sampler1D} 4 | \alias{Sampler1D} 5 | \title{Sampler1D Class} 6 | \description{ 7 | 1D sampler, abstract base class for Sampler like \link{Sampler1DUnif}, \link{Sampler1DRfun}, 8 | \link{Sampler1DCateg} and \link{Sampler1DNormal}. 9 | } 10 | \seealso{ 11 | Other Sampler: 12 | \code{\link{Sampler}}, 13 | \code{\link{Sampler1DCateg}}, 14 | \code{\link{Sampler1DNormal}}, 15 | \code{\link{Sampler1DRfun}}, 16 | \code{\link{Sampler1DUnif}}, 17 | \code{\link{SamplerHierarchical}}, 18 | \code{\link{SamplerJointIndep}}, 19 | \code{\link{SamplerUnif}} 20 | } 21 | \concept{Sampler} 22 | \section{Super class}{ 23 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{Sampler1D} 24 | } 25 | \section{Active bindings}{ 26 | \if{html}{\out{
}} 27 | \describe{ 28 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 29 | Returns the one-dimensional \code{\link{ParamSet}} that is sampled from.} 30 | } 31 | \if{html}{\out{
}} 32 | } 33 | \section{Methods}{ 34 | \subsection{Public methods}{ 35 | \itemize{ 36 | \item \href{#method-Sampler1D-new}{\code{Sampler1D$new()}} 37 | \item \href{#method-Sampler1D-clone}{\code{Sampler1D$clone()}} 38 | } 39 | } 40 | \if{html}{\out{ 41 |
Inherited methods 42 | 47 |
48 | }} 49 | \if{html}{\out{
}} 50 | \if{html}{\out{}} 51 | \if{latex}{\out{\hypertarget{method-Sampler1D-new}{}}} 52 | \subsection{Method \code{new()}}{ 53 | Creates a new instance of this \link[R6:R6Class]{R6} class. 54 | 55 | Note that this object is typically constructed via derived classes, 56 | e.g., \code{\link{Sampler1DUnif}}. 57 | \subsection{Usage}{ 58 | \if{html}{\out{
}}\preformatted{Sampler1D$new(param)}\if{html}{\out{
}} 59 | } 60 | 61 | \subsection{Arguments}{ 62 | \if{html}{\out{
}} 63 | \describe{ 64 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 65 | Domain / support of the distribution we want to sample from. 66 | Must be one-dimensional.} 67 | } 68 | \if{html}{\out{
}} 69 | } 70 | } 71 | \if{html}{\out{
}} 72 | \if{html}{\out{}} 73 | \if{latex}{\out{\hypertarget{method-Sampler1D-clone}{}}} 74 | \subsection{Method \code{clone()}}{ 75 | The objects of this class are cloneable with this method. 76 | \subsection{Usage}{ 77 | \if{html}{\out{
}}\preformatted{Sampler1D$clone(deep = FALSE)}\if{html}{\out{
}} 78 | } 79 | 80 | \subsection{Arguments}{ 81 | \if{html}{\out{
}} 82 | \describe{ 83 | \item{\code{deep}}{Whether to make a deep clone.} 84 | } 85 | \if{html}{\out{
}} 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /man/Sampler1DCateg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler1D.R 3 | \name{Sampler1DCateg} 4 | \alias{Sampler1DCateg} 5 | \title{Sampler1DCateg Class} 6 | \description{ 7 | Sampling from a discrete distribution, for a \code{\link{ParamSet}} containing a single \code{\link[=p_fct]{p_fct()}} or \code{\link[=p_lgl]{p_lgl()}}. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler}}, 12 | \code{\link{Sampler1D}}, 13 | \code{\link{Sampler1DNormal}}, 14 | \code{\link{Sampler1DRfun}}, 15 | \code{\link{Sampler1DUnif}}, 16 | \code{\link{SamplerHierarchical}}, 17 | \code{\link{SamplerJointIndep}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Super classes}{ 22 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{\link[paradox:Sampler1D]{paradox::Sampler1D}} -> \code{Sampler1DCateg} 23 | } 24 | \section{Public fields}{ 25 | \if{html}{\out{
}} 26 | \describe{ 27 | \item{\code{prob}}{(\code{numeric()} | NULL)\cr 28 | Numeric vector of \code{param$nlevels} probabilities.} 29 | } 30 | \if{html}{\out{
}} 31 | } 32 | \section{Methods}{ 33 | \subsection{Public methods}{ 34 | \itemize{ 35 | \item \href{#method-Sampler1DCateg-new}{\code{Sampler1DCateg$new()}} 36 | \item \href{#method-Sampler1DCateg-clone}{\code{Sampler1DCateg$clone()}} 37 | } 38 | } 39 | \if{html}{\out{ 40 |
Inherited methods 41 | 46 |
47 | }} 48 | \if{html}{\out{
}} 49 | \if{html}{\out{}} 50 | \if{latex}{\out{\hypertarget{method-Sampler1DCateg-new}{}}} 51 | \subsection{Method \code{new()}}{ 52 | Creates a new instance of this \link[R6:R6Class]{R6} class. 53 | \subsection{Usage}{ 54 | \if{html}{\out{
}}\preformatted{Sampler1DCateg$new(param, prob = NULL)}\if{html}{\out{
}} 55 | } 56 | 57 | \subsection{Arguments}{ 58 | \if{html}{\out{
}} 59 | \describe{ 60 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 61 | Domain / support of the distribution we want to sample from. 62 | Must be one-dimensional.} 63 | 64 | \item{\code{prob}}{(\code{numeric()} | NULL)\cr 65 | Numeric vector of \code{param$nlevels} probabilities, which is uniform by default.} 66 | } 67 | \if{html}{\out{
}} 68 | } 69 | } 70 | \if{html}{\out{
}} 71 | \if{html}{\out{}} 72 | \if{latex}{\out{\hypertarget{method-Sampler1DCateg-clone}{}}} 73 | \subsection{Method \code{clone()}}{ 74 | The objects of this class are cloneable with this method. 75 | \subsection{Usage}{ 76 | \if{html}{\out{
}}\preformatted{Sampler1DCateg$clone(deep = FALSE)}\if{html}{\out{
}} 77 | } 78 | 79 | \subsection{Arguments}{ 80 | \if{html}{\out{
}} 81 | \describe{ 82 | \item{\code{deep}}{Whether to make a deep clone.} 83 | } 84 | \if{html}{\out{
}} 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /man/Sampler1DNormal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler1D.R 3 | \name{Sampler1DNormal} 4 | \alias{Sampler1DNormal} 5 | \title{Sampler1DNormal Class} 6 | \description{ 7 | Normal sampling (potentially truncated) for \code{\link[=p_dbl]{p_dbl()}}. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler}}, 12 | \code{\link{Sampler1D}}, 13 | \code{\link{Sampler1DCateg}}, 14 | \code{\link{Sampler1DRfun}}, 15 | \code{\link{Sampler1DUnif}}, 16 | \code{\link{SamplerHierarchical}}, 17 | \code{\link{SamplerJointIndep}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Super classes}{ 22 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{\link[paradox:Sampler1D]{paradox::Sampler1D}} -> \code{\link[paradox:Sampler1DRfun]{paradox::Sampler1DRfun}} -> \code{Sampler1DNormal} 23 | } 24 | \section{Active bindings}{ 25 | \if{html}{\out{
}} 26 | \describe{ 27 | \item{\code{mean}}{(\code{numeric(1)})\cr 28 | Mean parameter of the normal distribution.} 29 | 30 | \item{\code{sd}}{(\code{numeric(1)})\cr 31 | SD parameter of the normal distribution.} 32 | } 33 | \if{html}{\out{
}} 34 | } 35 | \section{Methods}{ 36 | \subsection{Public methods}{ 37 | \itemize{ 38 | \item \href{#method-Sampler1DNormal-new}{\code{Sampler1DNormal$new()}} 39 | \item \href{#method-Sampler1DNormal-clone}{\code{Sampler1DNormal$clone()}} 40 | } 41 | } 42 | \if{html}{\out{ 43 |
Inherited methods 44 | 49 |
50 | }} 51 | \if{html}{\out{
}} 52 | \if{html}{\out{}} 53 | \if{latex}{\out{\hypertarget{method-Sampler1DNormal-new}{}}} 54 | \subsection{Method \code{new()}}{ 55 | Creates a new instance of this \link[R6:R6Class]{R6} class. 56 | \subsection{Usage}{ 57 | \if{html}{\out{
}}\preformatted{Sampler1DNormal$new(param, mean = NULL, sd = NULL)}\if{html}{\out{
}} 58 | } 59 | 60 | \subsection{Arguments}{ 61 | \if{html}{\out{
}} 62 | \describe{ 63 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 64 | Domain / support of the distribution we want to sample from. 65 | Must be one-dimensional.} 66 | 67 | \item{\code{mean}}{(\code{numeric(1)})\cr 68 | Mean parameter of the normal distribution. 69 | Default is \verb{mean(c(param$lower, param$upper)}.} 70 | 71 | \item{\code{sd}}{(\code{numeric(1)})\cr 72 | SD parameter of the normal distribution. 73 | Default is \code{(param$upper - param$lower)/4}.} 74 | } 75 | \if{html}{\out{
}} 76 | } 77 | } 78 | \if{html}{\out{
}} 79 | \if{html}{\out{}} 80 | \if{latex}{\out{\hypertarget{method-Sampler1DNormal-clone}{}}} 81 | \subsection{Method \code{clone()}}{ 82 | The objects of this class are cloneable with this method. 83 | \subsection{Usage}{ 84 | \if{html}{\out{
}}\preformatted{Sampler1DNormal$clone(deep = FALSE)}\if{html}{\out{
}} 85 | } 86 | 87 | \subsection{Arguments}{ 88 | \if{html}{\out{
}} 89 | \describe{ 90 | \item{\code{deep}}{Whether to make a deep clone.} 91 | } 92 | \if{html}{\out{
}} 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /man/Sampler1DRfun.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler1D.R 3 | \name{Sampler1DRfun} 4 | \alias{Sampler1DRfun} 5 | \title{Sampler1DRfun Class} 6 | \description{ 7 | Arbitrary sampling from 1D RNG functions from R. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler}}, 12 | \code{\link{Sampler1D}}, 13 | \code{\link{Sampler1DCateg}}, 14 | \code{\link{Sampler1DNormal}}, 15 | \code{\link{Sampler1DUnif}}, 16 | \code{\link{SamplerHierarchical}}, 17 | \code{\link{SamplerJointIndep}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Super classes}{ 22 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{\link[paradox:Sampler1D]{paradox::Sampler1D}} -> \code{Sampler1DRfun} 23 | } 24 | \section{Public fields}{ 25 | \if{html}{\out{
}} 26 | \describe{ 27 | \item{\code{rfun}}{(\verb{function()})\cr 28 | Random number generator function.} 29 | 30 | \item{\code{trunc}}{(\code{logical(1)})\cr 31 | \code{TRUE} enables naive rejection sampling, so we stay inside of [lower, upper].} 32 | } 33 | \if{html}{\out{
}} 34 | } 35 | \section{Methods}{ 36 | \subsection{Public methods}{ 37 | \itemize{ 38 | \item \href{#method-Sampler1DRfun-new}{\code{Sampler1DRfun$new()}} 39 | \item \href{#method-Sampler1DRfun-clone}{\code{Sampler1DRfun$clone()}} 40 | } 41 | } 42 | \if{html}{\out{ 43 |
Inherited methods 44 | 49 |
50 | }} 51 | \if{html}{\out{
}} 52 | \if{html}{\out{}} 53 | \if{latex}{\out{\hypertarget{method-Sampler1DRfun-new}{}}} 54 | \subsection{Method \code{new()}}{ 55 | Creates a new instance of this \link[R6:R6Class]{R6} class. 56 | \subsection{Usage}{ 57 | \if{html}{\out{
}}\preformatted{Sampler1DRfun$new(param, rfun, trunc = TRUE)}\if{html}{\out{
}} 58 | } 59 | 60 | \subsection{Arguments}{ 61 | \if{html}{\out{
}} 62 | \describe{ 63 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 64 | Domain / support of the distribution we want to sample from. 65 | Must be one-dimensional.} 66 | 67 | \item{\code{rfun}}{(\verb{function()})\cr 68 | Random number generator function, e.g. \code{rexp} to sample from exponential distribution.} 69 | 70 | \item{\code{trunc}}{(\code{logical(1)})\cr 71 | \code{TRUE} enables naive rejection sampling, so we stay inside of [lower, upper].} 72 | } 73 | \if{html}{\out{
}} 74 | } 75 | } 76 | \if{html}{\out{
}} 77 | \if{html}{\out{}} 78 | \if{latex}{\out{\hypertarget{method-Sampler1DRfun-clone}{}}} 79 | \subsection{Method \code{clone()}}{ 80 | The objects of this class are cloneable with this method. 81 | \subsection{Usage}{ 82 | \if{html}{\out{
}}\preformatted{Sampler1DRfun$clone(deep = FALSE)}\if{html}{\out{
}} 83 | } 84 | 85 | \subsection{Arguments}{ 86 | \if{html}{\out{
}} 87 | \describe{ 88 | \item{\code{deep}}{Whether to make a deep clone.} 89 | } 90 | \if{html}{\out{
}} 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /man/Sampler1DUnif.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Sampler1D.R 3 | \name{Sampler1DUnif} 4 | \alias{Sampler1DUnif} 5 | \title{Sampler1DUnif Class} 6 | \description{ 7 | Uniform random sampler for arbitrary (bounded) parameters. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler}}, 12 | \code{\link{Sampler1D}}, 13 | \code{\link{Sampler1DCateg}}, 14 | \code{\link{Sampler1DNormal}}, 15 | \code{\link{Sampler1DRfun}}, 16 | \code{\link{SamplerHierarchical}}, 17 | \code{\link{SamplerJointIndep}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Super classes}{ 22 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{\link[paradox:Sampler1D]{paradox::Sampler1D}} -> \code{Sampler1DUnif} 23 | } 24 | \section{Methods}{ 25 | \subsection{Public methods}{ 26 | \itemize{ 27 | \item \href{#method-Sampler1DUnif-new}{\code{Sampler1DUnif$new()}} 28 | \item \href{#method-Sampler1DUnif-clone}{\code{Sampler1DUnif$clone()}} 29 | } 30 | } 31 | \if{html}{\out{ 32 |
Inherited methods 33 | 38 |
39 | }} 40 | \if{html}{\out{
}} 41 | \if{html}{\out{}} 42 | \if{latex}{\out{\hypertarget{method-Sampler1DUnif-new}{}}} 43 | \subsection{Method \code{new()}}{ 44 | Creates a new instance of this \link[R6:R6Class]{R6} class. 45 | \subsection{Usage}{ 46 | \if{html}{\out{
}}\preformatted{Sampler1DUnif$new(param)}\if{html}{\out{
}} 47 | } 48 | 49 | \subsection{Arguments}{ 50 | \if{html}{\out{
}} 51 | \describe{ 52 | \item{\code{param}}{(\code{\link{ParamSet}})\cr 53 | Domain / support of the distribution we want to sample from. 54 | Must be one-dimensional.} 55 | } 56 | \if{html}{\out{
}} 57 | } 58 | } 59 | \if{html}{\out{
}} 60 | \if{html}{\out{}} 61 | \if{latex}{\out{\hypertarget{method-Sampler1DUnif-clone}{}}} 62 | \subsection{Method \code{clone()}}{ 63 | The objects of this class are cloneable with this method. 64 | \subsection{Usage}{ 65 | \if{html}{\out{
}}\preformatted{Sampler1DUnif$clone(deep = FALSE)}\if{html}{\out{
}} 66 | } 67 | 68 | \subsection{Arguments}{ 69 | \if{html}{\out{
}} 70 | \describe{ 71 | \item{\code{deep}}{Whether to make a deep clone.} 72 | } 73 | \if{html}{\out{
}} 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /man/SamplerHierarchical.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SamplerHierarchical.R 3 | \name{SamplerHierarchical} 4 | \alias{SamplerHierarchical} 5 | \title{SamplerHierarchical Class} 6 | \description{ 7 | Hierarchical sampling for arbitrary param sets with dependencies, where the user specifies 1D samplers per param. 8 | Dependencies are topologically sorted, parameters are then sampled in topological order, 9 | and if dependencies do not hold, values are set to \code{NA} in the resulting \code{data.table}. 10 | } 11 | \seealso{ 12 | Other Sampler: 13 | \code{\link{Sampler}}, 14 | \code{\link{Sampler1D}}, 15 | \code{\link{Sampler1DCateg}}, 16 | \code{\link{Sampler1DNormal}}, 17 | \code{\link{Sampler1DRfun}}, 18 | \code{\link{Sampler1DUnif}}, 19 | \code{\link{SamplerJointIndep}}, 20 | \code{\link{SamplerUnif}} 21 | } 22 | \concept{Sampler} 23 | \section{Super class}{ 24 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{SamplerHierarchical} 25 | } 26 | \section{Public fields}{ 27 | \if{html}{\out{
}} 28 | \describe{ 29 | \item{\code{samplers}}{(\code{list()})\cr 30 | List of \code{\link{Sampler1D}} objects that gives a Sampler for each dimension in the \code{param_set}.} 31 | } 32 | \if{html}{\out{
}} 33 | } 34 | \section{Methods}{ 35 | \subsection{Public methods}{ 36 | \itemize{ 37 | \item \href{#method-SamplerHierarchical-new}{\code{SamplerHierarchical$new()}} 38 | \item \href{#method-SamplerHierarchical-clone}{\code{SamplerHierarchical$clone()}} 39 | } 40 | } 41 | \if{html}{\out{ 42 |
Inherited methods 43 | 48 |
49 | }} 50 | \if{html}{\out{
}} 51 | \if{html}{\out{}} 52 | \if{latex}{\out{\hypertarget{method-SamplerHierarchical-new}{}}} 53 | \subsection{Method \code{new()}}{ 54 | Creates a new instance of this \link[R6:R6Class]{R6} class. 55 | \subsection{Usage}{ 56 | \if{html}{\out{
}}\preformatted{SamplerHierarchical$new(param_set, samplers)}\if{html}{\out{
}} 57 | } 58 | 59 | \subsection{Arguments}{ 60 | \if{html}{\out{
}} 61 | \describe{ 62 | \item{\code{param_set}}{(\code{\link{ParamSet}})\cr 63 | The \code{\link{ParamSet}} to associated with this \code{SamplerHierarchical}.} 64 | 65 | \item{\code{samplers}}{(\code{list()})\cr 66 | List of \code{\link{Sampler1D}} objects that gives a Sampler for each dimension in the \code{param_set}.} 67 | } 68 | \if{html}{\out{
}} 69 | } 70 | } 71 | \if{html}{\out{
}} 72 | \if{html}{\out{}} 73 | \if{latex}{\out{\hypertarget{method-SamplerHierarchical-clone}{}}} 74 | \subsection{Method \code{clone()}}{ 75 | The objects of this class are cloneable with this method. 76 | \subsection{Usage}{ 77 | \if{html}{\out{
}}\preformatted{SamplerHierarchical$clone(deep = FALSE)}\if{html}{\out{
}} 78 | } 79 | 80 | \subsection{Arguments}{ 81 | \if{html}{\out{
}} 82 | \describe{ 83 | \item{\code{deep}}{Whether to make a deep clone.} 84 | } 85 | \if{html}{\out{
}} 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /man/SamplerJointIndep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SamplerJointIndep.R 3 | \name{SamplerJointIndep} 4 | \alias{SamplerJointIndep} 5 | \title{SamplerJointIndep Class} 6 | \description{ 7 | Create joint, independent sampler out of multiple other samplers. 8 | } 9 | \seealso{ 10 | Other Sampler: 11 | \code{\link{Sampler}}, 12 | \code{\link{Sampler1D}}, 13 | \code{\link{Sampler1DCateg}}, 14 | \code{\link{Sampler1DNormal}}, 15 | \code{\link{Sampler1DRfun}}, 16 | \code{\link{Sampler1DUnif}}, 17 | \code{\link{SamplerHierarchical}}, 18 | \code{\link{SamplerUnif}} 19 | } 20 | \concept{Sampler} 21 | \section{Super class}{ 22 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{SamplerJointIndep} 23 | } 24 | \section{Public fields}{ 25 | \if{html}{\out{
}} 26 | \describe{ 27 | \item{\code{samplers}}{(\code{list()})\cr 28 | List of \code{\link{Sampler}} objects.} 29 | } 30 | \if{html}{\out{
}} 31 | } 32 | \section{Methods}{ 33 | \subsection{Public methods}{ 34 | \itemize{ 35 | \item \href{#method-SamplerJointIndep-new}{\code{SamplerJointIndep$new()}} 36 | \item \href{#method-SamplerJointIndep-clone}{\code{SamplerJointIndep$clone()}} 37 | } 38 | } 39 | \if{html}{\out{ 40 |
Inherited methods 41 | 46 |
47 | }} 48 | \if{html}{\out{
}} 49 | \if{html}{\out{}} 50 | \if{latex}{\out{\hypertarget{method-SamplerJointIndep-new}{}}} 51 | \subsection{Method \code{new()}}{ 52 | Creates a new instance of this \link[R6:R6Class]{R6} class. 53 | \subsection{Usage}{ 54 | \if{html}{\out{
}}\preformatted{SamplerJointIndep$new(samplers)}\if{html}{\out{
}} 55 | } 56 | 57 | \subsection{Arguments}{ 58 | \if{html}{\out{
}} 59 | \describe{ 60 | \item{\code{samplers}}{(\code{list()})\cr 61 | List of \code{\link{Sampler}} objects.} 62 | } 63 | \if{html}{\out{
}} 64 | } 65 | } 66 | \if{html}{\out{
}} 67 | \if{html}{\out{}} 68 | \if{latex}{\out{\hypertarget{method-SamplerJointIndep-clone}{}}} 69 | \subsection{Method \code{clone()}}{ 70 | The objects of this class are cloneable with this method. 71 | \subsection{Usage}{ 72 | \if{html}{\out{
}}\preformatted{SamplerJointIndep$clone(deep = FALSE)}\if{html}{\out{
}} 73 | } 74 | 75 | \subsection{Arguments}{ 76 | \if{html}{\out{
}} 77 | \describe{ 78 | \item{\code{deep}}{Whether to make a deep clone.} 79 | } 80 | \if{html}{\out{
}} 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /man/SamplerUnif.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SamplerUnif.R 3 | \name{SamplerUnif} 4 | \alias{SamplerUnif} 5 | \title{SamplerUnif Class} 6 | \description{ 7 | Uniform random sampling for an arbitrary (bounded) \link{ParamSet}. 8 | Constructs 1 uniform sampler per parameter, then passes them to \link{SamplerHierarchical}. 9 | Hence, also works for \link{ParamSet}s sets with dependencies. 10 | } 11 | \seealso{ 12 | Other Sampler: 13 | \code{\link{Sampler}}, 14 | \code{\link{Sampler1D}}, 15 | \code{\link{Sampler1DCateg}}, 16 | \code{\link{Sampler1DNormal}}, 17 | \code{\link{Sampler1DRfun}}, 18 | \code{\link{Sampler1DUnif}}, 19 | \code{\link{SamplerHierarchical}}, 20 | \code{\link{SamplerJointIndep}} 21 | } 22 | \concept{Sampler} 23 | \section{Super classes}{ 24 | \code{\link[paradox:Sampler]{paradox::Sampler}} -> \code{\link[paradox:SamplerHierarchical]{paradox::SamplerHierarchical}} -> \code{SamplerUnif} 25 | } 26 | \section{Methods}{ 27 | \subsection{Public methods}{ 28 | \itemize{ 29 | \item \href{#method-SamplerUnif-new}{\code{SamplerUnif$new()}} 30 | \item \href{#method-SamplerUnif-clone}{\code{SamplerUnif$clone()}} 31 | } 32 | } 33 | \if{html}{\out{ 34 |
Inherited methods 35 | 40 |
41 | }} 42 | \if{html}{\out{
}} 43 | \if{html}{\out{}} 44 | \if{latex}{\out{\hypertarget{method-SamplerUnif-new}{}}} 45 | \subsection{Method \code{new()}}{ 46 | Creates a new instance of this \link[R6:R6Class]{R6} class. 47 | \subsection{Usage}{ 48 | \if{html}{\out{
}}\preformatted{SamplerUnif$new(param_set)}\if{html}{\out{
}} 49 | } 50 | 51 | \subsection{Arguments}{ 52 | \if{html}{\out{
}} 53 | \describe{ 54 | \item{\code{param_set}}{(\code{\link{ParamSet}})\cr 55 | The \code{\link{ParamSet}} to associated with this \code{SamplerUnif}.} 56 | } 57 | \if{html}{\out{
}} 58 | } 59 | } 60 | \if{html}{\out{
}} 61 | \if{html}{\out{}} 62 | \if{latex}{\out{\hypertarget{method-SamplerUnif-clone}{}}} 63 | \subsection{Method \code{clone()}}{ 64 | The objects of this class are cloneable with this method. 65 | \subsection{Usage}{ 66 | \if{html}{\out{
}}\preformatted{SamplerUnif$clone(deep = FALSE)}\if{html}{\out{
}} 67 | } 68 | 69 | \subsection{Arguments}{ 70 | \if{html}{\out{
}} 71 | \describe{ 72 | \item{\code{deep}}{Whether to make a deep clone.} 73 | } 74 | \if{html}{\out{
}} 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /man/assert_param_set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/asserts.R 3 | \name{assert_param_set} 4 | \alias{assert_param_set} 5 | \title{Assertions for Params and ParamSets} 6 | \usage{ 7 | assert_param_set( 8 | param_set, 9 | cl = NULL, 10 | no_untyped = FALSE, 11 | must_bounded = FALSE, 12 | no_deps = FALSE 13 | ) 14 | } 15 | \arguments{ 16 | \item{param_set}{(\code{\link{ParamSet}}).} 17 | 18 | \item{cl}{(\code{character()})\cr 19 | Allowed subclasses.} 20 | 21 | \item{no_untyped}{(\code{logical(1)})\cr 22 | Are untyped \code{\link{Domain}}s allowed?} 23 | 24 | \item{must_bounded}{(\code{logical(1)})\cr 25 | Only bounded \code{\link{Domain}}s allowed?} 26 | 27 | \item{no_deps}{(\code{logical(1)})\cr 28 | Are dependencies allowed?} 29 | } 30 | \value{ 31 | The checked object, invisibly. 32 | } 33 | \description{ 34 | Assertions for Params and ParamSets 35 | } 36 | -------------------------------------------------------------------------------- /man/default_values.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/default_values.R 3 | \name{default_values} 4 | \alias{default_values} 5 | \alias{default_values.ParamSet} 6 | \title{Extract Parameter Default Values} 7 | \usage{ 8 | default_values(x, ...) 9 | 10 | \method{default_values}{ParamSet}(x, ...) 11 | } 12 | \arguments{ 13 | \item{x}{(\code{any})\cr 14 | Object to extract default values from.} 15 | 16 | \item{...}{(any)\cr 17 | Additional arguments.} 18 | } 19 | \value{ 20 | \code{list()}. 21 | } 22 | \description{ 23 | Extract parameter default values. 24 | } 25 | -------------------------------------------------------------------------------- /man/domain_check.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_check} 4 | \alias{domain_check} 5 | \alias{domain_assert} 6 | \alias{domain_test} 7 | \title{Check Value Validity} 8 | \usage{ 9 | domain_check(param, values, internal = FALSE) 10 | 11 | domain_assert( 12 | param, 13 | values, 14 | internal = FALSE, 15 | .var.name = checkmate::vname(param), 16 | add = NULL 17 | ) 18 | 19 | domain_test(param, values) 20 | } 21 | \arguments{ 22 | \item{param}{(\code{Domain}).} 23 | 24 | \item{values}{(\code{any}).} 25 | 26 | \item{internal}{(\code{logical(1)})\cr 27 | When set, function arguments are not checked for plausibility and \code{special_values} are not respected. 28 | This is an optimization for internal purposes and should not be used.} 29 | } 30 | \value{ 31 | If successful \code{TRUE}, if not a string with the error message. 32 | } 33 | \description{ 34 | \pkg{checkmate}-like check-function. Check whether a list of values is feasible in the domain. 35 | A value is feasible if it is of the same \code{storage_type}, inside of the bounds or element of 36 | \code{special_vals}. \code{TuneToken}s are generally \emph{not} accepted, so they should be filtered out 37 | before the call, if present. 38 | 39 | \code{domain_check} will return \code{TRUE} for accepted values, a \code{character(1)} error message otherwise. 40 | 41 | \code{domain_test} will return \code{TRUE} for accepted values, \code{FALSE} otherwise. 42 | 43 | \code{domain_assert} will return the \code{param} argument silently for accepted values, and throw an error message otherwise. 44 | } 45 | \keyword{internal} 46 | -------------------------------------------------------------------------------- /man/domain_is_bounded.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_is_bounded} 4 | \alias{domain_is_bounded} 5 | \title{Whether a Given Domain is Bounded} 6 | \usage{ 7 | domain_is_bounded(param) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | } 12 | \value{ 13 | \code{logical}. 14 | } 15 | \description{ 16 | This should generally be \code{TRUE} when \code{lower} and \code{upper} are given and finite, or when the \code{nlevels} is finite, and \code{FALSE} otherwise. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/domain_is_categ.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_is_categ} 4 | \alias{domain_is_categ} 5 | \title{Whether a Given Domain is Categorical} 6 | \usage{ 7 | domain_is_categ(param) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | } 12 | \value{ 13 | \code{logical}. 14 | } 15 | \description{ 16 | This should generally be \code{TRUE} for categorical \code{\link{Domain}}s, such as \code{\link[=p_fct]{p_fct()}} or \code{\link[=p_lgl]{p_lgl()}}, and \code{FALSE} otherwise. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/domain_is_number.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_is_number} 4 | \alias{domain_is_number} 5 | \title{Whether a Given Domain is Numeric} 6 | \usage{ 7 | domain_is_number(param) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | } 12 | \value{ 13 | \code{logical}. 14 | } 15 | \description{ 16 | This should generally be \code{TRUE} for discrete or continuous numeric \code{\link{Domain}}s, and \code{FALSE} otherwise. 17 | } 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man/domain_nlevels.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_nlevels} 4 | \alias{domain_nlevels} 5 | \title{The Number of Levels of a Given Domain} 6 | \usage{ 7 | domain_nlevels(param) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | } 12 | \value{ 13 | \code{numeric}. 14 | } 15 | \description{ 16 | This should be the number of discrete possible levels for discrete type \code{\link{Domain}}s such as \code{\link[=p_int]{p_int()}} or \code{\link[=p_fct]{p_fct()}}, and 17 | \code{Inf} for continuous or untyped parameters. 18 | } 19 | \keyword{internal} 20 | -------------------------------------------------------------------------------- /man/domain_qunif.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_qunif} 4 | \alias{domain_qunif} 5 | \title{Transform a Numeric Value to a Sample} 6 | \usage{ 7 | domain_qunif(param, x) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | 12 | \item{x}{\code{numeric} between 0 and 1.} 13 | } 14 | \value{ 15 | \code{any} -- format depending on the \code{Domain}. 16 | } 17 | \description{ 18 | Return a valid sample from the given \code{\link{Domain}}, given a value from the interval \verb{[0, 1]}. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/domain_sanitize.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Domain_methods.R 3 | \name{domain_sanitize} 4 | \alias{domain_sanitize} 5 | \title{Map to Acceptable Value} 6 | \usage{ 7 | domain_sanitize(param, values) 8 | } 9 | \arguments{ 10 | \item{param}{(\code{Domain}).} 11 | 12 | \item{values}{(\code{any}) -- format depending on the \code{Domain}.} 13 | } 14 | \value{ 15 | \code{any} -- format depending on the \code{Domain}. 16 | } 17 | \description{ 18 | Map values that are close enough to the given \code{\link{Domain}} to values that are truly acceptable. 19 | 20 | This is used to map \code{numeric()} values that are close to but outside the acceptable interval to the interval bounds. 21 | It is also used to convert integer-valued \code{numeric} values to \code{integer} values for \code{\link[=p_int]{p_int()}}. 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /man/generate_design_grid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generate_design_grid.R 3 | \name{generate_design_grid} 4 | \alias{generate_design_grid} 5 | \title{Generate a Grid Design} 6 | \usage{ 7 | generate_design_grid(param_set, resolution = NULL, param_resolutions = NULL) 8 | } 9 | \arguments{ 10 | \item{param_set}{(\code{\link{ParamSet}}).} 11 | 12 | \item{resolution}{(\code{integer(1)})\cr 13 | Global resolution for all parameters.} 14 | 15 | \item{param_resolutions}{(named \code{integer()})\cr 16 | Resolution per \code{\link{Domain}}, named by parameter ID.} 17 | } 18 | \value{ 19 | \code{\link{Design}}. 20 | } 21 | \description{ 22 | Generate a grid with a specified resolution in the parameter space. 23 | The resolution for categorical parameters is ignored, these parameters 24 | always produce a grid over all their valid levels. 25 | For number params the endpoints of the params are always included in the grid. 26 | } 27 | \examples{ 28 | pset = ps( 29 | ratio = p_dbl(lower = 0, upper = 1), 30 | letters = p_fct(levels = letters[1:3]) 31 | ) 32 | generate_design_grid(pset, 10) 33 | } 34 | \seealso{ 35 | Other generate_design: 36 | \code{\link{generate_design_lhs}()}, 37 | \code{\link{generate_design_random}()}, 38 | \code{\link{generate_design_sobol}()} 39 | } 40 | \concept{generate_design} 41 | -------------------------------------------------------------------------------- /man/generate_design_lhs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generate_design_lhs.R 3 | \name{generate_design_lhs} 4 | \alias{generate_design_lhs} 5 | \title{Generate a Space-Filling LHS Design} 6 | \usage{ 7 | generate_design_lhs(param_set, n, lhs_fun = NULL) 8 | } 9 | \arguments{ 10 | \item{param_set}{(\code{\link{ParamSet}}).} 11 | 12 | \item{n}{(\code{integer(1)}) \cr 13 | Number of points to sample.} 14 | 15 | \item{lhs_fun}{(\verb{function(n, k)})\cr 16 | Function to use to generate a LHS sample, with n samples and k values per param. 17 | LHS functions are implemented in package \pkg{lhs}, default is to use \code{\link[lhs:maximinLHS]{lhs::maximinLHS()}}.} 18 | } 19 | \value{ 20 | \code{\link{Design}}. 21 | } 22 | \description{ 23 | Generate a space-filling design using Latin hypercube sampling. Dependent 24 | parameters whose constraints are unsatisfied generate \code{NA} entries in 25 | their respective columns. 26 | } 27 | \examples{ 28 | pset = ps( 29 | ratio = p_dbl(lower = 0, upper = 1), 30 | letters = p_fct(levels = letters[1:3]) 31 | ) 32 | 33 | if (requireNamespace("lhs", quietly = TRUE)) { 34 | generate_design_lhs(pset, 10) 35 | } 36 | } 37 | \seealso{ 38 | Other generate_design: 39 | \code{\link{generate_design_grid}()}, 40 | \code{\link{generate_design_random}()}, 41 | \code{\link{generate_design_sobol}()} 42 | } 43 | \concept{generate_design} 44 | -------------------------------------------------------------------------------- /man/generate_design_random.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generate_design_random.R 3 | \name{generate_design_random} 4 | \alias{generate_design_random} 5 | \title{Generate a Random Design} 6 | \usage{ 7 | generate_design_random(param_set, n) 8 | } 9 | \arguments{ 10 | \item{param_set}{(\code{\link{ParamSet}}).} 11 | 12 | \item{n}{(\code{integer(1)})\cr 13 | Number of points to draw randomly.} 14 | } 15 | \value{ 16 | \code{\link{Design}}. 17 | } 18 | \description{ 19 | Generates a design with randomly drawn points. 20 | Internally uses \code{\link{SamplerUnif}}, hence, also works for \link{ParamSet}s with dependencies. 21 | If dependencies do not hold, values are set to \code{NA} in the resulting data.table. 22 | } 23 | \examples{ 24 | pset = ps( 25 | ratio = p_dbl(lower = 0, upper = 1), 26 | letters = p_fct(levels = letters[1:3]) 27 | ) 28 | generate_design_random(pset, 10) 29 | } 30 | \seealso{ 31 | Other generate_design: 32 | \code{\link{generate_design_grid}()}, 33 | \code{\link{generate_design_lhs}()}, 34 | \code{\link{generate_design_sobol}()} 35 | } 36 | \concept{generate_design} 37 | -------------------------------------------------------------------------------- /man/generate_design_sobol.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generate_design_sobol.R 3 | \name{generate_design_sobol} 4 | \alias{generate_design_sobol} 5 | \title{Generate a Space-Filling Sobol Sequence Design} 6 | \usage{ 7 | generate_design_sobol(param_set, n) 8 | } 9 | \arguments{ 10 | \item{param_set}{(\code{\link{ParamSet}}).} 11 | 12 | \item{n}{(\code{integer(1)}) \cr 13 | Number of points to sample.} 14 | } 15 | \value{ 16 | \code{\link{Design}}. 17 | } 18 | \description{ 19 | Generate a space-filling design using a Sobol sequence. Dependent 20 | parameters whose constraints are unsatisfied generate \code{NA} entries in 21 | their respective columns. 22 | 23 | Uses \link[spacefillr:generate_sobol_set]{spacefillr::generate_sobol_set}. 24 | 25 | Note that non determinism is achieved by sampling the seed argument via 26 | \code{sample(.Machine$integer.max, size = 1L)}. 27 | } 28 | \examples{ 29 | pset = ps( 30 | ratio = p_dbl(lower = 0, upper = 1), 31 | letters = p_fct(levels = letters[1:3]) 32 | ) 33 | 34 | if (requireNamespace("spacefillr", quietly = TRUE)) { 35 | generate_design_sobol(pset, 10) 36 | } 37 | } 38 | \seealso{ 39 | Other generate_design: 40 | \code{\link{generate_design_grid}()}, 41 | \code{\link{generate_design_lhs}()}, 42 | \code{\link{generate_design_random}()} 43 | } 44 | \concept{generate_design} 45 | -------------------------------------------------------------------------------- /man/paradox-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/zzz.R 3 | \docType{package} 4 | \name{paradox-package} 5 | \alias{paradox} 6 | \alias{paradox-package} 7 | \title{paradox: Define and Work with Parameter Spaces for Complex Algorithms} 8 | \description{ 9 | Define parameter spaces, constraints and dependencies for arbitrary algorithms, to program on such spaces. Also includes statistical designs and random samplers. Objects are implemented as 'R6' classes. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://paradox.mlr-org.com} 15 | \item \url{https://github.com/mlr-org/paradox} 16 | \item Report bugs at \url{https://github.com/mlr-org/paradox/issues} 17 | } 18 | 19 | } 20 | \author{ 21 | \strong{Maintainer}: Martin Binder \email{mlr.developer@mb706.com} 22 | 23 | Authors: 24 | \itemize{ 25 | \item Michel Lang \email{michellang@gmail.com} (\href{https://orcid.org/0000-0001-9754-0393}{ORCID}) 26 | \item Bernd Bischl \email{bernd_bischl@gmx.net} (\href{https://orcid.org/0000-0001-6002-6980}{ORCID}) 27 | \item Jakob Richter \email{jakob1richter@gmail.com} (\href{https://orcid.org/0000-0003-4481-5554}{ORCID}) 28 | \item Xudong Sun \email{smilesun.east@gmail.com} (\href{https://orcid.org/0000-0003-3269-2307}{ORCID}) 29 | } 30 | 31 | Other contributors: 32 | \itemize{ 33 | \item Marc Becker \email{marcbecker@posteo.de} (\href{https://orcid.org/0000-0002-8115-0400}{ORCID}) [contributor] 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /man/ps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ps.R 3 | \name{ps} 4 | \alias{ps} 5 | \title{Construct a ParamSet using Short Forms} 6 | \usage{ 7 | ps( 8 | ..., 9 | .extra_trafo = NULL, 10 | .constraint = NULL, 11 | .allow_dangling_dependencies = FALSE 12 | ) 13 | } 14 | \arguments{ 15 | \item{...}{(\code{\link{Domain}})\cr 16 | Named arguments of \code{\link{Domain}} objects. The \code{\link{ParamSet}} will be constructed of the given \code{\link{Domain}}s, 17 | The names of the arguments will be used as \verb{$id()} in the resulting \code{\link{ParamSet}}.} 18 | 19 | \item{.extra_trafo}{(\verb{function(x, param_set)})\cr 20 | Transformation to set the resulting \code{\link{ParamSet}}'s \verb{$trafo} value to. This is in addition to any \code{trafo} of 21 | \code{\link{Domain}} objects given in \code{...}, and will be run \emph{after} transformations of individual parameters were performed.} 22 | 23 | \item{.constraint}{(\verb{function(x)})\cr 24 | Constraint function. 25 | When given, this function must evaluate a named \code{list()} of values and determine whether it satisfies 26 | constraints, returning a scalar \code{logical(1)} value.} 27 | 28 | \item{.allow_dangling_dependencies}{(\code{logical})\cr 29 | Whether dependencies depending on parameters that are not present should be allowed. A parameter \code{x} having 30 | \code{depends = y == 0} if \code{y} is not present in the \code{ps()} call would usually throw an error, but if dangling 31 | dependencies are allowed, the dependency is added regardless. This is usually a bad idea and mainly for internal 32 | use. Dependencies between \code{\link{ParamSet}}s when using \code{\link[=to_tune]{to_tune()}} can be realized using this.} 33 | } 34 | \value{ 35 | A \code{\link{ParamSet}} object. 36 | } 37 | \description{ 38 | The \code{ps()} short form constructor uses \code{\link{Domain}} objects (\code{p_dbl}, \code{p_fct}, ...) to construct \code{\link{ParamSet}}s in a 39 | succinct and readable way. 40 | 41 | For more specifics also see the documentation of \code{\link{Domain}}. 42 | } 43 | \examples{ 44 | pars = ps( 45 | a = p_int(0, 10), 46 | b = p_int(upper = 20), 47 | c = p_dbl(), 48 | e = p_fct(letters[1:3]), 49 | f = p_uty(custom_check = checkmate::check_function) 50 | ) 51 | print(pars) 52 | 53 | pars = ps( 54 | a = p_dbl(0, 1, trafo = exp), 55 | b = p_dbl(0, 1, trafo = exp), 56 | .extra_trafo = function(x, ps) { 57 | x$c <- x$a + x$b 58 | x 59 | } 60 | ) 61 | 62 | # See how the addition happens after exp()ing: 63 | pars$trafo(list(a = 0, b = 0)) 64 | 65 | pars$values = list( 66 | a = to_tune(ps(x = p_int(0, 1), 67 | .extra_trafo = function(x, param_set) list(a = x$x) 68 | )), 69 | # make 'y' depend on 'x', but they are defined in different ParamSets 70 | # Therefore we need to allow dangling dependencies here. 71 | b = to_tune(ps(y = p_int(0, 1, depends = x == 1), 72 | .extra_trafo = function(x, param_set) list(b = x$y), 73 | .allow_dangling_dependencies = TRUE 74 | )) 75 | ) 76 | 77 | pars$search_space() 78 | } 79 | \seealso{ 80 | Other ParamSet construction helpers: 81 | \code{\link{Domain}()}, 82 | \code{\link{to_tune}()} 83 | } 84 | \concept{ParamSet construction helpers} 85 | -------------------------------------------------------------------------------- /man/ps_replicate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ps_replicate.R 3 | \name{ps_replicate} 4 | \alias{ps_replicate} 5 | \title{Create a ParamSet by Repeating a Given ParamSet} 6 | \usage{ 7 | ps_replicate( 8 | set, 9 | times = length(affixes), 10 | affixes = sprintf("rep\%s", seq_len(times)), 11 | postfix = FALSE, 12 | tag_sets = FALSE, 13 | tag_params = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{set}{(\code{\link{ParamSet}})\cr 18 | \code{\link{ParamSet}} to use as template.} 19 | 20 | \item{times}{(\code{integer(1)})\cr 21 | Number of times to repeat \code{set}. 22 | Should not be given if \code{affixes} is provided.} 23 | 24 | \item{affixes}{(\code{character})\cr 25 | A \code{character} vector indicating the prefixes / postfixes to use for each repetition of \code{set}. 26 | Per default, these are prefixes; if \code{postfix} is \code{TRUE}, these values are postfixed instead. 27 | If this is given, \code{times} is inferred from \code{length(affixes)} and should not be given separately. 28 | If \code{times} is given, this defaults to \code{"repX"}, with \code{X} counting up from 1.} 29 | 30 | \item{postfix}{(\code{logical(1)})\cr 31 | Whether to use \code{affixes} as a postfix instead of a prefix. 32 | Default \code{FALSE} (use prefixes).} 33 | 34 | \item{tag_sets}{(\code{logical(1)})\cr 35 | Whether to add a tag of the form \code{"set_"} to each parameter in the result, indicating the repetition each parameter belongs to.} 36 | 37 | \item{tag_params}{(\code{logical(1)})\cr 38 | Whether to add a tag of the form \code{"param_"} to each parameter in the result, indicating the original parameter ID inside \code{set}.} 39 | } 40 | \description{ 41 | Repeat a \code{\link{ParamSet}} a given number of times and thus create a larger \code{\link{ParamSet}}. 42 | By default, the resulting parameters are prefixed with the string \verb{"repX.", where }X\verb{counts up from 1. It is also possible to tag parameters by their original name and by their prefix, making grouped retrieval e.g. using}$get_values()` easier. 43 | } 44 | \examples{ 45 | pset = ps( 46 | i = p_int(), 47 | z = p_lgl() 48 | ) 49 | 50 | ps_replicate(pset, 3) 51 | 52 | ps_replicate(pset, affixes = c("first", "last")) 53 | 54 | ps_replicate(pset, affixes = c("first", "last"), postfix = TRUE) 55 | 56 | pset$values = list(i = 1, z = FALSE) 57 | 58 | psr = ps_replicate(pset, 2, tag_sets = TRUE, tag_params = TRUE) 59 | 60 | # observe the effect of tag_sets, tag_params: 61 | psr$tags 62 | 63 | # note that values are repeated as well 64 | psr$values 65 | 66 | psr$set_values(rep1.i = 10, rep2.z = TRUE) 67 | psr$values 68 | 69 | # use `any_tags` to get subset of values. 70 | # `any_tags = ` is preferable to `tags = `, since parameters 71 | # could also have other tags. `tags = ` would require the 72 | # selected params to have the given tags exclusively. 73 | 74 | # get all values associated with the original parameter `i` 75 | psr$get_values(any_tags = "param_i") 76 | 77 | # get all values associated with the first repetition "rep1" 78 | psr$get_values(any_tags = "set_rep1") 79 | } 80 | -------------------------------------------------------------------------------- /man/ps_union.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ps_union.R 3 | \name{ps_union} 4 | \alias{ps_union} 5 | \title{Create a ParamSet from a list of ParamSets} 6 | \usage{ 7 | ps_union(sets, tag_sets = FALSE, tag_params = FALSE, postfix_names = FALSE) 8 | } 9 | \arguments{ 10 | \item{sets}{(\code{list} of \code{\link{ParamSet}})\cr 11 | This may be a named list, in which case non-empty names are prefixed to parameters in the corresponding \code{\link{ParamSet}}.} 12 | 13 | \item{tag_sets}{(\code{logical(1)})\cr 14 | Whether to add tags of the form \code{"set_"} to each parameter originating from a given \code{ParamSet} given with name \verb{}.} 15 | 16 | \item{tag_params}{(\code{logical(1)})\cr 17 | Whether to add tags of the form \code{"param_"} to each parameter with original ID \verb{}.} 18 | 19 | \item{postfix_names}{(\code{logical(1)})\cr 20 | Whether to use names in \code{sets} as postfixes, instead of prefixes. 21 | Default \code{FALSE}.} 22 | } 23 | \description{ 24 | This emulates \code{ParamSetCollection$new(sets)}, except that the result is a flat \code{\link{ParamSet}}, not a \code{\link{ParamSetCollection}}. 25 | The resulting object is decoupled from the input \code{\link{ParamSet}} objects: Unlike \code{\link{ParamSetCollection}}, changing \verb{$values} of 26 | the resulting object will not change the input \code{\link{ParamSet}} \verb{$values} by reference. 27 | 28 | This emulates \code{ParamSetCollection$new(sets)}, which in particular means that the resulting \code{\link{ParamSet}} has all the \code{\link{Domain}}s 29 | from the input \code{sets}, but some \verb{$id}s are changed: If the \code{\link{ParamSet}} is given in \code{sets} with a name, then the \code{\link{Domain}}s will 30 | have their \verb{} changed to \verb{.}. This is also reflected in deps. 31 | 32 | The \code{c()} operator, applied to \code{\link{ParamSet}}s, is a synony for \code{ps_union()}. 33 | The named arguments \code{tag_sets}, \code{tag_params}, and \code{postfix_names} are also available in the \code{c()} operator, but need to be 34 | used with a preceding dot instead: \code{.tag_sets}, \code{.tag_params}, and \code{.postfix_names}. 35 | } 36 | \examples{ 37 | ps1 = ps(x = p_dbl()) 38 | ps1$values = list(x = 1) 39 | 40 | ps2 = ps(y = p_lgl()) 41 | 42 | pu = ps_union(list(ps1, ps2)) 43 | # same as: 44 | pu = c(ps1, ps2) 45 | 46 | pu 47 | 48 | pu$values 49 | 50 | pu$values$x = 2 51 | pu$values 52 | 53 | # p1 is unchanged: 54 | ps1$values 55 | 56 | # Prefixes automatically created for named elements. 57 | # This allows repeating components. 58 | pu2 = c(one = ps1, two = ps1, ps2) 59 | pu2 60 | 61 | pu2$values 62 | 63 | pu3 = c(one = ps1, two = ps1, ps2, .postfix_names = TRUE) 64 | pu3 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /man/psc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ps.R 3 | \name{psc} 4 | \alias{psc} 5 | \title{Create a ParamSet Collection} 6 | \usage{ 7 | psc(...) 8 | } 9 | \arguments{ 10 | \item{...}{(any)\cr 11 | The \code{\link{ParamSet}}s from which to create the collection.} 12 | } 13 | \description{ 14 | Creates a \code{\link{ParamSetCollection}}. 15 | } 16 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reexports.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{as.data.table} 7 | \title{Objects exported from other packages} 8 | \keyword{internal} 9 | \description{ 10 | These objects are imported from other packages. Follow the links 11 | below to see their documentation. 12 | 13 | \describe{ 14 | \item{data.table}{\code{\link[data.table]{as.data.table}}} 15 | }} 16 | 17 | -------------------------------------------------------------------------------- /paradox.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /pkgdown/_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://paradox.mlr-org.com 2 | 3 | template: 4 | bootstrap: 5 5 | light-switch: true 6 | math-rendering: mathjax 7 | package: mlr3pkgdowntemplate 8 | 9 | development: 10 | mode: auto 11 | version_label: default 12 | version_tooltip: "Version" 13 | 14 | toc: 15 | depth: 3 16 | 17 | navbar: 18 | structure: 19 | left: [reference, news, book] 20 | right: [search, github, mattermost, stackoverflow, rss, lightswitch] 21 | components: 22 | home: ~ 23 | reference: 24 | icon: fa fa-file-alt 25 | text: Reference 26 | href: reference/index.html 27 | mattermost: 28 | icon: fa fa-comments 29 | href: https://lmmisld-lmu-stats-slds.srv.mwn.de/mlr_invite/ 30 | book: 31 | text: mlr3book 32 | icon: fa fa-link 33 | href: https://mlr3book.mlr-org.com 34 | stackoverflow: 35 | icon: fab fa-stack-overflow 36 | href: https://stackoverflow.com/questions/tagged/mlr 37 | rss: 38 | icon: fa-rss 39 | href: https://mlr-org.com/ 40 | tutorial: 41 | text: Tutorial 42 | href: articles/indepth.html 43 | 44 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mlr-org/paradox/1ef50b6264ea1923af4f8ef8957382632a104a98/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | if (requireNamespace("testthat", quietly = TRUE)) { 2 | library("testthat") 3 | library("paradox") 4 | test_check("paradox") 5 | } 6 | -------------------------------------------------------------------------------- /tests/testthat/helper.R: -------------------------------------------------------------------------------- 1 | `[[.R6` = function(x, i, ...) { 2 | if (exists(i, envir = x, inherits = FALSE)) { 3 | return(get(i, envir = x)) 4 | } 5 | stop("R6 class ", paste0(class(x), collapse = "/"), " does not have slot '", i, "'!") 6 | } 7 | 8 | `$.R6` = function(x, name) { 9 | if (exists(name, envir = x, inherits = FALSE)) { 10 | return(get(name, envir = x)) 11 | } 12 | stop("R6 class ", paste0(class(x), collapse = "/"), " does not have slot '", name, "'!") 13 | } 14 | -------------------------------------------------------------------------------- /tests/testthat/helper_01_params.R: -------------------------------------------------------------------------------- 1 | # Objects Used for Testing 2 | # use th_ to indicate a test helper object 3 | 4 | # Param 5 | th_param_int = function() ParamInt$new(id = "th_param_int", default = 0, lower = -10, upper = 10) 6 | th_param_nat = function() ParamInt$new(id = "th_param_nat", default = 1L, lower = 1L, upper = 4L) 7 | th_param_dbl = function() ParamDbl$new(id = "th_param_dbl", default = 0, lower = -10, upper = 10) 8 | th_param_dbl_na = function() ParamDbl$new(id = "th_param_dbl_na", default = 0, 9 | lower = -10, upper = 10, special_vals = list(NA)) 10 | th_param_fct = function() ParamFct$new(id = "th_param_fct", default = "a", levels = letters[1:3]) 11 | th_param_lgl = function() ParamLgl$new(id = "th_param_lgl", default = FALSE) 12 | th_param_uty = function() ParamUty$new(id = "th_param_uty") 13 | -------------------------------------------------------------------------------- /tests/testthat/helper_02_ParamSet.R: -------------------------------------------------------------------------------- 1 | th_paramset_dbl1 = function() { 2 | th_param_dbl() 3 | } 4 | 5 | th_paramset_full = function() { 6 | c( 7 | th_param_int(), 8 | th_param_dbl(), 9 | th_param_fct(), 10 | th_param_lgl() 11 | ) 12 | } 13 | 14 | th_paramset_untyped = function() { 15 | th_param_uty() 16 | } 17 | 18 | th_paramset_numeric = function() { 19 | c( 20 | th_param_int(), 21 | th_param_dbl() 22 | ) 23 | } 24 | 25 | th_paramset_categorical = function() { 26 | c( 27 | th_param_fct(), 28 | th_param_lgl() 29 | ) 30 | } 31 | 32 | th_paramset_repeated = function() { 33 | c( 34 | th_param_nat(), 35 | th_param_fct(), 36 | ps_replicate(th_param_dbl_na(), 4) 37 | ) 38 | } 39 | 40 | th_paramset_deps = function() { 41 | ps = th_paramset_full() 42 | ps$add_dep("th_param_fct", on = "th_param_lgl", CondEqual(TRUE)) 43 | ps$add_dep("th_param_dbl", on = "th_param_fct", CondAnyOf(c("a", "b"))) 44 | ps 45 | } 46 | -------------------------------------------------------------------------------- /tests/testthat/helper_03_domain.R: -------------------------------------------------------------------------------- 1 | 2 | # compare ParamSets, but ignore Param ID 3 | 4 | expect_equal_ps = function(a, b) { 5 | assert_class(a, "ParamSet") 6 | assert_class(b, "ParamSet") 7 | 8 | normalize_ids = function(original) { 9 | acl = original$clone(deep = TRUE) 10 | acp = acl$.__enclos_env__$private 11 | acp$.params$id = sprintf("x%s", seq_len(original$length)) 12 | names(acp$.values) = sprintf("x%s", match(names(original$values), original$ids())) 13 | acp$.tags = setkeyv(copy(acp$.tags)[, id := sprintf("x%s", match(id, original$ids()))], key(acp$.tags)) 14 | acp$.trafos = setkeyv(copy(acp$.trafos)[, id := sprintf("x%s", match(id, original$ids()))], key(acp$.trafos)) 15 | acp$.deps[, id := sprintf("x%s", match(id, original$ids()))] 16 | setindexv(acp$.params, NULL) 17 | setindexv(acp$.trafos, NULL) 18 | setindexv(acp$.tags, NULL) 19 | setindexv(acp$.deps, NULL) 20 | acl 21 | } 22 | 23 | expect_equal(normalize_ids(a), normalize_ids(b)) 24 | } 25 | 26 | reset_indices = function(p) { 27 | 28 | setindexv(p$.__enclos_env__$private$.tags, NULL) 29 | setindexv(p$.__enclos_env__$private$.trafos, NULL) 30 | setindexv(p$.__enclos_env__$private$.params, NULL) 31 | setindexv(p$.__enclos_env__$private$.deps, NULL) 32 | p 33 | } 34 | -------------------------------------------------------------------------------- /tests/testthat/helper_compat.R: -------------------------------------------------------------------------------- 1 | 2 | # compatibility to with broken testthat v3 behaviour 3 | expect_equal = function(object, expected, ..., info = NULL, label = NULL) { 4 | expect_true(all.equal(object, expected, check.environment = FALSE, ...), info = info, label = label) 5 | } 6 | 7 | # suppress warnings as long as half the world still uses v2 8 | context = function(...) suppressWarnings(testthat::context(...)) 9 | expect_is = function(...) suppressWarnings(testthat::expect_is(...)) 10 | expect_equivalent = function(...) suppressWarnings(testthat::expect_equivalent(...)) 11 | library("checkmate") 12 | 13 | 14 | ParamInt = list( 15 | new = function(id, ...) { 16 | ParamSet$new(set_names(list(p_int(...)), id)) 17 | }, 18 | classname = "ParamInt" 19 | ) 20 | 21 | ParamDbl = list( 22 | new = function(id, ...) { 23 | ParamSet$new(set_names(list(p_dbl(...)), id)) 24 | }, 25 | classname = "ParamDbl" 26 | ) 27 | 28 | ParamFct = list( 29 | new = function(id, ...) { 30 | ParamSet$new(set_names(list(p_fct(...)), id)) 31 | }, 32 | classname = "ParamFct" 33 | ) 34 | 35 | ParamLgl = list( 36 | new = function(id, ...) { 37 | ParamSet$new(set_names(list(p_lgl(...)), id)) 38 | }, 39 | classname = "ParamLgl" 40 | ) 41 | 42 | ParamUty = list( 43 | new = function(id, ...) { 44 | ParamSet$new(set_names(list(p_uty(...)), id)) 45 | }, 46 | classname = "ParamUty" 47 | ) 48 | 49 | ParamSet_legacy = list( 50 | new = function(params = list()) { 51 | ps_union(params) 52 | } 53 | ) 54 | -------------------------------------------------------------------------------- /tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | old_opts = options( 2 | warnPartialMatchArgs = TRUE, 3 | warnPartialMatchAttr = TRUE, 4 | warnPartialMatchDollar = TRUE 5 | ) 6 | 7 | # https://github.com/HenrikBengtsson/Wishlist-for-R/issues/88 8 | old_opts = lapply(old_opts, function(x) if (is.null(x)) FALSE else x) 9 | -------------------------------------------------------------------------------- /tests/testthat/teardown.R: -------------------------------------------------------------------------------- 1 | options(old_opts) 2 | -------------------------------------------------------------------------------- /tests/testthat/test_Condition.R: -------------------------------------------------------------------------------- 1 | context("Condition") 2 | 3 | test_that("Condition", { 4 | cond = CondEqual("a") 5 | y = condition_test(cond, c("a", "b", "c", NA_character_)) 6 | expect_equal(y, c(TRUE, FALSE, FALSE, FALSE)) 7 | expect_output(print(cond), fixed = "CondEqual") 8 | 9 | expect_error(CondEqual(c("a","b")), "Assertion on 'rhs' failed") 10 | expect_error(CondEqual(NA), "Assertion on 'rhs' failed") 11 | 12 | cond = CondAnyOf(c("a", "b")) 13 | y = condition_test(cond, c("a", "b", "c", NA_character_)) 14 | expect_equal(y, c(TRUE, TRUE, FALSE, FALSE)) 15 | expect_output(print(cond), fixed = "CondAnyOf") 16 | 17 | expect_error(CondAnyOf(list("a","b")), "Assertion on 'rhs' failed") 18 | expect_error(CondAnyOf(c("a", "b", NA_character_)), "Assertion on 'rhs' failed") 19 | expect_error(CondAnyOf(character()), "Assertion on 'rhs' failed") 20 | }) 21 | -------------------------------------------------------------------------------- /tests/testthat/test_Design.R: -------------------------------------------------------------------------------- 1 | context("Design") 2 | 3 | test_that("transpose works", { 4 | ps = ParamSet_legacy$new(list( 5 | ParamFct$new("f", levels = c("a", "b")), 6 | ParamInt$new("i", lower = 1, upper = 5) 7 | )) 8 | ps$add_dep("i", on = "f", CondEqual("a")) 9 | data = data.table(f = c("a", "b"), i = c(1L, NA)) 10 | d = Design$new(ps, data, remove_dupl = FALSE) 11 | xs = d$transpose(filter_na = FALSE) 12 | expect_equal(xs, list(list(f = "a", i = 1L), list(f = "b", i = NA_integer_))) 13 | xs = d$transpose(filter_na = TRUE) 14 | expect_equal(xs, list(list(f = "a", i = 1L), list(f = "b"))) 15 | xs2 = d$transpose(filter_na = TRUE, trafo = TRUE) 16 | expect_equal(xs, xs2) 17 | 18 | # now a trafo, with a dep 19 | ps$extra_trafo = function(x, param_set) { 20 | if (!is.null(x$i)) { 21 | x$i = x$i + 10 22 | } 23 | return(x) 24 | } 25 | xs = d$transpose(trafo = TRUE, filter_na = FALSE) 26 | expect_equal(xs, list(list(f = "a", i = 11L), list(f = "b", i = NA_integer_))) 27 | xs = d$transpose(trafo = TRUE, filter_na = TRUE) 28 | expect_equal(xs, list(list(f = "a", i = 11L), list(f = "b"))) 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/test_Param.R: -------------------------------------------------------------------------------- 1 | context("Param") 2 | 3 | 4 | test_that("basic properties", { 5 | p1 = ParamDbl$new("x", default = 4) 6 | p2 = ParamFct$new("y", levels = c("a", "b")) 7 | expect_equal(p1$default, list(x = 4)) 8 | expect_equal(p2$default, named_list()) 9 | expect_true(p1$is_number[["x"]]) 10 | expect_false(p2$is_number[["y"]]) 11 | expect_false(p1$is_categ[["x"]]) 12 | expect_true(p2$is_categ[["y"]]) 13 | }) 14 | 15 | test_that("check and assert work", { 16 | # test-funcion should be tested in individual test_Param files 17 | # here we briefly check all 3 to see if they work in principle 18 | p = ParamDbl$new("x", lower = 1, upper = 2) 19 | p$assert(list(x = 1)) 20 | expect_error(p$assert(list(x = 3)), "Assertion .* failed") 21 | expect_true(p$check(list(x = 1))) 22 | expect_string(p$check(list(x = 3)), fixed = "<= 2") 23 | expect_true(p$test(list(x = 1))) 24 | expect_false(p$test(list(x = 3))) 25 | }) 26 | 27 | 28 | test_that("special_vals work for all Param subclasses", { 29 | class = list(ParamFct, ParamLgl, ParamInt, ParamDbl) 30 | special_vals_list = list( 31 | list(1), 32 | list("a"), 33 | list(1:10), 34 | list("a", 1, 1:10, as.environment(list(a = 10, b = 100, c = mean))), 35 | list(mean, sum, function(x) x^10) 36 | ) 37 | for (cl in class) { 38 | for (special_vals in special_vals_list) { 39 | if (cl$classname == "ParamFct") { 40 | p = cl$new(id = paste0("test.", cl$classname), special_vals = special_vals, levels = letters[11:20]) 41 | } else { 42 | p = cl$new(id = paste0("test.", cl$classname), special_vals = special_vals) 43 | } 44 | for (special_val in special_vals) { 45 | expect_true(p$test(set_names(list(special_val), paste0("test.", cl$classname)))) 46 | expect_false(p$test(set_names(list("never valid"), paste0("test.", cl$classname)))) 47 | expect_false(p$test(set_names(list(NA), paste0("test.", cl$classname)))) 48 | expect_false(p$test(set_names(list(NULL), paste0("test.", cl$classname)))) 49 | } 50 | } 51 | } 52 | }) 53 | 54 | test_that("we cannot create Params with non-strict R names", { 55 | expect_error(ParamInt$new(id = "$foo"), "does not comply") 56 | }) 57 | -------------------------------------------------------------------------------- /tests/testthat/test_ParamDbl.R: -------------------------------------------------------------------------------- 1 | context("ParamDbl") 2 | 3 | test_that("constructor works", { 4 | p = ParamDbl$new(id = "test", lower = 1, upper = 10) 5 | expect_equal(p$ids(), "test") 6 | expect_equal(p$lower, c(test = 1)) 7 | expect_equal(p$upper, c(test = 10)) 8 | 9 | # check that we can create param with Inf bounds 10 | p = ParamDbl$new(id = "test", lower = 1) 11 | expect_equal(p$lower, c(test = 1)) 12 | expect_equal(p$upper, c(test = Inf)) 13 | 14 | # check some invalid arg settings 15 | expect_error(ParamDbl$new(id = "x", lower = NULL), "not 'NULL'") 16 | expect_error(ParamDbl$new(id = "x", lower = 1, upper = 0), "lower <= upper") 17 | expect_error(ParamDbl$new(id = "x", lower = Inf, upper = 0), "lower <= upper") 18 | }) 19 | 20 | test_that("allowing inf as feasible value works", { 21 | p = ParamDbl$new(id = "x", lower = 1, upper = 10) 22 | expect_true(p$test(list(x = 1))) 23 | expect_false(p$test(list(x = Inf))) 24 | 25 | p = ParamDbl$new(id = "x", lower = 1, special_vals = list(Inf)) 26 | expect_true(p$test(list(x = 1))) 27 | expect_true(p$test(list(x = Inf))) 28 | }) 29 | 30 | 31 | test_that("is_bounded works", { 32 | expect_true(ParamDbl$new(id = "x", lower = 1, upper = 10)$is_bounded) 33 | expect_false(ParamDbl$new(id = "x", lower = 1)$is_bounded) 34 | expect_false(ParamDbl$new(id = "x")$is_bounded) 35 | }) 36 | 37 | test_that("qunif", { 38 | set.seed(8008135) 39 | n = 50000L 40 | testit = function(a, b) { 41 | 42 | # simulate from param, simulate directly from runif 43 | # then check that the estimated ecdfs from both distribs are nearly the same (L1 dist) 44 | p = ParamDbl$new("x", lower = a, upper = b) 45 | u = runif(n) 46 | v1 = p$qunif(data.table(x = u)) 47 | expect_data_table(v1, ncols = 1, nrows = n) 48 | expect_equal(colnames(v1), "x") 49 | expect_double(v1$x, any.missing = FALSE, len = n) 50 | v2 = runif(n, min = a, max = b) 51 | e1 = ecdf(v1$x) 52 | e2 = ecdf(v2) 53 | s = seq(a, b, by = 0.0001) 54 | d = abs(e1(s) - e2(s)) 55 | expect_lte(max(d), 0.01) 56 | } 57 | testit(1, 12) 58 | testit(-2, 1) 59 | }) 60 | 61 | test_that("tolerance in check allows values at the upper bound", { 62 | p = ParamDbl$new("x", lower = log(.01), upper = log(100)) 63 | ub = p$qunif(data.table(x = 1)) 64 | expect_true(p$check_dt(ub)) 65 | expect_true(p$check(as.list(ub))) 66 | }) 67 | 68 | test_that("tolerance for setting values", { 69 | p = ParamSet_legacy$new(list(ParamDbl$new("x", lower = 0, upper = 1))) 70 | p$values$x = -1e-8 71 | expect_equal(p$values$x, 0) 72 | expect_error({p$values$x = -1e-6}, "Element 1 is not >=") 73 | }) 74 | -------------------------------------------------------------------------------- /tests/testthat/test_ParamFct.R: -------------------------------------------------------------------------------- 1 | context("ParamFct") 2 | 3 | test_that("test if ParamFct constructor works", { 4 | p = ParamFct$new(id = "test", levels = c("a", "b")) 5 | expect_equal(p$levels$test, c("a", "b")) 6 | expect_equal(p$nlevels[["test"]], 2L) 7 | 8 | # we dont allow NAs as levels 9 | expect_error(ParamFct$new(id = "test", levels = c("a", NA))) 10 | }) 11 | 12 | test_that("qunif", { 13 | n = 100000L 14 | testit = function(vals) { 15 | p = ParamFct$new("x", levels = vals) 16 | k = p$nlevels 17 | u = runif(n) 18 | v1 = p$qunif(data.frame(x = u))$x 19 | expect_character(v1, any.missing = FALSE, len = n) 20 | expect_setequal(unique(v1), p$levels$x) # check we see all levels 21 | # check that empirical frequencies are pretty much uniform 22 | freqs = prop.table(table(v1)) 23 | p = rep(1 / k, k) 24 | expect_lte(max(abs(freqs - p)), 0.01) 25 | } 26 | testit(c("f", "g")) 27 | testit(letters[2:9]) 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/test_ParamInt.R: -------------------------------------------------------------------------------- 1 | context("ParamInt") 2 | 3 | test_that("constructor works", { 4 | p = ParamInt$new(id = "test", lower = 1L, upper = 10L) 5 | expect_equal(p$ids(), "test") 6 | expect_equal(p$lower[["test"]], 1L) 7 | expect_equal(p$upper[["test"]], 10L) 8 | expect_equal(p$nlevels[["test"]], 10L) 9 | 10 | # check that we can create param with Inf bounds 11 | p = ParamInt$new(id = "test", lower = 1L) 12 | expect_equal(p$lower[["test"]], 1L) 13 | expect_equal(p$upper[["test"]], Inf) 14 | 15 | # check some invalid arg settings 16 | expect_error(ParamInt$new(id = "x", lower = NULL), "not 'NULL'") 17 | expect_error(ParamInt$new(id = "x", lower = 1.5), "not 'double'") 18 | expect_error(ParamInt$new(id = "x", upper = NULL), "not 'NULL'") 19 | expect_error(ParamInt$new(id = "x", upper = 1.5), "not 'double'") 20 | expect_error(ParamInt$new(id = "x", lower = 1, upper = 0), "lower <= upper") 21 | expect_error(ParamInt$new(id = "x", lower = Inf, upper = 0), "lower <= upper") 22 | }) 23 | 24 | test_that("is_bounded works", { 25 | expect_true(ParamInt$new(id = "x", lower = 1, upper = 10)$is_bounded) 26 | expect_false(ParamInt$new(id = "x", lower = 1)$is_bounded) 27 | expect_false(ParamInt$new(id = "x")$is_bounded) 28 | }) 29 | 30 | test_that("qunif", { 31 | n = 100000L 32 | testit = function(a, b) { 33 | 34 | p = ParamInt$new("x", lower = a, upper = b) 35 | k = p$nlevels[["x"]] 36 | expect_equal(k, b - a + 1) 37 | u = runif(n) 38 | v1 = p$qunif(data.frame(x = u))$x 39 | expect_integer(v1, any.missing = FALSE, len = n) 40 | expect_setequal(unique(v1), a:b) # check we see all levels 41 | # check that empirical frequencies are pretty much uniform 42 | freqs = prop.table(table(v1)) 43 | p = rep(1 / k, k) 44 | expect_lte(max(abs(freqs - p)), 0.01) 45 | } 46 | testit(1, 12) 47 | testit(-2, 1) 48 | }) 49 | 50 | test_that("assigning integer value results in int", { 51 | 52 | p = ParamSet_legacy$new(list(ParamInt$new("x"))) 53 | p$values$x = 0 54 | expect_equal(typeof(p$values$x), "integer") 55 | expect_error({p$values$x = 1e-2}, "be of type.*integerish") 56 | 57 | }) 58 | 59 | test_that("integer params are not corrected to the wrong value", { 60 | param_set = ps(a = p_int()) 61 | param_set$values$a = 100 62 | expect_identical(param_set$values$a, 100L) 63 | param_set$values$a = -100 64 | expect_identical(param_set$values$a, -100L) 65 | 66 | }) 67 | 68 | test_that("integer params are not corrected to the wrong value", { 69 | param_set = ps(a = p_int(tolerance = 0.4)) 70 | param_set$values$a = 100.4 71 | expect_identical(param_set$values$a, 100L) 72 | param_set$values$a = 100.6 73 | expect_identical(param_set$values$a, 101L) 74 | expect_error({param_set$values$a = 100.41}, "Must be of type.*integerish.*not.*double") 75 | expect_error({param_set$values$a = 100.59}, "Must be of type.*integerish.*not.*double") 76 | 77 | param_set$values$a = -100.4 78 | expect_identical(param_set$values$a, -100L) 79 | param_set$values$a = -100.6 80 | expect_identical(param_set$values$a, -101L) 81 | expect_error({param_set$values$a = -100.41}, "Must be of type.*integerish.*not.*double") 82 | expect_error({param_set$values$a = -100.59}, "Must be of type.*integerish.*not.*double") 83 | }) 84 | -------------------------------------------------------------------------------- /tests/testthat/test_ParamLgl.R: -------------------------------------------------------------------------------- 1 | context("ParamLgl") 2 | 3 | test_that("constructor works", { 4 | p = ParamLgl$new(id = "test") 5 | expect_equal(p$ids(), "test") 6 | expect_equal(p$nlevels[["test"]], 2L) 7 | expect_equal(p$levels[["test"]], c(TRUE, FALSE)) 8 | }) 9 | 10 | test_that("qunif", { 11 | n = 100000L 12 | testit = function() { 13 | p = ParamLgl$new("x") 14 | u = runif(n) 15 | v1 = p$qunif(data.frame(x = u))$x 16 | expect_logical(v1, any.missing = FALSE, len = n) 17 | expect_setequal(unique(v1), p$levels[["x"]]) # check we see all levels 18 | # check that empirical frequencies are pretty much uniform 19 | freqs = prop.table(table(v1)) 20 | p = c(1 / 2, 1 / 2) 21 | expect_lte(max(abs(freqs - p)), 0.01) 22 | } 23 | testit() 24 | }) 25 | -------------------------------------------------------------------------------- /tests/testthat/test_ParamUty.R: -------------------------------------------------------------------------------- 1 | context("ParamUty") 2 | 3 | test_that("ParamUty", { 4 | p = ParamUty$new(id = "x") 5 | expect_true(p$check(list(x = FALSE))) 6 | expect_true(p$check(list(x = NULL))) 7 | expect_true(p$check(list(x = NA))) 8 | 9 | p = ParamUty$new(id = "x", custom_check = function(x) 10 | if (is.null(x)) "foo" else TRUE) 11 | expect_true(p$check(list(x = FALSE))) 12 | expect_string(p$check(list(x = NULL)), fixed = "foo") 13 | expect_true(p$check(list(x = NA))) 14 | 15 | p = ParamUty$new(id = "x", default = Inf) 16 | }) 17 | 18 | test_that("R6 values of ParamUty are cloned", { 19 | ps = ParamSet_legacy$new(list(ParamUty$new("x"))) 20 | ps$values$x = R6Class("testclass", public = list(x = NULL))$new() 21 | 22 | psclone = ps$clone(deep = TRUE) 23 | psunclone = ps$clone(deep = FALSE) 24 | 25 | ps$values$x$x = TRUE 26 | 27 | expect_true(ps$values$x$x) # was changed to TRUE 28 | expect_true(psunclone$values$x$x) # reference check: value was not cloned 29 | expect_null(psclone$values$x$x) # was cloned before change --> should still be null 30 | }) 31 | 32 | test_that("default NULL works", { 33 | expect_equal(p_uty(default = NULL)$cargo[[1]]$repr, "NULL") 34 | }) 35 | -------------------------------------------------------------------------------- /tests/testthat/test_Param_rep.R: -------------------------------------------------------------------------------- 1 | context("Repeated params") 2 | 3 | test_that("rep params work", { 4 | p = ParamDbl$new(id = "x", lower = 1, upper = 3) 5 | ps = ps_replicate(p, 2) 6 | expect_r6(ps, "ParamSet") 7 | expect_equal(ps$length, 2L) 8 | expect_subset(ps$class, "ParamDbl") 9 | expect_equal(ps$ids(), c("rep1.x", "rep2.x")) 10 | expect_subset(ps$lower, 1) 11 | expect_subset(ps$upper, 3) 12 | 13 | p = ParamFct$new(id = "kk", levels = c("a", "b")) 14 | ps = ps_replicate(p, 3) 15 | expect_r6(ps, "ParamSet") 16 | expect_equal(ps$length, 3L) 17 | expect_subset(ps$class, "ParamFct") 18 | expect_equal(ps$ids(), c("rep1.kk", "rep2.kk", "rep3.kk")) 19 | for (id in ps$ids()) { 20 | expect_equal(ps$levels[[id]], c("a", "b")) 21 | } 22 | }) 23 | 24 | -------------------------------------------------------------------------------- /tests/testthat/test_default_values.R: -------------------------------------------------------------------------------- 1 | test_that("default_values", { 2 | param_set = ps(x = p_int(default = 3), y = p_dbl(default = 2.5)) 3 | values = default_values(param_set) 4 | expect_names(names(values), permutation.of = c("x", "y")) 5 | expect_equal(values$x, 3) 6 | expect_equal(values$y, 2.5) 7 | }) 8 | -------------------------------------------------------------------------------- /tests/testthat/test_deps.R: -------------------------------------------------------------------------------- 1 | context("Dependencies") 2 | 3 | test_that("basic example works", { 4 | ps = th_paramset_full() 5 | expect_false(ps$has_deps) 6 | ps$add_dep("th_param_int", on = "th_param_fct", CondEqual("a")) 7 | expect_true(ps$has_deps) 8 | x = list(th_param_int = 1) 9 | expect_string(ps$check(x, check_strict = TRUE), fixed = "th_param_int: can only be set") 10 | x = list(th_param_int = 1, th_param_fct = "a") 11 | expect_true(ps$check(x, check_strict = TRUE)) 12 | x = list(th_param_int = 1, th_param_fct = "b") 13 | expect_string(ps$check(x, check_strict = TRUE), fixed = "th_param_int: can only be set") 14 | x = list(th_param_int = NA, th_param_fct = "b") 15 | expect_string(ps$check(x, check_strict = TRUE), fixed = "May not be NA") 16 | x = list(th_param_fct = "a") 17 | expect_true(ps$check(x, check_strict = TRUE)) 18 | x = list(th_param_fct = "b") 19 | expect_true(ps$check(x, check_strict = TRUE)) 20 | x = list(th_param_dbl = 1.3) 21 | expect_true(ps$check(x, check_strict = TRUE)) 22 | 23 | # test printer, with 2 deps 24 | ps = th_paramset_full() 25 | ps$add_dep("th_param_int", on = "th_param_fct", CondEqual("a")) 26 | ps$add_dep("th_param_int", on = "th_param_lgl", CondEqual(TRUE)) 27 | expect_output(print(ps), "th_param_fct,th_param_lgl") 28 | 29 | # test that we can remove deps 30 | ps$deps = ps$deps[-1, ] 31 | expect_true(ps$has_deps) 32 | ps$deps = ps$deps[-1, ] 33 | expect_false(ps$has_deps) 34 | }) 35 | 36 | test_that("nested deps work", { 37 | ps = th_paramset_full() 38 | ps$add_dep("th_param_int", on = "th_param_fct", CondAnyOf(c("a", "b"))) 39 | ps$add_dep("th_param_dbl", on = "th_param_lgl", CondEqual(TRUE)) 40 | ps$add_dep("th_param_lgl", on = "th_param_fct", CondEqual("c")) 41 | 42 | x1 = list(th_param_int = 1) 43 | expect_string(ps$check(x1, check_strict = TRUE), fixed = "th_param_int: can only be set") 44 | x2 = list(th_param_int = 1, th_param_fct = "b") 45 | expect_true(ps$check(x2, check_strict = TRUE)) 46 | x3 = list(th_param_int = 1, th_param_fct = "c") 47 | expect_string(ps$check(x3, check_strict = TRUE), fixed = "th_param_int: can only be set") 48 | x4 = list(th_param_fct = "a") 49 | expect_true(ps$check(x4, check_strict = TRUE)) 50 | x5 = list(th_param_dbl = 1.3) 51 | expect_string(ps$check(x5, check_strict = TRUE), fixed = "th_param_dbl: can only be set") 52 | x6 = list(th_param_fct = "c", th_param_lgl = TRUE, th_param_dbl = 3) 53 | expect_true(ps$check(x6, check_strict = TRUE)) 54 | }) 55 | 56 | 57 | test_that("adding 2 sets with deps works", { 58 | ps1 = ParamSet_legacy$new(list( 59 | ParamFct$new("x1", levels = c("a", "b")), 60 | ParamDbl$new("y1") 61 | )) 62 | ps1$add_dep("y1", on = "x1", CondEqual("a")) 63 | 64 | ps2 = ParamSet_legacy$new(list( 65 | ParamFct$new("x2", levels = c("a", "b")), 66 | ParamDbl$new("y2") 67 | )) 68 | ps2$add_dep("y2", on = "x2", CondEqual("a")) 69 | 70 | ps1 = ps_union(list(ps1, ps2)) 71 | expect_equal(ps1$length, 4L) 72 | expect_true(ps1$has_deps) 73 | expect_data_table(ps1$deps, nrows = 2) 74 | # do a few feasibility checks on larger set 75 | expect_true(ps1$test(list(x1 = "a", y1 = 1, x2 = "a", y2 = 1), check_strict = TRUE)) 76 | expect_true(ps1$test(list(x1 = "a", y1 = 1), check_strict = TRUE)) 77 | expect_false(ps1$test(list(x1 = "b", y1 = 1), check_strict = TRUE)) 78 | expect_true(ps1$test(list(x2 = "a", y2 = 1), check_strict = TRUE)) 79 | expect_false(ps1$test(list(x2 = "b", y2 = 1), check_strict = TRUE)) 80 | }) 81 | 82 | test_that("subsetting with deps works", { 83 | ps = ParamSet_legacy$new(list( 84 | ParamFct$new("a", levels = c("a", "b")), 85 | ParamFct$new("b", levels = c("a", "b")), 86 | ParamFct$new("c", levels = c("a", "b")), 87 | ParamFct$new("d", levels = c("a", "b")) 88 | )) 89 | ps$add_dep("a", on = "b", CondEqual("a")) 90 | ps$add_dep("a", on = "c", CondEqual("a")) 91 | ps$add_dep("b", on = "c", CondEqual("a")) 92 | 93 | ps$clone(deep = TRUE)$subset("d") 94 | ps$clone(deep = TRUE)$subset(c("a", "b", "c")) 95 | expect_error(ps$clone(deep = TRUE)$subset(c("a", "c")), "Subsetting so that dependencies") 96 | expect_error(ps$clone(deep = TRUE)$subset(c("a")), "Subsetting so that dependencies") 97 | }) 98 | 99 | test_that("cannot add a dep on yourself", { 100 | ps = ParamSet_legacy$new(list(ParamFct$new("x", levels = c("a")))) 101 | expect_error(ps$add_dep("x", on = "x", CondEqual("a")), "depend on itself") 102 | }) 103 | 104 | 105 | test_that("we can also dep on integer", { 106 | ps = ParamSet_legacy$new(list( 107 | ParamInt$new("i", lower = 0, upper = 9), 108 | ParamDbl$new("d", lower = 0, upper = 9) 109 | )) 110 | ps$add_dep("d", on = "i", CondAnyOf(1:3)) 111 | 112 | expect_true(ps$check(list(i = 2, d = 5), check_strict = TRUE)) 113 | expect_string(ps$check(list(i = 5, d = 5), check_strict = TRUE)) 114 | }) 115 | 116 | test_that("deps make sense", { 117 | ps = th_paramset_full() 118 | expect_error(ps$add_dep("th_param_lgl", "th_param_fct", CondEqual("d")), 119 | "Condition has infeasible values for th_param_fct") 120 | expect_error(ps$add_dep("th_param_lgl", "th_param_int", CondAnyOf(5:15)), 121 | "Condition has infeasible values for th_param_int") 122 | }) 123 | -------------------------------------------------------------------------------- /tests/testthat/test_param_vals.R: -------------------------------------------------------------------------------- 1 | context("values") 2 | 3 | test_that("values", { 4 | ps = ParamSet_legacy$new(list( 5 | ParamDbl$new(id = "d", lower = 0, upper = 1), 6 | ParamInt$new(id = "i", lower = 1, upper = 3), 7 | ParamFct$new(id = "f", levels = letters[1:3]) 8 | )) 9 | # make sure we accept empty list, and not only a "named list" 10 | ps$values = list() 11 | expect_equal(ps$values, named_list()) 12 | ps$values = list(d = 1, f = "a") 13 | expect_true(ps$check(list(d = 0, f = "a"))) 14 | ps2 = ps$clone() 15 | ps2 = ps2$subset(ids = c("d", "i")) 16 | expect_equal(ps2$values, list(d = 1)) 17 | ps2$values = list(d = 0.5) 18 | expect_true(ps$check(list(d = 1, f = "a"))) 19 | expect_equal(ps2$values, list(d = 0.5)) 20 | # check printer 21 | expect_output(print(ps2), "d.*.*0.5") 22 | 23 | ps2 = ps$clone() 24 | ps2 = ps2$subset(ids = c("i")) 25 | expect_equal(ps2$values, set_names(list(), character(0))) 26 | 27 | ps3 = ParamSet_legacy$new(list( 28 | ParamDbl$new(id = "x", lower = 0, upper = 9) 29 | )) 30 | ps3$values = list(x = 7) 31 | ps2 = ps$clone() 32 | ps2 = ps_union(list(ps2, ps3)) 33 | expect_equal(ps2$values, list(d = 1, f = "a", x = 7)) 34 | 35 | # designs 36 | ps$values = list(f = "a") 37 | d = generate_design_grid(ps, resolution = 3) 38 | dd = d$data 39 | expect_data_table(dd, nrows = 9, ncols = 3) 40 | expect_true(all(dd$f == "a")) 41 | 42 | d = generate_design_random(ps, n = 100) 43 | dd = d$data 44 | expect_data_table(dd, nrows = 100, ncols = 3) 45 | expect_true(all(dd$f == "a")) 46 | 47 | if (requireNamespace("lhs", quietly = TRUE)) { 48 | d = generate_design_lhs(ps, n = 10) 49 | dd = d$data 50 | expect_data_table(dd, nrows = 10, ncols = 3) 51 | expect_true(all(dd$f == "a")) 52 | } 53 | 54 | # sampler 55 | s = SamplerUnif$new(ps) 56 | d = s$sample(9) 57 | dd = d$data 58 | expect_data_table(dd, nrows = 9, ncols = 3) 59 | expect_true(all(dd$f == "a")) 60 | }) 61 | 62 | test_that("values calls assert", { 63 | # most of the tests should be done for ParamSet$check, so we simply 64 | # check here, that paramvals calls assert 65 | ps = ParamSet_legacy$new(list( 66 | ParamDbl$new(id = "d", lower = 0, upper = 1), 67 | ParamInt$new(id = "i", lower = 1, upper = 3), 68 | ParamFct$new(id = "f", levels = letters[1:3]) 69 | )) 70 | expect_error(ps$values <- list(xxx = 1), "not available") 71 | expect_error(ps$values <- list(d = 9), "not <= 1") 72 | 73 | # now check that we can disable assert 74 | ps$assert_values = FALSE 75 | ps$values = list(d = 9) 76 | expect_equal(ps$values, list(d = 9)) 77 | }) 78 | 79 | 80 | -------------------------------------------------------------------------------- /tests/testthat/test_sampler.R: -------------------------------------------------------------------------------- 1 | context("sampling") 2 | 3 | test_that("1d samplers: basic tests", { 4 | samplers = list( 5 | ParamDbl = list(Sampler1DUnif, Sampler1DNormal), 6 | ParamInt = list(Sampler1DUnif), 7 | ParamFct = list(Sampler1DUnif, Sampler1DCateg), 8 | ParamLgl = list(Sampler1DUnif, Sampler1DCateg) 9 | ) 10 | ps = th_paramset_full() 11 | for (p in ps$subspaces()) { 12 | ss = samplers[[p$class]] 13 | for (s in ss) { 14 | expect_error(s$new(ps()), "exactly 1 Param, but contains 0") 15 | expect_error(s$new(ps_union(list(x = p, y = p))), "exactly 1 Param, but contains 2") 16 | expect_class(s$new(p), "Sampler1D") 17 | s = s$new(p) 18 | info = paste(p$ids(), "-", class(s)[[1L]]) 19 | n = 5L 20 | x = s$sample(n) 21 | d = x$data 22 | expect_data_table(d, ncols = 1L, nrows = n, info = info) 23 | d1 = d[[1]] 24 | expect_is(d1, p$storage_type, info = info) 25 | if (p$class %in% c("ParamInt", "ParamDbl")) { 26 | expect_true(all(d1 >= p$lower & d1 <= p$upper), info = info) 27 | } 28 | if (p$class %in% c("ParamFct")) { 29 | expect_true(all(d1 %in% p$levels[[1]]), info = info) 30 | } 31 | expect_output(print(s), "") 61 | expect_output(print(s), "Independent comps: 2") 62 | }) 63 | 64 | test_that("SamplerUnif", { 65 | ps_list = list( 66 | dbl = th_paramset_dbl1(), 67 | full = th_paramset_full(), 68 | repeated = th_paramset_repeated(), 69 | numeric = th_paramset_numeric() 70 | ) 71 | 72 | for (info in names(ps_list)) { 73 | ps = ps_list[[info]] 74 | s = SamplerUnif$new(ps) 75 | # as the ps is constructed in the sampler, we cannot expect ps$id to be the same 76 | expect_equal(s$param_set$params, ps$params) 77 | d = s$sample(10) 78 | dd = d$data 79 | expect_data_table(dd, nrows = 10, any.missing = FALSE, info = info) 80 | expect_equal(colnames(dd), ps$ids(), info = info) 81 | expect_true(all(map_lgl(d$transpose(), ps$test)), info = info) 82 | expect_output(print(s), "") 83 | expect_output(print(s), str_collapse(ps$ids()[1])) # check that we at least see an id 84 | } 85 | }) 86 | 87 | test_that("SamplerUnif works with deps", { 88 | ps = th_paramset_deps() 89 | s = SamplerUnif$new(ps) 90 | d = s$sample(1000) 91 | dd = d$data 92 | expect_data_table(dd, nrows = 1000, ncols = 4L, any.missing = TRUE) 93 | expect_true(anyNA(dd)) 94 | expect_true(all((dd$th_param_fct %in% c("c", NA_character_) & is.na(dd$th_param_dbl)) 95 | | (dd$th_param_fct %in% c("a", "b") & !is.na(dd$th_param_dbl)))) 96 | expect_names(names(dd), permutation.of = c("th_param_int", "th_param_dbl", "th_param_lgl", "th_param_fct")) 97 | expect_true(all(map_lgl(d$transpose(filter_na = TRUE), ps$test))) 98 | }) 99 | 100 | test_that("we had a bug where creating the joint sampler changed the ps-ref of the 1d samplers", { 101 | p1 = th_param_fct() 102 | p2 = th_param_dbl() 103 | ps = ParamSet_legacy$new(list(p1, p2)) 104 | s1 = Sampler1DCateg$new(p1) 105 | s2 = Sampler1DUnif$new(p2) 106 | s = SamplerJointIndep$new(list(s1, s2)) 107 | 108 | s1_expected = ParamSet_legacy$new(list(th_param_fct())) 109 | 110 | # reset indices: they are set but do not make the param_set unequal 111 | setindexv(s1_expected$.__enclos_env__$private$.params, NULL) 112 | setindexv(s1$param_set$.__enclos_env__$private$.params, NULL) 113 | setindexv(s1_expected$.__enclos_env__$private$.tags, NULL) 114 | setindexv(s1$param_set$.__enclos_env__$private$.tags, NULL) 115 | setindexv(s1_expected$.__enclos_env__$private$.deps, NULL) 116 | setindexv(s1$param_set$.__enclos_env__$private$.deps, NULL) 117 | expect_equal(s1$param_set, s1_expected) 118 | 119 | s2_expected = ParamSet_legacy$new(list(th_param_dbl())) 120 | 121 | setindexv(s2_expected$.__enclos_env__$private$.params, NULL) 122 | setindexv(s2$param_set$.__enclos_env__$private$.params, NULL) 123 | setindexv(s2_expected$.__enclos_env__$private$.tags, NULL) 124 | setindexv(s2$param_set$.__enclos_env__$private$.tags, NULL) 125 | setindexv(s2_expected$.__enclos_env__$private$.deps, NULL) 126 | setindexv(s2$param_set$.__enclos_env__$private$.deps, NULL) 127 | 128 | expect_equal(s2$param_set, s2_expected) 129 | }) 130 | 131 | test_that("Sampler1DRfun with 0 samples (#338)", { 132 | s = Sampler1DRfun$new(param = ParamDbl$new("x", 0, 10), rfun = function(n) numeric(0)) 133 | x = s$sample(0) 134 | expect_data_table(x$data, nrows = 0L, ncols = 1L) 135 | }) 136 | -------------------------------------------------------------------------------- /tests/testthat/test_trafo.R: -------------------------------------------------------------------------------- 1 | context("trafo") 2 | 3 | test_that("trafo", { 4 | ps = ParamSet_legacy$new(list( 5 | ParamDbl$new("x", lower = -3, upper = 3), 6 | ParamDbl$new("w1", lower = 7, upper = 9), 7 | ParamDbl$new("w2", lower = 7, upper = 9), 8 | ParamFct$new("f", levels = c("a", "b")) 9 | )) 10 | expect_false(ps$has_trafo) 11 | ps$extra_trafo = function(x, param_set) { 12 | x$x = 2^x$x 13 | s = x$w1 + x$w2 14 | x$w1 = x$w1 / s 15 | x$w2 = x$w2 / s 16 | return(x) 17 | } 18 | expect_true(ps$has_trafo) 19 | expect_output(print(ps), "Trafo is set") 20 | d1 = generate_design_grid(ps, resolution = 4) 21 | dd1 = d1$data 22 | d2 = map_dtr(seq_len(nrow(dd1)), function(i) ps$trafo(as.list(dd1[i]))) 23 | expect_numeric(d2$x, lower = 0) 24 | expect_numeric(d2$w1, lower = 0, upper = 1) 25 | expect_numeric(d2$w2, lower = 0, upper = 1) 26 | expect_equal(d2$w1 + d2$w2, rep(1, nrow(d2))) 27 | }) 28 | --------------------------------------------------------------------------------