1 #define _USE_MATH_DEFINES    11 #include <boost/random/mersenne_twister.hpp>    12 #include <boost/random/uniform_real_distribution.hpp>    13 #include <boost/random/variate_generator.hpp>    15 #include <Eigen/Dense>    18 #include "function_dispatcher.h"    19 #include "json_object.h"    20 #include "lognormal_dist.h"    21 #include "normal_dist.h"    22 #include "normal_multivar.h"    23 #include "numeric_utils.h"    24 #include "vlachos_et_al.h"    27                                      double rupture_distance, 
double vs30,
    29                                      unsigned int num_spectra,
    30                                      unsigned int num_sims)
    32       moment_magnitude_{moment_magnitude / 6.0},
    33       rupture_dist_{(rupture_distance + 5.0) / 30.0},
    35       orientation_{orientation},
    39       num_spectra_{num_spectra},
    41       seed_value_{std::numeric_limits<int>::infinity()},
    42       model_parameters_{18} {
    43   model_name_ = 
"VlachosEtAl";
    45   double site_soft = 0.0, site_medium = 0.0, site_hard = 0.0;
    48   } 
else if (vs30 <= 450.0) {
    55   Eigen::VectorXd conditional_means(7);
    58       1.0, moment_magnitude_, std::log(rupture_dist_),
    59       moment_magnitude_ * std::log(rupture_dist_), site_soft * std::log(vs30_),
    60       site_medium * std::log(vs30_), site_hard * std::log(vs30_);
    65   Eigen::MatrixXd beta(18, 7);
    68     -1.1417, 1.0917, 1.9125, -0.9696, 0.0971, 0.3476, -0.6740,
    69     1.8052,-1.8381, -3.5874, 3.7895, 0.3236, 0.5497, 0.2876,
    70     1.8969,-1.8819, -2.0818, 1.9000, -0.3520, -0.6959, -0.0025,
    71     1.6627,-1.6922, -1.2509, 1.1880, -0.5170, -1.0157, -0.1041,
    72     3.8703,-3.4745, -0.0816, 0.0166, 0.4904, 0.8697, 0.3179,
    73     1.1043,-1.1852, -1.0068, 0.9388, -0.5603, -0.8855, -0.3174,
    74     1.1935,-1.2922, -0.7028, 0.6975, -0.6629, -1.1075, -0.4542,
    75     1.7895,-1.5014, -0.0300, -0.1306, 0.4526, 0.7132, 0.1522,
    76     -3.6404, 3.3189, -0.5316, 0.3874, -0.3757, -0.8334, 0.1006,
    77     -2.2742, 2.1454, 0.6315, -0.6620, 0.1093, -0.1028, -0.0479,
    78     0.6930, -0.6202, 1.8037, -1.6064, 0.0727, -0.1498, -0.0722,
    79     1.3003, -1.2004, -1.2210, 1.0623, -0.0252, 0.1885, 0.0069,
    80     0.4604, -0.4087, -0.5057, 0.4486, 0.1073, -0.0219, -0.1352,
    81     2.2304, -2.0398, -0.1364, 0.1910, 0.2425, 0.1801, 0.3233,
    82     2.3806, -2.2011, -0.3256, 0.2226, -0.0221, 0.0970, 0.0762,
    83     0.2057, -0.1714, 0.3385, -0.2229, 0.0802, 0.2649, 0.0396,
    84     -7.6011, 6.8507, -2.3609, 0.9201, -0.7508, -0.7903, -0.6204,
    85     -6.3472, 5.8241, 3.2994, -2.8774, -0.1411, -0.5298, -0.0203;
    89   Eigen::VectorXd variance(18);
    92       0.90, 0.80, 0.78, 0.74, 0.66, 0.73, 0.72, 0.70, 0.69,
    93       0.78, 0.90, 0.90, 0.90, 0.90, 0.80, 0.90, 0.35, 0.80;
    97   Eigen::MatrixXd correlation_matrix(18, 18);
   100     1.0000, 0.0382, -0.0912, -0.0701, -0.0214, -0.0849, -0.0545, -0.0185, 0.0270, -0.0122, 0.0059, -0.0344, -0.0342, 0.0409, -0.0137, -0.0168, -0.0990, -0.6701,
   101     0.0382, 1.0000, -0.1159, -0.1856, 0.0681, -0.2018, -0.2765, -0.0304, -0.1719, -0.1157, -0.0347, -0.0277, -0.0189, 0.0357, 0.0657, -0.0070, 0.3690, -0.0510,
   102     -0.0912, -0.1159, 1.0000, 0.9467, 0.4123, 0.4815, 0.4240, 0.2120, 0.1070, -0.1898, 0.0506, -0.0661, -0.0380, 0.0260, 0.0506, -0.0317, -0.0278, 0.0245,
   103     -0.0701, -0.1856, 0.9467, 1.0000, 0.4075, 0.4891, 0.4940, 0.2285, 0.2009, -0.1709, 0.0365, -0.0579, -0.0999, 0.0467, 0.0410, 0.0027, -0.0966, 0.0631,
   104     -0.0214, 0.0681, 0.4123, 0.4075, 1.0000, 0.1772, 0.1337, 0.7315, -0.0066, -0.2787, 0.0703, -0.0541, -0.0453, 0.1597, 0.0792, 0.0220, 0.0606, -0.0844,
   105     -0.0849, -0.2018, 0.4815, 0.4891, 0.1772, 1.0000, 0.9448, 0.3749, 0.1682, -0.0831, 0.0124, -0.1236, -0.0346, -0.0054, 0.0877, -0.0197, -0.0867, 0.0281,
   106     -0.0545, -0.2765, 0.4240, 0.4940, 0.1337, 0.9448, 1.0000, 0.3530, 0.2305, -0.0546, -0.0223, -0.0782, -0.0872, 0.0074, 0.0999, 0.0066, -0.1358, 0.0626,
   107     -0.0185, -0.0304, 0.2120, 0.2285, 0.7315, 0.3749, 0.3530, 1.0000, 0.1939, -0.0617, -0.0017, -0.0942, -0.0332, 0.0813, 0.0810, -0.0032, -0.0870, -0.0599,
   108     0.0270, -0.1719, 0.1070, 0.2009, -0.0066, 0.1682, 0.2305, 0.1939, 1.0000, -0.1851, -0.2073, -0.0756, -0.1637, -0.0865, 0.0699, -0.0485, -0.2153, 0.0320,
   109     -0.0122, -0.1157, -0.1898, -0.1709, -0.2787, -0.0831, -0.0546, -0.0617, -0.1851, 1.0000, 0.2139, 0.0769, 0.1391, 0.0769, -0.1838, 0.0377, -0.1615, 0.1000,
   110     0.0059, -0.0347, 0.0506, 0.0365, 0.0703, 0.0124, -0.0223, -0.0017, -0.2073, 0.2139, 1.0000, -0.1102, -0.0530, 0.0791, 0.0012, 0.0090, -0.0236, 0.0037,
   111     -0.0344, -0.0277, -0.0661, -0.0579, -0.0541, -0.1236, -0.0782, -0.0942, -0.0756, 0.0769, -0.1102, 1.0000, -0.2562, -0.0406, 0.3154, 0.0065, -0.0093, -0.0354,
   112     -0.0342, -0.0189, -0.0380, -0.0999, -0.0453, -0.0346, -0.0872, -0.0332, -0.1637, 0.1391, -0.0530, -0.2562, 1.0000, -0.1836, -0.1624, -0.5646, 0.0216, 0.0243,
   113     0.0409, 0.0357, 0.0260, 0.0467, 0.1597, -0.0054, 0.0074, 0.0813, -0.0865, 0.0769, 0.0791, -0.0406, -0.1836, 1.0000, 0.1624, 0.1989, 0.0549, -0.0411,
   114     -0.0137, 0.0657, 0.0506, 0.0410, 0.0792, 0.0877, 0.0999, 0.0810, 0.0699, -0.1838, 0.0012, 0.3154, -0.1624, 0.1624, 1.0000, 0.1552, 0.0844, -0.0637,
   115     -0.0168, -0.0070, -0.0317, 0.0027, 0.0220, -0.0197, 0.0066, -0.0032, -0.0485, 0.0377, 0.0090, 0.0065, -0.5646, 0.1989, 0.1552, 1.0000, 0.0058, 0.0503,
   116     -0.0990, 0.3690, -0.0278, -0.0966, 0.0606, -0.0867, -0.1358, -0.0870, -0.2153, -0.1615, -0.0236, -0.0093, 0.0216, 0.0549, 0.0844, 0.0058, 1.0000, -0.0930,
   117     -0.6701, -0.0510, 0.0245, 0.0631, -0.0844, 0.0281, 0.0626, -0.0599, 0.0320, 0.1000, 0.0037, -0.0354, 0.0243, -0.0411, -0.0637, 0.0503, -0.0930, 1.0000;
   121   means_ = beta * conditional_means;
   125                                            (variance.array().sqrt()).matrix());
   130           "MultivariateNormal");
   131   sample_generator_->generate(parameter_realizations_, means_, covariance_,
   133   parameter_realizations_.transposeInPlace();
   136   model_parameters_[0] =
   138           "LognormalDist", std::move(-1.735), std::move(0.523));
   139   model_parameters_[1] =
   141           "LognormalDist", std::move(1.009), std::move(0.422));
   142   model_parameters_[2] =
   144           "NormalDist", std::move(0.249), std::move(1.759));
   145   model_parameters_[3] =
   147           "NormalDist", std::move(0.768), std::move(1.958));  
   148   model_parameters_[4] =
   150           "LognormalDist", std::move(2.568), std::move(0.557));
   151   model_parameters_[5] =
   153           "NormalDist", std::move(0.034), std::move(1.471));
   154   model_parameters_[6] =
   156           "NormalDist", std::move(0.441), std::move(1.733));
   157   model_parameters_[7] =
   159           "LognormalDist", std::move(3.356), std::move(0.473));    
   160   model_parameters_[8] =
   162           "BetaDist", std::move(2.516), std::move(9.174));
   163   model_parameters_[9] =
   165           "BetaDist", std::move(3.582), std::move(15.209));
   166   model_parameters_[10] =
   168           "LognormalDist", std::move(0.746), std::move(0.404));
   169   model_parameters_[11] =
   171           ->
