From e3aacd87d3f47dc6de86ec17767d8c245857e2c9 Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Wed, 3 Apr 2019 18:20:13 +0100 Subject: [PATCH 1/9] #50 Re-enable C++ code --- App-1/server.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/App-1/server.R b/App-1/server.R index 9c7994e..1d4d679 100644 --- a/App-1/server.R +++ b/App-1/server.R @@ -234,7 +234,8 @@ shinyServer(function(input, output) { output$language <- renderUI({ selectInput("language", "Language", - c("Mathematica"="Mathematica", + c("C++"="Cplusplus", + "Mathematica"="Mathematica", "Matlab"="Matlab", "Python"="Python", "R"="R", From da7d722b5f515e6553854bda4495214387c04784 Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Wed, 3 Apr 2019 18:20:36 +0100 Subject: [PATCH 2/9] #50 First attempt at adding some C++ code --- App-1/code_cplusplus.R | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index af65695..98e9bca 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -1,8 +1,43 @@ fCpluspluscode <- function(input){ text <- if(input$dist=="Normal"){ + common.pdf <- paste0( + "#include <cassert>\n", + "#include <cmath>\n", + "\n", + "class NormalDistributionPdf {\n", + "private:\n", + " // Params\n", + " double mMean;\n", + " double mStdDev;\n", + "\n", + " // Cached constants for Pdf & LogPdf\n", + " double m2SigSq;\n", + " double mPrefactor;\n", + " double mLogPrefactor;\n", + "\n", + "public:\n", + " explicit NormalDistributionPdf(double mean = 0.0, double std_dev = 1.0)\n", + " : mMean(mean), mStdDev(std_dev) {\n", + "\n", + " // Standard deviation must be positive\n", + " assert(mStdDev > 0.0);\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ) if(input$property=="pdf") - paste("#include <math>", + paste(common.pdf, "#include <math>", paste("double normal_pdf(int n, double mu, double sigma)", "{", paste0("return 1.0 / (std::sqrt(2.0 * M_PI) * ", From 926274c9ce117d61645c08a9701e6c06f586ad3d Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Wed, 3 Apr 2019 20:50:33 +0100 Subject: [PATCH 3/9] Utility file for converting text file to "paste0" format --- translate_file_to_paste0.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 translate_file_to_paste0.py diff --git a/translate_file_to_paste0.py b/translate_file_to_paste0.py new file mode 100644 index 0000000..dde1423 --- /dev/null +++ b/translate_file_to_paste0.py @@ -0,0 +1,35 @@ +import os +import sys + +if len(sys.argv) != 2: + print('\nPlease specify file to translate.\n\nUsage: {} /path/to/file\n'.format(sys.argv[0])) + sys.exit(1) + +file_to_translate = sys.argv[1] +if not os.path.isfile(file_to_translate): + print('\n{} is not a valid file.\n'.format(file_to_translate)) + +with open(file_to_translate, 'r') as f: + lines = f.readlines() + +new_lines = ['var.name <- paste0('] + +for line in lines: + + if r'{{{ignore}}}' in line.lower(): + continue + + line = line.replace('<', r'<') + line = line.replace('>', r'>') + line = line.replace('"', r'\"') + + line = r' "{}\n",'.format(line.replace('\n','')) + + line = line.replace(r'~~~', r'", eval(parse(text=input$VAR_NAME)), "') + + new_lines.append(line) + +new_lines.append(' ""\n)') + + +print('\n'.join(new_lines)) \ No newline at end of file From f5f4ad24a86e7efc3b85c312032f92a364168064 Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Wed, 3 Apr 2019 20:50:53 +0100 Subject: [PATCH 4/9] #50 C++ for Normal, and "coming soon" for beta --- App-1/code_cplusplus.R | 149 +++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 58 deletions(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index 98e9bca..30e6fca 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -1,7 +1,7 @@ fCpluspluscode <- function(input){ text <- if(input$dist=="Normal"){ - common.pdf <- paste0( + text.common <- paste0( "#include <cassert>\n", "#include <cmath>\n", "\n", @@ -21,75 +21,108 @@ fCpluspluscode <- function(input){ " : mMean(mean), mStdDev(std_dev) {\n", "\n", " // Standard deviation must be positive\n", - " assert(mStdDev > 0.0);\n", - "\n", - "\n", - "\n", - "\n", + " assert(mStdDev > 0.0);\n", + "\n", + " m2SigSq = 2.0 * mStdDev * mStdDev;\n", + " mPrefactor = 1.0 / std::sqrt(M_PI * m2SigSq);\n", + " mLogPrefactor = -0.5 * std::log(M_PI * m2SigSq);\n", + " }\n", + "\n", + " double Pdf(const double x) {\n", + " return mPrefactor * exp(-(x - mMean) * (x - mMean) / m2SigSq);\n", + " }\n", + "\n", + " double LogPdf(const double x) {\n", + " return mLogPrefactor - (x - mMean) * (x - mMean) / m2SigSq;\n", + " }\n", + "};\n", + "" + ) + + text.pdf <- paste0( + "int main() {\n", "\n", + " // Create distribution with required parameters\n", + " NormalDistributionPdf pdf{", eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), "};\n", "\n", + " // Sample from the pdf at any given x-value:\n", + " pdf.Pdf(0.5);\n", "\n", + " return 0;\n", + "}\n", + "" + ) + + text.logpdf <- paste0( + "int main() {\n", "\n", + " // Create distribution with required parameters\n", + " NormalDistributionPdf pdf{", eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), "};\n", "\n", + " // Sample from the log pdf at any given x-value:\n", + " pdf.LogPdf(0.5);\n", "\n", + " return 0;\n", + "}\n", + "" + ) + + text.samples <- paste0( + "#include <random>\n", "\n", + "int main() {\n", + " // Seed a Mersenne twister with a 'true' random seed from random_device\n", + " std::random_device rd{};\n", + " std::mt19937 gen{rd()};\n", "\n", - "\n" + " // Params\n", + " const std::size_t n = 100'000;\n", + " const double mean = ", eval(parse(text=input$normal_mu)), ";\n", + " const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", + "\n", + " // Create distribution\n", + " std::normal_distribution<double> dist{mean, std_dev};\n", + "\n", + " // Create and fill the vector\n", + " std::vector<double> vec(n);\n", + " for (double &x : vec) {\n", + " x = dist(gen);\n", + " }\n", + "\n", + " return 0;\n", + "}\n", + "" + ) + + if(input$property=="pdf") + paste(text.common, text.pdf, sep="\n") + else if(input$property=="log_pdf") + paste(text.common, text.logpdf, sep="\n") + else if(input$property=="random") + paste(text.samples) + } else if(input$dist=="Beta"){ + text.common <- paste0( + "Coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "Coming soon!" ) + if(input$property=="pdf") - paste(common.pdf, "#include <math>", - paste("double normal_pdf(int n, double mu, double sigma)", - "{", - paste0("return 1.0 / (std::sqrt(2.0 * M_PI) * ", - eval(parse(text=input$normal_sigma)), - ") * exp(-pow(x - ", - eval(parse(text=input$normal_mu)), - ", 2.0) / (2 * pow(", - input$normal_sigma, ", 2.0)));"), - "}", - sep="\n"), - sep="\n") + paste(text.common, text.pdf, sep="\n") else if(input$property=="log_pdf") - paste("#include <math>", - paste("double normal_lpdf(int n, double mu, double sigma)", - "{", - paste0("return -0.5 * log(2 * M_PI) - log(", - eval(parse(text=input$normal_sigma)), - ") - pow(x - ", - eval(parse(text=input$normal_mu)), - ", 2.0) / (2 * pow(", - input$normal_sigma, ", 2.0)));"), - "}", - sep="\n"), sep="\n") + paste(text.common, text.logpdf, sep="\n") else if(input$property=="random") - paste("#include <random>", - "#include <vector>", - "#include <math>", - "#include <chrono>", - "// unseeded", - paste0("std::vector<double> normal_rng(int n, double mu, double sigma)", "\n", - "{", - "\n", - "unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();", "\n", - "std::normal_distribution<double> distribution(", - eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), ");", "\n", - "std::vector<double> samples(n);", "\n", - "for(int i = 0; i < n; i++)", "\n", - " ", "samples[i] = distribution(generator);", "\n", - "return samples;", "\n", - "}"), - "// seeded", - paste0("std::vector<double> normal_rng(int n, double mu, double sigma, unsigned seed)", "\n", - "{", - "\n", - "std::normal_distribution<double> distribution(", - eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), ");", "\n", - "std::vector<double> samples(n);", "\n", - "for(int i = 0; i < n; i++)", "\n", - " ", "samples[i] = distribution(generator);", "\n", - "return samples;", "\n", - "}"), - sep = "\n") + paste(text.samples) } return(prismCodeBlock(text, language = "cpp")) } From 61e744b9b600730f2e3ee5d894df7ceb2b774e36 Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Wed, 3 Apr 2019 21:10:31 +0100 Subject: [PATCH 5/9] #50 Rearrange to reduce code duplication, and add coming soon --- App-1/code_cplusplus.R | 202 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 186 insertions(+), 16 deletions(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index 30e6fca..6254e2e 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -1,5 +1,4 @@ fCpluspluscode <- function(input){ - text <- if(input$dist=="Normal"){ text.common <- paste0( "#include <cassert>\n", @@ -93,16 +92,89 @@ fCpluspluscode <- function(input){ "}\n", "" ) + } else if(input$dist=="Uniform"){ + text.common <- paste0( + "Uniform coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "Uniform coming soon!" + ) + } else if(input$dist=="LogNormal"){ + text.common <- paste0( + "LogNormal coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "LogNormal coming soon!" + ) + } else if(input$dist=="Exponential"){ + text.common <- paste0( + "Exponential coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) - if(input$property=="pdf") - paste(text.common, text.pdf, sep="\n") - else if(input$property=="log_pdf") - paste(text.common, text.logpdf, sep="\n") - else if(input$property=="random") - paste(text.samples) + text.samples <- paste0( + "Exponential coming soon!" + ) + } else if(input$dist=="Gamma"){ + text.common <- paste0( + "Gamma coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "Gamma coming soon!" + ) + } else if(input$dist=="t"){ + text.common <- paste0( + "t coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "t coming soon!" + ) } else if(input$dist=="Beta"){ text.common <- paste0( - "Coming soon!" + "Beta coming soon!" ) text.pdf <- paste0( @@ -114,15 +186,113 @@ fCpluspluscode <- function(input){ ) text.samples <- paste0( - "Coming soon!" + "Beta coming soon!" + ) + } else if(input$dist=="Cauchy"){ + text.common <- paste0( + "Cauchy coming soon!" ) - if(input$property=="pdf") - paste(text.common, text.pdf, sep="\n") - else if(input$property=="log_pdf") - paste(text.common, text.logpdf, sep="\n") - else if(input$property=="random") - paste(text.samples) + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "Cauchy coming soon!" + ) + } else if(input$dist=="HalfCauchy"){ + text.common <- paste0( + "HalfCauchy coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "HalfCauchy coming soon!" + ) + } else if(input$dist=="InverseGamma"){ + text.common <- paste0( + "InverseGamma coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "InverseGamma coming soon!" + ) + } else if(input$dist=="InverseChiSquared"){ + text.common <- paste0( + "InverseChiSquared coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "InverseChiSquared coming soon!" + ) + } else if(input$dist=="LogitNormal"){ + text.common <- paste0( + "LogitNormal coming soon!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "LogitNormal coming soon!" + ) + } else { + text.common <- paste0( + "Not done yet!" + ) + + text.pdf <- paste0( + "" + ) + + text.logpdf <- paste0( + "" + ) + + text.samples <- paste0( + "Not done yet!" + ) } - return(prismCodeBlock(text, language = "cpp")) + + text.to.display <- + if(input$property=="pdf") + paste(text.common, text.pdf, sep="\n") + else if(input$property=="log_pdf") + paste(text.common, text.logpdf, sep="\n") + else if(input$property=="random") + paste(text.samples) + + return(prismCodeBlock(text.to.display, language = "cpp")) } From 80f147948fc8a66041c433e9611adacd93f3a38f Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Thu, 4 Apr 2019 14:42:55 +0100 Subject: [PATCH 6/9] Add vscode to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 69504d3..115ca73 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .Rhistory .Rhistory .Rhistory + +.vscode \ No newline at end of file From 1d835a444f90e70d802f1a2433537b0d9de96d6e Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Thu, 4 Apr 2019 14:43:55 +0100 Subject: [PATCH 7/9] #50 Change C++ code to "useful" + dependencies boxes --- App-1/code_cplusplus.R | 316 +++++++++++++++++------------------------ 1 file changed, 131 insertions(+), 185 deletions(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index 6254e2e..507aac2 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -1,6 +1,9 @@ fCpluspluscode <- function(input){ if(input$dist=="Normal"){ - text.common <- paste0( + text.common.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", "#include <cassert>\n", "#include <cmath>\n", "\n", @@ -28,7 +31,7 @@ fCpluspluscode <- function(input){ " }\n", "\n", " double Pdf(const double x) {\n", - " return mPrefactor * exp(-(x - mMean) * (x - mMean) / m2SigSq);\n", + " return mPrefactor * std::exp(-(x - mMean) * (x - mMean) / m2SigSq);\n", " }\n", "\n", " double LogPdf(const double x) {\n", @@ -37,262 +40,205 @@ fCpluspluscode <- function(input){ "};\n", "" ) - text.pdf <- paste0( - "int main() {\n", - "\n", - " // Create distribution with required parameters\n", - " NormalDistributionPdf pdf{", eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), "};\n", + "const double mean = ", eval(parse(text=input$normal_mu)), ";\n", + "const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", + "NormalDistributionPdf pdf{mean, std_dev};\n", "\n", - " // Sample from the pdf at any given x-value:\n", - " pdf.Pdf(0.5);\n", - "\n", - " return 0;\n", - "}\n", + "// Sample from the pdf at any given x-value:\n", + "pdf.Pdf(0.5);\n", "" ) - text.logpdf <- paste0( - "int main() {\n", - "\n", - " // Create distribution with required parameters\n", - " NormalDistributionPdf pdf{", eval(parse(text=input$normal_mu)), ", ", eval(parse(text=input$normal_sigma)), "};\n", + "const double mean = ", eval(parse(text=input$normal_mu)), ";\n", + "const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", + "NormalDistributionPdf pdf{mean, std_dev};\n", "\n", - " // Sample from the log pdf at any given x-value:\n", - " pdf.LogPdf(0.5);\n", + "// Sample from the pdf at any given x-value:\n", + "pdf.LogPdf(0.5);\n", + "" + ) + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", "\n", - " return 0;\n", - "}\n", + "#include <random>\n", + "#include <vector>\n", "" ) - text.samples <- paste0( - "#include <random>\n", - "\n", - "int main() {\n", - " // Seed a Mersenne twister with a 'true' random seed from random_device\n", - " std::random_device rd{};\n", - " std::mt19937 gen{rd()};\n", - "\n", - " // Params\n", - " const std::size_t n = 100'000;\n", - " const double mean = ", eval(parse(text=input$normal_mu)), ";\n", - " const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", - "\n", - " // Create distribution\n", - " std::normal_distribution<double> dist{mean, std_dev};\n", - "\n", - " // Create and fill the vector\n", - " std::vector<double> vec(n);\n", - " for (double &x : vec) {\n", - " x = dist(gen);\n", - " }\n", - "\n", - " return 0;\n", + "// Seed a Mersenne twister with a 'true' random seed from random_device\n", + "std::random_device rd{};\n", + "std::mt19937 gen{rd()};\n", + "\n", + "// Params\n", + "const std::size_t n = 100'000;\n", + "const double mean = ", eval(parse(text=input$normal_mu)), ";\n", + "const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", + "\n", + "// Create distribution\n", + "std::normal_distribution<double> dist{mean, std_dev};\n", + "\n", + "// Create and fill the vector\n", + "std::vector<double> vec(n);\n", + "for (double &x : vec) {\n", + " x = dist(gen);\n", "}\n", "" ) } else if(input$dist=="Uniform"){ - text.common <- paste0( - "Uniform coming soon!" + text.common.dep <- paste0("Uniform coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Uniform coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Uniform coming soon" ) - - text.samples <- paste0( - "Uniform coming soon!" + text.samples.dep <- paste0("Uniform coming soon" + ) + text.samples <- paste0("Uniform coming soon" ) } else if(input$dist=="LogNormal"){ - text.common <- paste0( - "LogNormal coming soon!" + text.common.dep <- paste0("LogNormal coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("LogNormal coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("LogNormal coming soon" ) - - text.samples <- paste0( - "LogNormal coming soon!" + text.samples.dep <- paste0("LogNormal coming soon" + ) + text.samples <- paste0("LogNormal coming soon" ) } else if(input$dist=="Exponential"){ - text.common <- paste0( - "Exponential coming soon!" + text.common.dep <- paste0("Exponential coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Exponential coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Exponential coming soon" ) - - text.samples <- paste0( - "Exponential coming soon!" + text.samples.dep <- paste0("Exponential coming soon" + ) + text.samples <- paste0("Exponential coming soon" ) } else if(input$dist=="Gamma"){ - text.common <- paste0( - "Gamma coming soon!" + text.common.dep <- paste0("Gamma coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Gamma coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Gamma coming soon" ) - - text.samples <- paste0( - "Gamma coming soon!" + text.samples.dep <- paste0("Gamma coming soon" + ) + text.samples <- paste0("Gamma coming soon" ) } else if(input$dist=="t"){ - text.common <- paste0( - "t coming soon!" + text.common.dep <- paste0("t coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("t coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("t coming soon" ) - - text.samples <- paste0( - "t coming soon!" + text.samples.dep <- paste0("t coming soon" + ) + text.samples <- paste0("t coming soon" ) } else if(input$dist=="Beta"){ - text.common <- paste0( - "Beta coming soon!" + text.common.dep <- paste0("Beta coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Beta coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Beta coming soon" ) - - text.samples <- paste0( - "Beta coming soon!" + text.samples.dep <- paste0("Beta coming soon" + ) + text.samples <- paste0("Beta coming soon" ) } else if(input$dist=="Cauchy"){ - text.common <- paste0( - "Cauchy coming soon!" + text.common.dep <- paste0("Cauchy coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Cauchy coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Cauchy coming soon" ) - - text.samples <- paste0( - "Cauchy coming soon!" + text.samples.dep <- paste0("Cauchy coming soon" + ) + text.samples <- paste0("Cauchy coming soon" ) } else if(input$dist=="HalfCauchy"){ - text.common <- paste0( - "HalfCauchy coming soon!" + text.common.dep <- paste0("HalfCauchy coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("HalfCauchy coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("HalfCauchy coming soon" ) - - text.samples <- paste0( - "HalfCauchy coming soon!" + text.samples.dep <- paste0("HalfCauchy coming soon" + ) + text.samples <- paste0("HalfCauchy coming soon" ) } else if(input$dist=="InverseGamma"){ - text.common <- paste0( - "InverseGamma coming soon!" + text.common.dep <- paste0("InverseGamma coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("InverseGamma coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("InverseGamma coming soon" ) - - text.samples <- paste0( - "InverseGamma coming soon!" + text.samples.dep <- paste0("InverseGamma coming soon" + ) + text.samples <- paste0("InverseGamma coming soon" ) } else if(input$dist=="InverseChiSquared"){ - text.common <- paste0( - "InverseChiSquared coming soon!" + text.common.dep <- paste0("InverseChiSquared coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("InverseChiSquared coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("InverseChiSquared coming soon" ) - - text.samples <- paste0( - "InverseChiSquared coming soon!" + text.samples.dep <- paste0("InverseChiSquared coming soon" + ) + text.samples <- paste0("InverseChiSquared coming soon" ) } else if(input$dist=="LogitNormal"){ - text.common <- paste0( - "LogitNormal coming soon!" + text.common.dep <- paste0("LogitNormal coming soon" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("LogitNormal coming soon" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("LogitNormal coming soon" ) - - text.samples <- paste0( - "LogitNormal coming soon!" + text.samples.dep <- paste0("LogitNormal coming soon" + ) + text.samples <- paste0("LogitNormal coming soon" ) } else { - text.common <- paste0( - "Not done yet!" + text.common.dep <- paste0("Not done yet!" ) - - text.pdf <- paste0( - "" + text.pdf <- paste0("Not done yet!" ) - - text.logpdf <- paste0( - "" + text.logpdf <- paste0("Not done yet!" ) - - text.samples <- paste0( - "Not done yet!" + text.samples.dep <- paste0("Not done yet!" + ) + text.samples <- paste0("Not done yet!" ) } - text.to.display <- - if(input$property=="pdf") - paste(text.common, text.pdf, sep="\n") - else if(input$property=="log_pdf") - paste(text.common, text.logpdf, sep="\n") - else if(input$property=="random") - paste(text.samples) - - return(prismCodeBlock(text.to.display, language = "cpp")) + text.to.display.main <- + if(input$property=="pdf") { + text.pdf + } else if(input$property=="log_pdf") { + text.logpdf + } else if(input$property=="random") { + text.samples + } + + text.to.display.dep <- + if(input$property=="random") { + text.samples.dep + } else { + text.common.dep + } + + return(tagList( + prismCodeBlock(text.to.display.main, language = "cpp"), + prismCodeBlock(text.to.display.dep, language = "cpp") + ) + ) } From 39fec900f37adef9791ede7314e40d21ee6d82fb Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Thu, 4 Apr 2019 14:52:15 +0100 Subject: [PATCH 8/9] #50 All sample deps are the same --- App-1/code_cplusplus.R | 88 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 11 deletions(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index 507aac2..b2bdc91 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -93,7 +93,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("Uniform coming soon" ) - text.samples.dep <- paste0("Uniform coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("Uniform coming soon" ) @@ -104,7 +110,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("LogNormal coming soon" ) - text.samples.dep <- paste0("LogNormal coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("LogNormal coming soon" ) @@ -115,7 +127,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("Exponential coming soon" ) - text.samples.dep <- paste0("Exponential coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("Exponential coming soon" ) @@ -126,7 +144,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("Gamma coming soon" ) - text.samples.dep <- paste0("Gamma coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("Gamma coming soon" ) @@ -137,7 +161,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("t coming soon" ) - text.samples.dep <- paste0("t coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("t coming soon" ) @@ -148,7 +178,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("Beta coming soon" ) - text.samples.dep <- paste0("Beta coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("Beta coming soon" ) @@ -159,7 +195,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("Cauchy coming soon" ) - text.samples.dep <- paste0("Cauchy coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("Cauchy coming soon" ) @@ -170,7 +212,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("HalfCauchy coming soon" ) - text.samples.dep <- paste0("HalfCauchy coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("HalfCauchy coming soon" ) @@ -181,7 +229,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("InverseGamma coming soon" ) - text.samples.dep <- paste0("InverseGamma coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("InverseGamma coming soon" ) @@ -192,7 +246,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("InverseChiSquared coming soon" ) - text.samples.dep <- paste0("InverseChiSquared coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("InverseChiSquared coming soon" ) @@ -203,7 +263,13 @@ fCpluspluscode <- function(input){ ) text.logpdf <- paste0("LogitNormal coming soon" ) - text.samples.dep <- paste0("LogitNormal coming soon" + text.samples.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <random>\n", + "#include <vector>\n", + "" ) text.samples <- paste0("LogitNormal coming soon" ) From 0da6dba28a839f1da78ef24c5684ddae404965a6 Mon Sep 17 00:00:00 2001 From: Fergus Cooper Date: Thu, 4 Apr 2019 15:01:02 +0100 Subject: [PATCH 9/9] #50 Add beta --- App-1/code_cplusplus.R | 97 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/App-1/code_cplusplus.R b/App-1/code_cplusplus.R index b2bdc91..195f996 100644 --- a/App-1/code_cplusplus.R +++ b/App-1/code_cplusplus.R @@ -54,7 +54,7 @@ fCpluspluscode <- function(input){ "const double std_dev = ", eval(parse(text=input$normal_sigma)), ";\n", "NormalDistributionPdf pdf{mean, std_dev};\n", "\n", - "// Sample from the pdf at any given x-value:\n", + "// Sample from the log pdf at any given x-value:\n", "pdf.LogPdf(0.5);\n", "" ) @@ -172,11 +172,78 @@ fCpluspluscode <- function(input){ text.samples <- paste0("t coming soon" ) } else if(input$dist=="Beta"){ - text.common.dep <- paste0("Beta coming soon" + text.common.dep <- paste0( + "// The code above depends on the following, which you can copy directly into your application\n", + "// Note that C++11 (or later) is required\n", + "\n", + "#include <cassert>\n", + "#include <cmath>\n", + "#include <limits>\n", + "\n", + "class BetaDistributionPdf {\n", + "private:\n", + " // Params\n", + " double mAlpha;\n", + " double mBeta;\n", + "\n", + " // Cached constants for Pdf & LogPdf\n", + " double m1OnBetaFn;\n", + " double mLogBetaFn;\n", + " double mAm1;\n", + " double mBm1;\n", + "\n", + "public:\n", + " explicit BetaDistributionPdf(double alpha = 1.0, double beta = 1.0)\n", + " : mAlpha(alpha), mBeta(beta) {\n", + "\n", + " // Both params must be positive\n", + " assert(mAlpha > 0.0);\n", + " assert(mBeta > 0.0);\n", + "\n", + " // Constants for Beta function evaluations\n", + " m1OnBetaFn = std::tgamma(mAlpha + mBeta) / (std::tgamma(mAlpha) * std::tgamma(mBeta));\n", + " mLogBetaFn = std::lgamma(mAlpha + mBeta) - (std::lgamma(mAlpha) + std::lgamma(mBeta));\n", + "\n", + " // Other useful constants\n", + " mAm1 = mAlpha - 1.0;\n", + " mBm1 = mBeta - 1.0;\n", + " }\n", + "\n", + " double Pdf(const double x) {\n", + " if (x > 0.0 && x < 1.0) {\n", + " return std::pow(x, mAm1) * std::pow(1.0 - x, mBm1) * m1OnBetaFn;\n", + " } else {\n", + " return 0.0;\n", + " }\n", + " }\n", + "\n", + " double LogPdf(const double x) {\n", + " if (x > 0.0 && x < 1.0) {\n", + " return mAm1 * std::log(x) + mBm1 * std::log1p(-x) + mLogBetaFn;\n", + " } else {\n", + " return -std::numeric_limits<double>::infinity();\n", + " }\n", + " }\n", + "};\n", + "" ) - text.pdf <- paste0("Beta coming soon" + text.pdf <- paste0( + "const double alpha = ", eval(parse(text=input$beta_a)), ";\n", + "const double beta = ", eval(parse(text=input$beta_b)), ";\n", + "BetaDistributionPdf pdf{alpha, beta};\n", + "\n", + "// Sample from the pdf at any given x-value:\n", + "pdf.Pdf(0.5);\n", + "" ) - text.logpdf <- paste0("Beta coming soon" + text.logpdf <- paste0( + "const double alpha = ", eval(parse(text=input$beta_a)), ";\n", + "const double beta = ", eval(parse(text=input$beta_b)), ";\n", + "BetaDistributionPdf pdf{alpha, beta};\n", + "\n", + "// Sample from the log pdf at any given x-value:\n", + "pdf.LogPdf(0.5);\n", + "" ) text.samples.dep <- paste0( "// The code above depends on the following, which you can copy directly into your application\n", @@ -186,7 +253,27 @@ fCpluspluscode <- function(input){ "#include <vector>\n", "" ) - text.samples <- paste0("Beta coming soon" + text.samples <- paste0( + "// Seed a Mersenne twister with a 'true' random seed from random_device\n", + "std::random_device rd{};\n", + "std::mt19937 gen{rd()};\n", + "\n", + "// Params\n", + "const std::size_t n = 100'000;\n", + "const double alpha = ", eval(parse(text=input$beta_a)), ";\n", + "const double beta = ", eval(parse(text=input$beta_b)), ";\n", + "\n", + "// No beta distribution in the standard library, so construct samples using two Gammas\n", + "std::gamma_distribution<double> dis_alpha(alpha, 1.0);\n", + "std::gamma_distribution<double> dis_beta(beta, 1.0);\n", + "\n", + "// Create and fill the vector\n", + "std::vector<double> vec(n);\n", + "for (double &x : vec) {\n", + " const double alpha_sample = dis_alpha(gen);\n", + " x = alpha_sample / (alpha_sample + dis_beta(gen));\n", + "}\n", + "" ) } else if(input$dist=="Cauchy"){ text.common.dep <- paste0("Cauchy coming soon"