{"id":16857151,"url":"https://github.com/anirban166/testcomplexity","last_synced_at":"2025-03-17T05:32:23.983Z","repository":{"id":129054735,"uuid":"228646265","full_name":"Anirban166/testComplexity","owner":"Anirban166","description":"Asymptotic complexity testing framework","archived":false,"fork":false,"pushed_at":"2024-09-12T02:18:41.000Z","size":2224,"stargazers_count":35,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-27T18:27:02.289Z","etag":null,"topics":["complexity-tester","r-package"],"latest_commit_sha":null,"homepage":"https://anirban166.github.io/testComplexity/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Anirban166.png","metadata":{"files":{"readme":"README.md","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-17T15:30:22.000Z","updated_at":"2025-01-04T06:50:12.000Z","dependencies_parsed_at":"2024-09-12T06:31:09.149Z","dependency_job_id":"f856f640-f640-4c0f-9527-ea8f891b3f86","html_url":"https://github.com/Anirban166/testComplexity","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anirban166%2FtestComplexity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anirban166%2FtestComplexity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anirban166%2FtestComplexity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Anirban166%2FtestComplexity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Anirban166","download_url":"https://codeload.github.com/Anirban166/testComplexity/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243846989,"owners_count":20357296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["complexity-tester","r-package"],"created_at":"2024-10-13T14:06:57.907Z","updated_at":"2025-03-17T05:32:22.028Z","avatar_url":"https://github.com/Anirban166.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align = \"center\"\u003e\n\u003cimg width = \"95%\" height = \"auto\" src = \"Images/TransparentLogoV5.png\"\u003e\n\u003c/p\u003e\n\n\u003cp align = \"center\"\u003e\n    \u003ca href = \"https://travis-ci.com/github/Anirban166/testComplexity\"\u003e\n    \u003cimg src = \"https://api.travis-ci.com/Anirban166/testComplexity.svg?branch=master\"\n         alt = \"Build status (Travis CI)\"\u003e\u003c/a\u003e\n    \u003ca href = \"https://codecov.io/gh/Anirban166/testComplexity?branch=master\"\u003e    \n    \u003cimg src = \"https://codecov.io/gh/Anirban166/testComplexity/branch/master/graph/badge.svg\"\n         alt = \"Code Coverage (covr/codecov)\"\u003e\u003c/a\u003e\n    \u003ca href = \"https://www.codacy.com/manual/bloodraven166/testComplexity?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=Anirban166/testComplexity\u0026amp;utm_campaign=Badge_Grade\"\u003e\n    \u003cimg src = \"https://app.codacy.com/project/badge/Grade/d69a466f4597434e9118ee59ae3307e3\"    \n         alt = \"Codacy Badge\"\u003e\u003c/a\u003e\n    \u003ca href = \"https://www.r-project.org/\"\u003e\n    \u003cimg src = \"https://img.shields.io/badge/100%25--blue?style=flat\u0026logo=R\"\n         alt = \"The R project for statistical computing\"\u003e\u003c/a\u003e\n    \u003ca href = \"https://summerofcode.withgoogle.com/archive/2020/projects/5767451238727680/\"\u003e\n    \u003cimg src = \"https://img.shields.io/badge/Google-Funded-success?style=flat\u0026logo=Google\"\n         alt = \"GSoC project\"\u003e\u003c/a\u003e\n    \u003ca href = \"https://github.com/Anirban166/testComplexity/blob/master/LICENSE.md\"\u003e\n    \u003cimg src = \"https://img.shields.io/badge/License-MIT-black?style=flat\"\n         alt = \"GitHub License\"\u003e\u003c/a\u003e\n\u003c/p\u003e \n\n| \u003ca href = \"#abstract\"\u003eAbstract\u003c/a\u003e | \u003ca href = \"#objectives\"\u003eObjectives\u003c/a\u003e | \u003ca href = \"#installation\"\u003eInstallation\u003c/a\u003e | \u003ca href = \"#functional-flow\"\u003eFunctions\u003c/a\u003e | \u003ca href = \"#usage\"\u003eUsage\u003c/a\u003e | \u003ca href = \"#plotting\"\u003ePlotting\u003c/a\u003e | \u003ca href = \"#benchmarking\"\u003eBenchmarking\u003c/a\u003e | \u003ca href = \"#testing\"\u003eTesting\u003c/a\u003e | \u003ca href = \"#resources\"\u003eResources\u003c/a\u003e |\n|---|---|---|---|---|---|---|---|---|\n        \n---\n\u003ch2 align = \"center\"\u003e\nAbstract\n\u003c/h2\u003e\n\nR package developers currently use ad-hoc tests of asymptotic computational complexity via empirical timings of functions and visual diagnostic plots. However, there is no framework in R for systematically testing the empirical computational complexity of functions, which tends to be a problem because such a testing framework could be essential for identifying big speed gains in R code as well. In response to this, **testComplexity** provides a suite of [functions](https://github.com/Anirban166/testComplexity/tree/master/R) that will be useful for testing and thereby improving the speed of various algorithms/functions in R.\n\n\u003ch2 align = \"center\"\u003e\nObjectives\n\u003c/h2\u003e\n\n- Primary objectives include quantification of runtimes for an algorithm/function (against a set of user-provided data sizes), classification of the corresponding asymptotic time complexity class it belongs to (based on the computed benchmarks) and testing for the same against an expected time complexity class for verification of empirically observed results, based upon the initial idea as staged [here](https://github.com/rstats-gsoc/gsoc2020/wiki/Asymptotic-complexity-testing#details-of-your-coding-project). \u003cbr\u003e\n- Additionally (or as per my proposal), I thought of covering memory complexity testing as well, which in terms of resources, goes hand-in-hand when dealing with 'complexity' in Computer Science. \u003cbr\u003e\n- Furthermore, [@tdhock](https://github.com/tdhock) suggested classifying complexity for user-defined output parameters (i.e. a measure of a parameter apart from timings/memory), which would eventually make the package more flexible in terms of use-cases.\n\nSince algorithms are used in every sphere of research, this package potentially caters to all sorts of R-users, following different fields of study. At its current state, it has been tested on algorithms pertaining to changepoint detection, sorting, constrained optimal segmentation/partitioning, plus a few common ones from base R such as substring and gregexpr.\n\n\u003ch2 align = \"center\"\u003e\nInstallation\n\u003c/h2\u003e\n\nUse `devtools` or `remotes` to fetch the package from this repository:\n```r\nif(!require(devtools)) install.packages(\"devtools\")\ndevtools::install_github(\"Anirban166/testComplexity\")\n```\n```r\nif(!require(remotes)) install.packages(\"remotes\")\nremotes::install_github(\"Anirban166/testComplexity\")\n```\n\n\u003ch2 align = \"center\"\u003e\nFunctional Flow\n\u003c/h2\u003e\n\n```r\n__________________ R Files _______________________________________ Additional Details _____________________________\ntestComplexity                              @ returns              @ type                    @ commit-branch(es) \n├──\u003e asymptoticTimings                    : data.frame             timings quantifier        master\n│    ├──\u003e asymptoticTimeComplexityClass   :   ├──\u003e string          ↑ complexity classifier   master\n│    └──\u003e plotTimings                     :   └──\u003e ggplot object   ↑ plotter                 master/Plotfunc\n│\n├──\u003e asymptoticMemoryUsage                : data.frame             memory-usage quantifier   Memtest\n│    ├──\u003e asymptoticMemoryComplexityClass :   ├──\u003e string          ↑ complexity classifier   Memtest\n│    └──\u003e plotMemoryUsage                 :   └──\u003e ggplot object   ↑ plotter                 Memtest/Plotfunc\n│\n├──\u003e asymptoticComplexityClass            : string                 complexity classifier     Generalizedcomplexity\n│    └──\u003e asymptoticComplexityClassifier  :   ↑ string             ↑ complexity classifier   Generalizedcomplexity\n│\n├──\u003e expect_complexity_class              : -/-                    test function             Testfunc\n│    └──\u003e expect_time_complexity          : -/-                    ↑  test function          Testfunc\n│         ├──\u003e expect_linear_time         : -/-                    ↑↑ test function          Testfunc\n│         ├──\u003e expect_loglinear_time      : -/-                    ↑↑ test function          Testfunc\n│         └──\u003e expect_quadratic_time      : -/-                    ↑↑ test function          Testfunc\n│\n└──\u003e testthat                                                                                \n     ├──\u003e testsfortestComplexity                                   unit-tester               All branches\n     ├──\u003e testsforConstrainedchangepointmodelalgos                 unit-tester               Testfunc\n     └──\u003e testsforRegularfunctions                                 unit-tester               Testfunc\n____________________________________________________________________________________________________________________\n```\n\n\u003ch2 align = \"center\"\u003e\nUsage\n\u003c/h2\u003e\n\nTo get started, please check the [general vignette](https://anirban166.github.io/testComplexity/articles/testComplexity.html) which highlights all the features, enlists the different types of function categories existent in the package and describes the functionality offered by the underlying user-oriented functions via a set of textual elucidations with one example taken to be discussed throughout for each of them. \n\nFor a quick overview of the main functionality (obtaining quantified benchmarks and subsequently computing the time/memory complexity class), please check the examples below.\n\n- To obtain the benchmarked timings/memory-allocations against specified data sizes, pass the required algorithm as a function of `N` to `asymptoticTimings()`/`asymptoticMemoryUsage()`: \u003cbr\u003e\n```r\nlibrary(data.table)\n# Example 1 | Applying the bubble sort algorithm to a sample of 100 elements: (expected quadratic time complexity \u0026 constant memory complexity)\nbubble.sort \u003c- function(elements.vec) { \n  n \u003c- length(elements.vec)\n  for(i in 1:(n - 1)) {\n    for(j in 1:(n - i)) {\n      if(elements.vec[j + 1] \u003c elements.vec[j]) { \n        temp \u003c- elements.vec[j]\n        elements.vec[j] \u003c- elements.vec[j + 1]\n        elements.vec[j + 1] \u003c- temp\n      }\n    }\n  }\n  return(elements.vec)\n}\n\ndf.bubble.time \u003c- asymptoticTimings(bubble.sort(sample(1:100, N, replace = TRUE)), data.sizes = 10^seq(1, 3, by = 0.5))\ndata.table(df.bubble.time)\n      Timings Data sizes\n  1:    91902         10\n  2:    39402         10\n  3:    34701         10\n  4:    33101         10\n  5:    33201         10\n ---                    \n496: 64490501       1000\n497: 59799101       1000\n498: 63452200       1000\n499: 62807201       1000\n500: 59757102       1000\n                  \ndf.bubble.memory \u003c- asymptoticMemoryUsage(bubble.sort(sample(1:100, N, replace = TRUE)), data.sizes = 10^seq(1, 3, by = 0.1))\ndata.table(df.bubble.memory)\n    Memory usage Data sizes\n 1:        87800   10.00000\n 2:         2552   12.58925\n 3:         2552   15.84893\n 4:         2552   19.95262\n 5:         2552   25.11886\n ---                    \n17:         7472  398.10717\n18:         8720  501.18723\n19:        10256  630.95734\n20:        12224  794.32823\n21:        14696 1000.00000\n```\n```r\n# Example 2 | Testing PeakSegPDPA, an algorithm for constrained changepoint detection: (expected log-linear time and memory complexity)\ndata.vec \u003c- rpois(N, 1)\ndf.PDPA.time \u003c- asymptoticTimings(PeakSegOptimal::PeakSegPDPA(count.vec = data.vec, max.segments = 3L), data.sizes = 10^seq(1, 4, by = 0.1))\ndata.table(df.PDPA.time)\n       Timings Data sizes\n  1:    248701         10\n  2:    120302         10\n  3:    125701         10\n  4:    133301         10\n  5:    146500         10\n ---                     \n696: 405597501      10000\n697: 408335001      10000\n698: 338544401      10000\n699: 404081901      10000\n700: 399575501      10000\n\ndf.PDPA.memory \u003c- asymptoticMemoryUsage(PeakSegOptimal::PeakSegPDPA(count.vec = data.vec, max.segments = 3L), data.sizes = 10^seq(1, 4, by = 0.1))\ndata.table(df.PDPA.memory)\n    Memory usage Data sizes\n 1:         6256   10.00000\n 2:         7024   12.58925\n 3:         7432   15.84893\n 4:         8560   19.95262\n 5:         9496   25.11886\n --- \n25:       447792 2511.88643\n26:       562336 3162.27766\n27:       706512 3981.07171\n28:       887792 5011.87234\n29:      1116240 6309.57344\n```\n- To estimate the corresponding time/memory complexity class, pass the obtained data frame onto `asymptoticTimeComplexityClass()`/`asymptoticMemoryComplexityClass()`: \u003cbr\u003e\n```r\n# Example 1 | Applying the bubble sort algorithm to a sample of 100 elements: (expected quadratic time complexity \u0026 constant memory complexity)\nasymptoticTimeComplexityClass(df.bubble.time)\n[1] \"quadratic\"\nasymptoticMemoryComplexityClass(df.bubble.memory)\n[1] \"constant\"\n```\n```r\n# Example 2 | Testing PeakSegPDPA, an algorithm for constrained changepoint detection: (expected log-linear time and memory complexity)\nasymptoticTimeComplexityClass(df.PDPA.time)\n[1] \"loglinear\"\nasymptoticMemoryComplexityClass(df.PDPA.memory)\n[1] \"loglinear\"\n```\n- Combine the functions if you only require the complexity class: \u003cbr\u003e\n```r\n# Example 3 | Testing the time complexity of the quick sort algorithm: (expected log-linear time complexity)\nasymptoticTimeComplexityClass(asymptoticTimings(sort(sample(1:100, N, replace = TRUE), method = \"quick\" , index.return = TRUE), data.sizes = 10^seq(1, 3, by = 0.5)))\n[1] \"loglinear\"\n```\n```r\n# Example 4 | Allocating a square matrix (N*N dimensions): (expected quadratic memory complexity)\nasymptoticMemoryComplexityClass(asymptoticMemoryUsage(matrix(data = N:N, nrow = N, ncol = N), data.sizes = 10^seq(1, 3, by = 0.1)))\n[1] \"quadratic\"\n```\nCheck [this screencast](https://youtu.be/H4uefLb8zcQ) for a demonstration of time complexity testing on different sorting algorithms over a test session.\nFor more examples with functions from specific packages, please check the table with relevant contents in the [testing section](#testing).\n\n\u003ch2 align = \"center\"\u003e\nPlotting\n\u003c/h2\u003e\n\nFor obtaining a visual description of the trend followed between runtimes/memory-usage vs data sizes so as to diagnose the complexity result(s) (the traditional method, for visual verification say), simple plots can be crafted. They are roughly grouped into: \n\n- **Single Plots** \u003cbr\u003e\nIndividual plots can be obtained by passing the data frame returned by the quantifying functions to `plotTimings()`/`plotMemoryUsage()` for time/memory cases respectively: \u003cbr\u003e\n```r\n# Timings plot for PeakSegDP::cDPA\ndf \u003c- asymptoticTimings(PeakSegDP::cDPA(rpois(N, 1), rep(1, length(rpois(N, 1))), 3L), data.sizes = 10^seq(1, 4))\nplotTimings(df.time, titles = list(\"Timings\", \"PeakSegDP::cDPA\"), line.color = \"#ffec1b\", point.color = \"#ffec1b\", line.size = 1, point.size = 1.5)\n# Equivalent ggplot object:\ndf \u003c- asymptoticTimings(PeakSegDP::cDPA(rpois(data.sizes, 1), rep(1, length(rpois(data.sizes, 1))), 3L), data.sizes = 10^seq(1, 4))\nggplot(df, aes(x = `Data sizes`, y = Timings)) + geom_point(color = ft_cols$yellow, size = 1.5) + geom_line(color = ft_cols$yellow, size = 1) + labs(x = \"Data sizes\", y = \"Runtime (in nanoseconds)\") + scale_x_log10() + scale_y_log10() + ggtitle(\"Timings\", \"PeakSegDP::cDPA\") + hrbrthemes::theme_ft_rc()\n```\n```r\n# Memory Usage plot for PeakSegDP::cDPA\ndf \u003c- asymptoticMemoryUsage(PeakSegDP::cDPA(rpois(N, 1), rep(1, length(rpois(N, 1))), 3L), data.sizes = 10^seq(1, 6, by = 0.1))\nplotMemoryUsage(df.memory, titles = list(\"Memory Usage\", \"PeakSegDP::cDPA\"), line.color = \"#ffec1b\", point.color = \"#ffec1b\", line.size = 1, point.size = 2) \n# Equivalent ggplot object:\nggplot(df, aes(x = `Data sizes`, y = `Memory usage`)) + geom_point(color = ft_cols$yellow, size = 2) + geom_line(color = ft_cols$yellow, size = 1) labs(x = \"Data sizes\", y = \"Memory usage (in bytes)\") + scale_x_log10() + scale_y_log10() + ggtitle(\"Memory Usage\", \"PeakSegDP::cDPA\") + hrbrthemes::theme_ft_rc()\n```\n\u003cimg width = \"100%\" src = \"Images/timememorycDPA.png\"\u003e \u003cbr\u003e\n- **Comparison Plots** \u003cbr\u003e\nIn order to visually compare different algorithms based on the benchmarked metrics returned as a data frame by the quantifiers, one can appropriately add a third column (to help distinguish by aesthetics based on it) with a unique value for each of the data frames, combine them using an `rbind()` and then plot the resultant data frame using suitable aesthetics, geometry, scale, labels/titles etcetera via a ggplot: \u003cbr\u003e\n```r\ndf.substring \u003c- asymptoticTimings(substring(paste(rep(\"A\", N), collapse = \"\"), 1:N, 1:N), data.sizes = 10^seq(1, 4, by = 0.5))\nasymptoticTimeComplexityClass(df.substring)\n[1] \"linear\"\ndf.PeakSegPDPA \u003c- asymptoticTimings(PeakSegOptimal::PeakSegPDPA(rpois(N, 1),rep(1, length(rpois(N, 1))), 3L), data.sizes = 10^seq(1, 4, by = 0.5), max.seconds = 1)\nasymptoticTimeComplexityClass(df.PeakSegPDPA)\n[1] \"loglinear\"\ndf.cDPA \u003c- asymptoticTimings(PeakSegDP::cDPA(rpois(N, 1), rep(1, length(rpois(N, 1))), 3L), data.sizes = 10^seq(1, 4, by = 0.5), max.seconds = 5)\nasymptoticTimeComplexityClass(df.cDPA)\n[1] \"quadratic\"\ndf.gregexpr \u003c- asymptoticTimings(gregexpr(\"a\", paste(collapse = \"\", rep(\"ab\", N)), perl = TRUE), data.sizes = 10^seq(1, 4, by = 0.5))\nasymptoticTimeComplexityClass(df.gregexpr)\n[1] \"linear\"\ndf.fpop \u003c- asymptoticTimings(fpop::Fpop(rnorm(N), 1), data.sizes = 10^seq(1, 4, by = 0.5))\nasymptoticTimeComplexityClass(df.fpop)\n[1] \"loglinear\"\ndf.opart \u003c- asymptoticTimings(opart::opart_gaussian(rnorm(N), 1), data.sizes = 10^seq(1, 4, by = 0.5))\nasymptoticTimeComplexityClass(df.opart)\n[1] \"quadratic\"\n        \ndf.substring$expr = \"substring\"\ndf.PeakSegPDPA$expr = \"PeakSegPDPA\"\ndf.cDPA$expr = \"cDPA\"\ndf.gregexpr$expr = \"gregexpr\"\ndf.fpop$expr = \"fpop\"\ndf.opart$expr = \"opart\"\n        \nplot.df \u003c- rbind(df.substring, df.PeakSegPDPA, df.cDPA, df.gregexpr, df.fpop, df.opart)\nggplot(plot.df, aes(x = `Data sizes`, y = Timings)) + geom_point(aes(color = expr)) + geom_line(aes(color = expr)) + labs(x = \"Data sizes\", y = \"Runtime (in nanoseconds)\") + scale_x_log10() + scale_y_log10() + ggtitle(\"Timings comparison plot\", subtitle = \"Linear vs Log-linear vs Quadratic complexities\") + ggthemes::theme_pander()\n```\n\u003cimg width = \"100%\" src = \"Images/cp2.png\"\u003e \u003cbr\u003e\n\nFeel free to include more functions and increase the number of data sizes for a more comprehensive outlook: \u003cbr\u003e\n\n\u003cimg width = \"100%\" src = \"Images/cp.png\"\u003e \u003cbr\u003e\n- **Generalized Linear Model based Plots** \u003cbr\u003e\n`ggfortify`, an extension of `ggplot2`, can be used to produce diagnostic plots for generalized linear models with the same formulae as used in the complexity classification functions: \u003cbr\u003e\n```r\nlibrary(ggfortify)\ndf \u003c- asymptoticTimings(PeakSegDP::cDPA(rpois(N, 1), rep(1, length(rpois(N, 1))), 3L), data.sizes = 10^seq(1, 4 by = 0.1))\nglm.plot.obj \u003c- glm(Timings~`Data sizes`, data = df)\nggplot2::autoplot(stats::glm(glm.plot.obj)) + ggthemes::theme_gdocs()\n```\n\u003cimg src = \"Images/glmplot.png\"\u003e \u003cbr\u003e\n\n\u003ch2 align = \"center\"\u003e\nBenchmarking\n\u003c/h2\u003e\n\nAmong a few [options](https://anirban166.github.io//Benchmarking/), \n- `microbenchmark::microbenchmark()` is used to compute the benchmarks to obtain the time results in `testComplexity::asymptoticTimings()`, for the added convenience of having the benchmarked results as a data frame plus for the precision or time scale it produces the results on. (usually in nanoseconds, as can be found from [here](https://cran.r-project.org/web/packages/microbenchmark/microbenchmark.pdf)) \u003cbr\u003e\n- `bench::bench_memory()` is used to compute the allocated memory size in order to obtain the memory use metrics in `testComplexity::asymptoticMemoryUsage()`. \u003cbr\u003e\n            \n\u003ch2 align = \"center\"\u003e\nTesting\n\u003c/h2\u003e\n\n- **Functions** \u003cbr\u003e\nCurrent set of functions taken into consideration for testing our functionality, plus a dedicated vignette-based article for each can be found below:  \n\n| Source Package | Function | Article Link |\n|----------------|----------|--------------|\n| base           | gregexpr    | [Quadratic to linear transition for substring and gregexpr](https://anirban166.github.io/testComplexity/articles/substring_and_gregexpr.html) |\n| base           | substring   | [Quadratic to linear transition for substring and gregexpr](https://anirban166.github.io/testComplexity/articles/substring_and_gregexpr.html) |\n| fpop           | Fpop        | [fpop::Fpop(), a log-linear time segmentation algorithm](https://anirban166.github.io/testComplexity/articles/fpop.html) |\n| gfpop          | gfpop       | [gfpop::gfpop(), a log-linear time algorithm for constrained changepoint detection](https://anirban166.github.io/testComplexity/articles/gfpop.html) |\n| opart          | gaussian    | [opart::gaussian(), a quadratic time optimal partioning algorithm](https://anirban166.github.io/testComplexity/articles/opart.html) |\n| PeakSegDP      | cDPA        | [PeakSegDP::cDPA, a quadratic time constrained dynamic programming algorithm](https://anirban166.github.io/testComplexity/articles/cDPA.html) |\n| changepoint    | cpt.mean    | [PELT and SegNeigh algorithms for changepoint::cpt.mean()](https://anirban166.github.io/testComplexity/articles/PELT_and_SegNeigh.html) |\n| PeakSegOptimal | PeakSegPDPA | [PeakSegOptimal::PeakSegPDPA, a log-linear time algorithm for constrained changepoint detection](https://anirban166.github.io/testComplexity/articles/PeakSegPDPA.html) |\n\nA complexity-wise ordered list with functional instances for the aforementioned set of functions can be found [here](https://github.com/Anirban166/testComplexity/issues/2#issue-615087634). \u003cbr\u003e\n- **Unit Testing** \u003cbr\u003e\nTest cases for testComplexity functions via [testthat](https://cran.r-project.org/web/packages/testthat/index.html) package can be found [here](https://github.com/Anirban166/testComplexity/blob/master/tests/testthat/test-testsfortestComplexity.R). \u003cbr\u003e\n- **Code Coverage** \u003cbr\u003e\nTested using `covr::package_coverage()` both locally and via codecov, with [100% coverage](https://codecov.io/gh/Anirban166/testComplexity?branch=master) attained. \u003cbr\u003e\n- **OS Support** \u003cbr\u003e\nWindows is the native OS this package is developed and tested on, but in addition to that, RCMD checks are run on latest versions of [MacOS](https://github.com/Anirban166/testComplexity/blob/cdb771a040e77ac02e715f033a7debf889a8efa2/.github/workflows/R-CMD-check.yaml#L21) and [Ubuntu](https://github.com/Anirban166/testComplexity/blob/cdb771a040e77ac02e715f033a7debf889a8efa2/.github/workflows/R-CMD-check.yaml#L22) as well. \u003cbr\u003e\nNote that the use of `bench::bench_memory()` overcomes the drawback of windows-only OS limitation for memory complexity testing as observed in `GuessCompx::CompEst()` since it successfully runs on other operating systems. \u003cbr\u003e\n\n\u003cp align = \"center\"\u003e\n\u003ca href = \"https://www.microsoft.com/en-in/windows\"\u003e \u003cimg src = \"https://img.shields.io/badge/Windows--brightgreen?style=for-the-badge\u0026logo=Windows\"\u003e \u003ca href = \"https://www.linux.org/\"\u003e \u003cimg src = \"https://img.shields.io/badge/Linux--brightgreen?style=for-the-badge\u0026logo=Linux\"\u003e \u003ca href = \"https://developer.apple.com/macos/\"\u003e \u003cimg src = \"https://img.shields.io/badge/MacOS--brightgreen?style=for-the-badge\u0026logo=Apple\"\u003e \u003c/a\u003e\n\u003c/p\u003e \n\n\u003ch2 align=\"center\"\u003e\nResources\n\u003c/h2\u003e\n\nIn addition to the readme content, the [web version](https://anirban166.github.io/testComplexity/) includes quick [reference](https://anirban166.github.io/testComplexity/reference/index.html) to functions plus vignettes for some use-cases. For [blog](https://anirban166.github.io/posts/) posts, please check the links below: \u003cbr\u003e\n\n\u003cp align = \"center\"\u003e\n\u003ca href = \"https://anirban166.github.io//Test-functions/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoTF.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//Timings-quantifying-function/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoTQ.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//Memory-usage-quantifier/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoMQ.png\"\u003e \n\u003ca href=\"https://anirban166.github.io//Complexity-classifiers/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoCC.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//Plotters/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoPT.png\"\u003e \u003c/a\u003e \u003cbr\u003e\n\u003ca href = \"https://anirban166.github.io//Generalized-complexity/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoGC.png\"\u003e\n\u003ca href = \"https://anirban166.github.io//Testing-functions/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoTS.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//Website/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoWS.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//Software-Development/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoSD.png\"\u003e \n\u003ca href = \"https://anirban166.github.io//GSoC-2020-Summary/\"\u003e \u003cimg width = \"12.5%\" src = \"/Images/LogoPKG.png\"\u003e \u003cbr\u003e\n\u003c/p\u003e\n    \n---\n\u003cp align = \"center\"\u003e\n    \u003ca href = \"https://summerofcode.withgoogle.com/projects/4887653356404736\"\u003e \n    \u003cimg width = \"15%\" src = \"https://img.shields.io/badge/--black?style=flat\u0026logo=google\"\n         alt = \"Google Summer of Code Project Link\"\u003e \n    \u003ca href = \"mailto:bloodraven166@gmail.com\"\u003e \n    \u003cimg width = \"15%\" src = \"https://img.shields.io/badge/--black?style=flat\u0026logo=gmail\"\n         alt = \"Email\"\u003e\n    \u003ca href = \"https://github.com/Anirban166\"\u003e\n    \u003cimg width = \"15%\" src = \"https://img.shields.io/badge/--black?style=flat\u0026logo=Github\"\n         alt = \"GitHub Link\"\u003e                  \n    \u003ca href = \"https://www.linkedin.com/in/anirban166/\"\u003e\n    \u003cimg width = \"15%\" src = \"https://img.shields.io/badge/--black?style=flat\u0026logo=LinkedIn\"\n         alt = \"LinkedIn Link\"\u003e\n\u003c/p\u003e         \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanirban166%2Ftestcomplexity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanirban166%2Ftestcomplexity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanirban166%2Ftestcomplexity/lists"}