create(
"StudentstDist", std::move(0.205), std::move(0.232),
   173   model_parameters_[12] =
   175             "InverseGaussianDist", std::move(0.499), std::move(0.213));
   176   model_parameters_[13] =
   178             "LognormalDist", std::move(0.702), std::move(0.435));
   179   model_parameters_[14] =
   181           ->
create(
"StudentstDist", std::move(0.792), std::move(0.157),
   183   model_parameters_[15] =
   185             "InverseGaussianDist", std::move(0.350), std::move(0.170));
   186   model_parameters_[16] =
   188           "LognormalDist", std::move(9.470), std::move(1.317));
   189   model_parameters_[17] =
   191           "LognormalDist", std::move(3.658), std::move(0.375));
   194   auto std_normal_dist =
   196           "NormalDist", std::move(0.0), std::move(1.0));
   198   physical_parameters_.resize(parameter_realizations_.rows(),
   199                               parameter_realizations_.cols());
   202   for (
unsigned int i = 0; i < parameter_realizations_.rows(); ++i) {
   203     for (
unsigned int j = 0; j < model_parameters_.size(); ++j) {
   204       physical_parameters_(i, j) =
   205           (model_parameters_[j]->inv_cumulative_dist_func(
   206               std_normal_dist->cumulative_dist_func(
   207                   std::vector<double>{parameter_realizations_(i, j)})))[0];
   214                                      double rupture_distance, 
double vs30,
   216                                      unsigned int num_spectra,
   217                                      unsigned int num_sims,
   220       moment_magnitude_{moment_magnitude / 6.0},
   221       rupture_dist_{(rupture_distance + 5.0) / 30.0},
   223       orientation_{orientation},
   227       num_spectra_{num_spectra},
   229       seed_value_{seed_value},
   230       model_parameters_{18} {
   231   model_name_ = 
"VlachosEtAl";
   233   double site_soft = 0.0, site_medium = 0.0, site_hard = 0.0;
   236   } 
else if (vs30 <= 450.0) {
   243   Eigen::VectorXd conditional_means(7);
   246       1.0, moment_magnitude_, std::log(rupture_dist_),
   247       moment_magnitude_ * std::log(rupture_dist_), site_soft * std::log(vs30_),
   248       site_medium * std::log(vs30_), site_hard * std::log(vs30_);
   253   Eigen::MatrixXd beta(18, 7);
   256     -1.1417, 1.0917, 1.9125, -0.9696, 0.0971, 0.3476, -0.6740,
   257     1.8052,-1.8381, -3.5874, 3.7895, 0.3236, 0.5497, 0.2876,
   258     1.8969,-1.8819, -2.0818, 1.9000, -0.3520, -0.6959, -0.0025,
   259     1.6627,-1.6922, -1.2509, 1.1880, -0.5170, -1.0157, -0.1041,
   260     3.8703,-3.4745, -0.0816, 0.0166, 0.4904, 0.8697, 0.3179,
   261     1.1043,-1.1852, -1.0068, 0.9388, -0.5603, -0.8855, -0.3174,
   262     1.1935,-1.2922, -0.7028, 0.6975, -0.6629, -1.1075, -0.4542,
   263     1.7895,-1.5014, -0.0300, -0.1306, 0.4526, 0.7132, 0.1522,
   264     -3.6404, 3.3189, -0.5316, 0.3874, -0.3757, -0.8334, 0.1006,
   265     -2.2742, 2.1454, 0.6315, -0.6620, 0.1093, -0.1028, -0.0479,
   266     0.6930, -0.6202, 1.8037, -1.6064, 0.0727, -0.1498, -0.0722,
   267     1.3003, -1.2004, -1.2210, 1.0623, -0.0252, 0.1885, 0.0069,
   268     0.4604, -0.4087, -0.5057, 0.4486, 0.1073, -0.0219, -0.1352,
   269     2.2304, -2.0398, -0.1364, 0.1910, 0.2425, 0.1801, 0.3233,
   270     2.3806, -2.2011, -0.3256, 0.2226, -0.0221, 0.0970, 0.0762,
   271     0.2057, -0.1714, 0.3385, -0.2229, 0.0802, 0.2649, 0.0396,
   272     -7.6011, 6.8507, -2.3609, 0.9201, -0.7508, -0.7903, -0.6204,
   273     -6.3472, 5.8241, 3.2994, -2.8774, -0.1411, -0.5298, -0.0203;
   277   Eigen::VectorXd variance(18);
   280       0.90, 0.80, 0.78, 0.74, 0.66, 0.73, 0.72, 0.70, 0.69,
   281       0.78, 0.90, 0.90, 0.90, 0.90, 0.80, 0.90, 0.35, 0.80;
   285   Eigen::MatrixXd correlation_matrix(18, 18);
   287   correlation_matrix <<
   288     1.0000, 0.0382, -0.0912, -0.0701, -0.0214, -0.0849, -0.0545, -0.0185, 0.0270, -0.0122, 0.0059, -0.0344, -0.0342, 0.0409, -0.0137, -0.0168, -0.0990, -0.6701,
   289     0.0382, 1.0000, -0.1159, -0.1856, 0.0681, -0.2018, -0.2765, -0.0304, -0.1719, -0.1157, -0.0347, -0.0277, -0.0189, 0.0357, 0.0657, -0.0070, 0.3690, -0.0510,
   290     -0.0912, -0.1159, 1.0000, 0.9467, 0.4123, 0.4815, 0.4240, 0.2120, 0.1070, -0.1898, 0.0506, -0.0661, -0.0380, 0.0260, 0.0506, -0.0317, -0.0278, 0.0245,
   291     -0.0701, -0.1856, 0.9467, 1.0000, 0.4075, 0.4891, 0.4940, 0.2285, 0.2009, -0.1709, 0.0365, -0.0579, -0.0999, 0.0467, 0.0410, 0.0027, -0.0966, 0.0631,
   292     -0.0214, 0.0681, 0.4123, 0.4075, 1.0000, 0.1772, 0.1337, 0.7315, -0.0066, -0.2787, 0.0703, -0.0541, -0.0453, 0.1597, 0.0792, 0.0220, 0.0606, -0.0844,
   293     -0.0849, -0.2018, 0.4815, 0.4891, 0.1772, 1.0000, 0.9448, 0.3749, 0.1682, -0.0831, 0.0124, -0.1236, -0.0346, -0.0054, 0.0877, -0.0197, -0.0867, 0.0281,
   294     -0.0545, -0.2765, 0.4240, 0.4940, 0.1337, 0.9448, 1.0000, 0.3530, 0.2305, -0.0546, -0.0223, -0.0782, -0.0872, 0.0074, 0.0999, 0.0066, -0.1358, 0.0626,
   295     -0.0185, -0.0304, 0.2120, 0.2285, 0.7315, 0.3749, 0.3530, 1.0000, 0.1939, -0.0617, -0.0017, -0.0942, -0.0332, 0.0813, 0.0810, -0.0032, -0.0870, -0.0599,
   296     0.0270, -0.1719, 0.1070, 0.2009, -0.0066, 0.1682, 0.2305, 0.1939, 1.0000, -0.1851, -0.2073, -0.0756, -0.1637, -0.0865, 0.0699, -0.0485, -0.2153, 0.0320,
   297     -0.0122, -0.1157, -0.1898, -0.1709, -0.2787, -0.0831, -0.0546, -0.0617, -0.1851, 1.0000, 0.2139, 0.0769, 0.1391, 0.0769, -0.1838, 0.0377, -0.1615, 0.1000,
   298     0.0059, -0.0347, 0.0506, 0.0365, 0.0703, 0.0124, -0.0223, -0.0017, -0.2073, 0.2139, 1.0000, -0.1102, -0.0530, 0.0791, 0.0012, 0.0090, -0.0236, 0.0037,
   299     -0.0344, -0.0277, -0.0661, -0.0579, -0.0541, -0.1236, -0.0782, -0.0942, -0.0756, 0.0769, -0.1102, 1.0000, -0.2562, -0.0406, 0.3154, 0.0065, -0.0093, -0.0354,
   300     -0.0342, -0.0189, -0.0380, -0.0999, -0.0453, -0.0346, -0.0872, -0.0332, -0.1637, 0.1391, -0.0530, -0.2562, 1.0000, -0.1836, -0.1624, -0.5646, 0.0216, 0.0243,
   301     0.0409, 0.0357, 0.0260, 0.0467, 0.1597, -0.0054, 0.0074, 0.0813, -0.0865, 0.0769, 0.0791, -0.0406, -0.1836, 1.0000, 0.1624, 0.1989, 0.0549, -0.0411,
   302     -0.0137, 0.0657, 0.0506, 0.0410, 0.0792, 0.0877, 0.0999, 0.0810, 0.0699, -0.1838, 0.0012, 0.3154, -0.1624, 0.1624, 1.0000, 0.1552, 0.0844, -0.0637,
   303     -0.0168, -0.0070, -0.0317, 0.0027, 0.0220, -0.0197, 0.0066, -0.0032, -0.0485, 0.0377, 0.0090, 0.0065, -0.5646, 0.1989, 0.1552, 1.0000, 0.0058, 0.0503,
   304     -0.0990, 0.3690, -0.0278, -0.0966, 0.0606, -0.0867, -0.1358, -0.0870, -0.2153, -0.1615, -0.0236, -0.0093, 0.0216, 0.0549, 0.0844, 0.0058, 1.0000, -0.0930,
   305     -0.6701, -0.0510, 0.0245, 0.0631, -0.0844, 0.0281, 0.0626, -0.0599, 0.0320, 0.1000, 0.0037, -0.0354, 0.0243, -0.0411, -0.0637, 0.0503, -0.0930, 1.0000;
   309   means_ = beta * conditional_means;
   313                                            (variance.array().sqrt()).matrix());
   318           "MultivariateNormal", std::move(seed_value_));
   319   sample_generator_->generate(parameter_realizations_, means_, covariance_,
   321   parameter_realizations_.transposeInPlace();
   324   model_parameters_[0] =
   326           "LognormalDist", std::move(-1.735), std::move(0.523));
   327   model_parameters_[1] =
   329           "LognormalDist", std::move(1.009), std::move(0.422));
   330   model_parameters_[2] =
   332           "NormalDist", std::move(0.249), std::move(1.759));
   333   model_parameters_[3] =
   335           "NormalDist", std::move(0.768), std::move(1.958));  
   336   model_parameters_[4] =
   338           "LognormalDist", std::move(2.568), std::move(0.557));
   339   model_parameters_[5] =
   341           "NormalDist", std::move(0.034), std::move(1.471));
   342   model_parameters_[6] =
   344           "NormalDist", std::move(0.441), std::move(1.733));
   345   model_parameters_[7] =
   347           "LognormalDist", std::move(3.356), std::move(0.473));    
   348   model_parameters_[8] =
   350           "BetaDist", std::move(2.516), std::move(9.714));
   351   model_parameters_[9] =
   353           "BetaDist", std::move(3.582), std::move(15.209));
   354   model_parameters_[10] =
   356           "LognormalDist", std::move(0.746), std::move(0.404));
   357   model_parameters_[11] =
   359           ->
create(
"StudentstDist", std::move(0.205), std::move(0.232),
   361   model_parameters_[12] =
   363             "InverseGaussianDist", std::move(0.499), std::move(0.213));
   364   model_parameters_[13] =
   366             "LognormalDist", std::move(0.702), std::move(0.435));
   367   model_parameters_[14] =
   369           ->
create(
"StudentstDist", std::move(0.792), std::move(0.157),
   371   model_parameters_[15] =
   373             "InverseGaussianDist", std::move(0.350), std::move(0.170));
   374   model_parameters_[16] =
   376           "LognormalDist", std::move(9.470), std::move(1.317));
   377   model_parameters_[17] =
   379           "LognormalDist", std::move(3.658), std::move(0.375));
   382   auto std_normal_dist =
   384           "NormalDist", std::move(0.0), std::move(1.0));
   386   physical_parameters_.resize(parameter_realizations_.rows(),
   387                               parameter_realizations_.cols());
   390   for (
unsigned int i = 0; i < parameter_realizations_.rows(); ++i) {
   391     for (
unsigned int j = 0; j < model_parameters_.size(); ++j) {
   392       physical_parameters_(i, j) =
   393           (model_parameters_[j]->inv_cumulative_dist_func(
   394               std_normal_dist->cumulative_dist_func(
   395                   std::vector<double>{parameter_realizations_(i, j)})))[0];
   401     const std::string& event_name, 
bool g_units) {
   405   std::vector<std::vector<std::vector<double>>> acceleration_pool(
   407       std::vector<std::vector<double>>(num_sims_, std::vector<double>()));
   412     for (
unsigned int i = 0; i < num_spectra_; ++i) {
   413       time_history_family(acceleration_pool[i], physical_parameters_.row(i));
   415   } 
catch (
const std::exception& e) {
   416     std::cerr << e.what();
   422   std::vector<utilities::JsonObject> events_array(num_spectra_ * num_sims_);
   427   pattern_x.add_value(
"type", 
"UniformAcceleration");
   428   pattern_x.add_value(
"timeSeries", 
"accel_x");
   429   pattern_x.add_value(
"dof", 1);
   430   pattern_y.add_value(
"type", 
"UniformAcceleration");
   431   pattern_y.add_value(
"timeSeries", 
"accel_y");
   432   pattern_y.add_value(
"dof", 2);
   437   for (
unsigned int i = 0; i < num_spectra_; ++i) {
   439     for (
unsigned int j = 0; j < num_sims_; ++j) {
   440       event_data.add_value(
"name", event_name + 
"_Spectra" + std::to_string(i) +
   441                                        "_Sim" + std::to_string(j));
   442       event_data.add_value(
"type", 
"Seismic");
   443       event_data.add_value(
"dT", time_step_);
   444       event_data.add_value(
"numSteps", acceleration_pool[i][j].size());
   445       event_data.add_value(
   446           "pattern", std::vector<utilities::JsonObject>{pattern_x, pattern_y});
   449       std::vector<double> x_accels(acceleration_pool[i][j].size());
   450       std::vector<double> y_accels(acceleration_pool[i][j].size());
   451       rotate_acceleration(acceleration_pool[i][j], x_accels, y_accels, g_units);
   456       time_history_x.add_value(
"name", 
"accel_x");
   457       time_history_x.add_value(
"type", 
"Value");
   458       time_history_x.add_value(
"dT", time_step_);
   459       time_history_x.add_value(
"data", x_accels);
   460       time_history_y.add_value(
"name", 
"accel_y");
   461       time_history_y.add_value(
"type", 
"Value");
   462       time_history_y.add_value(
"dT", time_step_);
   463       time_history_y.add_value(
"data", y_accels);
   464       event_data.add_value(
"timeSeries", std::vector<utilities::JsonObject>{
   465                                              time_history_x, time_history_y});
   466       events_array[i * num_sims_ + j] = event_data; 
   471   events.add_value(
"Events", events_array);
   477                                        const std::string& output_location,
   483     auto json_output = generate(event_name, g_units);
   484     json_output.write_to_file(output_location);
   485   } 
catch (
const std::exception& e) {
   486     std::cerr << e.what();
   495     std::vector<std::vector<double>>& time_histories,
   496     const Eigen::VectorXd& parameters)
 const {
   498   auto identified_parameters = identify_parameters(parameters);
   500   unsigned int num_times =
   501       static_cast<unsigned int>(std::ceil(identified_parameters[17] / time_step_)) + 1;
   502   unsigned int num_freqs =
   503       static_cast<unsigned int>(std::ceil(cutoff_freq_ / freq_step_)) + 1;
   505   std::vector<double> times(num_times);
   506   std::vector<double> frequencies(num_freqs);
   507   double total_time = (num_times - 1) * time_step_;
   509   for (
unsigned int i = 0; i < times.size(); ++i) {
   510     times[i] = i * time_step_ / total_time;
   514   for (
unsigned int i = 0; i < frequencies.size(); ++i) {
   515     frequencies[i] = i * freq_step_;
   519   auto energy = energy_accumulation(
   520       std::vector<double>{identified_parameters[0], identified_parameters[1]},
   524   auto mode_1_freqs = modal_frequencies(
   525       std::vector<double>{identified_parameters[2], identified_parameters[3],
   526                           identified_parameters[4]},
   528   auto mode_2_freqs = modal_frequencies(
   529       std::vector<double>{identified_parameters[5], identified_parameters[6],
   530                           identified_parameters[7]},
   534   auto mode_2_participation = modal_participation_factor(
   535       std::vector<double>{identified_parameters[10], identified_parameters[11],
   536                           identified_parameters[12], identified_parameters[13],
   537                           identified_parameters[14], identified_parameters[15]},
   541   auto amplitude_modulation = amplitude_modulating_function(
   542       identified_parameters[17], identified_parameters[16],
   543       std::vector<double>{identified_parameters[0], identified_parameters[1]},
   547   int filter_order = 4;
   548   double norm_cutoff_freq = 0.20;
   551   std::vector<double> highpass_butter_energy(frequencies.size());
   552   double freq_ratio_sq;
   553   for (
unsigned int i = 0; i < frequencies.size(); ++i) {
   554     freq_ratio_sq = std::pow(frequencies[i] / (2.0 * M_PI * norm_cutoff_freq),
   556     highpass_butter_energy[i] = freq_ratio_sq / (1.0 + freq_ratio_sq);
   561   Eigen::MatrixXd power_spectrum(times.size(), frequencies.size());
   563   for (
unsigned int i = 0; i < times.size(); ++i) {
   564     power_spectrum.row(i) =
   565         kt_2(std::vector<double>{mode_1_freqs[i], identified_parameters[8], 1.0,
   566                                  mode_2_freqs[i], identified_parameters[9],
   567                                  mode_2_participation[i]},
   568              frequencies, highpass_butter_energy);
   570     double freq_domain_integral =
   573     power_spectrum.row(i) =
   574         power_spectrum.row(i) * amplitude_modulation[i] / freq_domain_integral;
   580       static_cast<int>(std::round(1.5 * static_cast<double>(filter_order) /
   581                                   (2.0 * norm_cutoff_freq)) /
   587           ->
dispatch(
"HighPassButter", filter_order,
   588                      norm_cutoff_freq / (1.0 / time_step_ / 2.0));
   591   auto impulse_response =
   593                  int, 
int>::instance()
   594           ->
dispatch(
"ImpulseResponse", hp_butter[0], hp_butter[1],
   595                      filter_order, num_samples);
   599     for (
unsigned int i = 0; i < num_sims_; ++i) {
   600       simulate_time_history(time_histories[i], power_spectrum);
   601       post_process(time_histories[i], impulse_response);
   603   } 
catch (
const std::exception& e) {
   604     std::cerr << e.what();
   613     std::vector<double>& time_history,
   614     const Eigen::MatrixXd& power_spectrum)
 const {
   615   unsigned int num_times = power_spectrum.rows(),
   616                num_freqs = power_spectrum.cols();
   618   time_history.resize(num_times, 0.0);
   620   std::vector<double> times(num_times);
   621   std::vector<double> frequencies(num_freqs);
   623   for (
unsigned int i = 0; i < times.size(); ++i) {
   624     times[i] = i * time_step_;
   627   for (
unsigned int i = 0; i < frequencies.size(); ++i) {
   628     frequencies[i] = i * freq_step_;
   631   static unsigned int history_seed = 
static_cast<unsigned int>(std::time(
nullptr));
   632   history_seed = history_seed + 10;
   635     seed_value_ != std::numeric_limits<int>::infinity()
   636     ? boost::random::mt19937(static_cast<unsigned int>(seed_value_ + 10))
   637     : boost::random::mt19937(history_seed);
   639   boost::random::uniform_real_distribution<> distribution(0.0, 2.0 * M_PI);
   640   boost::random::variate_generator<boost::random::mt19937&,
   641                                    boost::random::uniform_real_distribution<>>
   642       angle_gen(generator, distribution);
   644   std::vector<double> phase_angle(num_freqs, 0.0);
   646   for (
auto & angle : phase_angle) {
   651   for (
unsigned int i = 0; i < num_times; ++i) {
   652     for (
unsigned int j = 0; j < num_freqs; ++j) {
   655           std::sqrt(power_spectrum(i, j)) *
   656               std::cos(frequencies[j] * times[i] + phase_angle[j]);      
   658     time_history[i] = 2.0 * std::sqrt(freq_step_) * time_history[i];
   663     std::vector<double>& time_history,
   664     const std::vector<double>& filter_imp_resp)
 const {
   667   double time_hann_2 = 1.0;
   669   Eigen::VectorXd window = Eigen::VectorXd::Ones(time_history.size());
   670   unsigned int window1_size =
   671       static_cast<unsigned int>(time_hann_2 / time_step_ + 1);
   672   unsigned int window2_size = 
static_cast<unsigned int>((window1_size - 1) / 2);
   675   if (time_history.size() < window1_size) {
   676     throw std::runtime_error(
   677         "\nERROR: in stochastic::VlachosEtAl::post_process: Input time history "   678         "too short for Hanning Window size\n");
   684           "HannWindow", window1_size);
   686   window.head(window2_size) = hann_window.head(window2_size);
   687   window.tail(window2_size) = hann_window.head(window2_size).reverse();
   690   double mean = std::accumulate(time_history.begin(), time_history.end(), 0.0) /
   691                 static_cast<double>(time_history.size());
   694   for (
unsigned int i = 0; i < time_history.size(); ++i) {
   695     time_history[i] = window[i] * (time_history[i] - mean);
   699   std::vector<double> filtered_history(filter_imp_resp.size() +
   700                                        time_history.size() - 1);
   703   } 
catch (
const std::exception& e) {
   704     std::cerr << e.what();
   710   time_history = filtered_history;
   716     const Eigen::VectorXd& initial_params)
 const {
   718   std::vector<double> energy(static_cast<unsigned int>(1.0 / 0.05) + 1, 0.0);
   720   for (
unsigned int i = 1; i < energy.size(); ++i) {
   721     energy[i] = energy[i - 1] + 0.05;
   725   std::vector<double> mode_1_params = {initial_params(2),
   728   auto mode_1_freqs = modal_frequencies(mode_1_params, energy);
   731   std::vector<double> mode_2_params = {initial_params(5),
   734   auto mode_2_freqs = modal_frequencies(mode_2_params, energy);
   736   double mode_1_mean = initial_params(11), mode_2_mean = initial_params(14);
   739   auto std_normal_dist =
   741           "NormalDist", std::move(0.0), std::move(1.0));  
   743   Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> realizations(
   744       initial_params.size(), 1);
   745   Eigen::VectorXd transformed_realizations = initial_params;
   749   bool freq_comparison = 
false;
   750   for (
unsigned int i = 0; i < mode_1_freqs.size(); ++i) {
   751     if (mode_1_freqs[i] > mode_2_freqs[i]) {
   752       freq_comparison = 
true;
   758   while (freq_comparison || (mode_1_mean > mode_2_mean)) {
   761     sample_generator_->generate(realizations, means_, covariance_, 1);
   764     for (
unsigned int i = 0; i < initial_params.size(); ++i) {
   765       transformed_realizations(i) =
   766           (model_parameters_[i]->inv_cumulative_dist_func(
   767               std_normal_dist->cumulative_dist_func(
   768                   std::vector<double>{realizations(i, 0)})))[0];
   773         modal_frequencies(std::vector<double>{transformed_realizations(2),
   774                                               transformed_realizations(3),
   775                                               transformed_realizations(4)},
   778     mode_2_params = {transformed_realizations(5), transformed_realizations(6),
   779                      transformed_realizations(7)};
   781         modal_frequencies(std::vector<double>{transformed_realizations(5),
   782                                               transformed_realizations(6),
   783                                               transformed_realizations(7)},
   786     mode_1_mean = transformed_realizations(11);
   787     mode_2_mean = transformed_realizations(14);
   791     freq_comparison = 
false;
   792     for (
unsigned int i = 0; i < mode_1_freqs.size(); ++i) {
   793       if (mode_1_freqs[i] > mode_2_freqs[i]) {
   794     freq_comparison = 
true;
   800   return transformed_realizations;
   804     const std::vector<double>& parameters,
   805     const std::vector<double>& energy)
 const {
   806   std::vector<double> frequencies(energy.size());
   808   for (
unsigned int i = 0; i < energy.size(); ++i) {
   809     frequencies[i] = parameters[2] * std::pow(0.5 + energy[i], parameters[0]) *
   810                      std::pow(1.5 - energy[i], parameters[1]);
   817     const std::vector<double>& parameters,
   818     const std::vector<double>& times)
 const {
   819   std::vector<double> accumulated_energy(times.size());
   821   for (
unsigned int i = 0; i < times.size(); ++i) {
   822     accumulated_energy[i] =
   823         std::exp(-std::pow(times[i] / parameters[0], -parameters[1])) /
   824         std::exp(-std::pow(1.0 / parameters[0], -parameters[1]));
   827   return accumulated_energy;
   831     const std::vector<double>& parameters,
   832     const std::vector<double>& energy)
 const {
   833   std::vector<double> participation_factor(energy.size());
   835   for (
unsigned int i = 0; i < energy.size(); ++i) {
   836     participation_factor[i] = std::pow(
   838         parameters[0] * std::exp(-std::pow(
   839                             (energy[i] - parameters[1]) / parameters[2], 2)) +
   842                     -std::pow((energy[i] - parameters[4]) / parameters[5], 2)) -
   846   return participation_factor;
   850     double duration, 
double total_energy, 
const std::vector<double>& parameters,
   851     const std::vector<double>& times)
 const {
   852   std::vector<double> func_vals(times.size());
   854   double mult_term = total_energy * parameters[1] / (parameters[0] * duration);
   855   double exponent_1 = std::pow(1.0 / parameters[0], -parameters[1]);
   857   for (
unsigned int i = 0; i < times.size(); ++i) {
   858     func_vals[i] = mult_term *
   859                    std::exp(exponent_1 - std::pow(times[i] / parameters[0], -parameters[1])) *
   860                    std::pow(times[i] / parameters[0], -1.0 - parameters[1]);
   867     const std::vector<double>& parameters,
   868     const std::vector<double>& frequencies,
   869     const std::vector<double>& highpass_butter)
 const {
   870   Eigen::VectorXd power_spectrum(frequencies.size());
   871   double mode1 = 0, mode2 = 0;
   873   for (
unsigned int i = 0; i < frequencies.size(); ++i) {
   874     mode1 = parameters[2] *
   875             (1.0 + 4.0 * parameters[1] * parameters[1] *
   876                        std::pow(frequencies[i] / parameters[0], 2)) /
   877             (std::pow(1 - std::pow(frequencies[i] / parameters[0], 2), 2) +
   878              4.0 * parameters[1] * parameters[1] *
   879                  std::pow(frequencies[i] / parameters[0], 2));
   880     mode2 = parameters[5] *
   881             (1.0 + 4.0 * parameters[4] * parameters[4] *
   882                        std::pow(frequencies[i] / parameters[3], 2)) /
   883             (std::pow(1 - std::pow(frequencies[i] / parameters[3], 2), 2) +
   884              4.0 * parameters[4] * parameters[4] *
   885                  std::pow(frequencies[i] / parameters[3], 2));
   887     power_spectrum[i] = highpass_butter[i] * (mode1 + mode2);
   890   return power_spectrum;
   894     const std::vector<double>& acceleration, std::vector<double>& x_accels,
   895     std::vector<double>& y_accels, 
bool g_units)
 const {
   897   x_accels.resize(acceleration.size());
   898   y_accels.resize(acceleration.size());
   900   double conversion_factor = g_units ? 100.0 * 9.81 : 100.0;
   903   if (std::abs(orientation_) < 1E-6) {
   904     for (
unsigned int i = 0; i < acceleration.size(); ++i) {
   906       x_accels[i] = acceleration[i] / conversion_factor;      
   908     y_accels.assign(acceleration.size(), 0.0);
   911     for (
unsigned int i = 0; i < acceleration.size(); ++i) {
   914           acceleration[i] * std::cos(orientation_ * M_PI / 180.0) / conversion_factor;
   916           acceleration[i] * std::sin(orientation_ * M_PI / 180.0) / conversion_factor;
 bool convolve_1d(const std::vector< double > &input_x, const std::vector< double > &input_y, std::vector< double > &response)
 
bool post_process(std::vector< double > &time_history, const std::vector< double > &filter_imp_resp) const 
 
std::vector< double > energy_accumulation(const std::vector< double > ¶meters, const std::vector< double > ×) const 
 
Eigen::VectorXd kt_2(const std::vector< double > ¶meters, const std::vector< double > &frequencies, const std::vector< double > &highpass_butter) const 
 
std::shared_ptr< Tbaseclass > create(const std::string &key, Targs &&...args)
 
Treturntype dispatch(const std::string &key, Targs...args)
 
static Factory * instance()
 
static Dispatcher * instance()
 
std::vector< double > modal_frequencies(const std::vector< double > ¶meters, const std::vector< double > &energy) const 
 
std::vector< double > amplitude_modulating_function(double duration, double total_energy, const std::vector< double > ¶meters, const std::vector< double > ×) const 
 
bool time_history_family(std::vector< std::vector< double >> &time_histories, const Eigen::VectorXd ¶meters) const 
 
void rotate_acceleration(const std::vector< double > &acceleration, std::vector< double > &x_accels, std::vector< double > &y_accels, bool g_units) const 
 
Eigen::VectorXd identify_parameters(const Eigen::VectorXd &initial_params) const 
 
utilities::JsonObject generate(const std::string &event_name, bool g_units=false) override
 
double trapazoid_rule(const std::vector< double > &input_vector, double spacing)
 
Eigen::MatrixXd corr_to_cov(const Eigen::MatrixXd &corr, const Eigen::VectorXd &std_dev)
 
void simulate_time_history(std::vector< double > &time_history, const Eigen::MatrixXd &power_spectrum) const 
 
std::vector< double > modal_participation_factor(const std::vector< double > ¶meters, const std::vector< double > &energy) const