diff --git a/.github/workflows/wasmstan.yml b/.github/workflows/wasmstan.yml new file mode 100644 index 00000000..d976d683 --- /dev/null +++ b/.github/workflows/wasmstan.yml @@ -0,0 +1,29 @@ +name: prophet-wasmstan + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown,wasm32-wasip1 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-binstall,just,wasmtime + - name: Install deps + run: just components/install-deps + - uses: actions/setup-node@v4 + - name: Run node test + run: just components/test diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..c9a3f17a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "components/cpp/prophet-wasmstan/stan"] + path = components/cpp/prophet-wasmstan/stan + url = https://github.com/stan-dev/stan diff --git a/components/.gitignore b/components/.gitignore new file mode 100644 index 00000000..2f8494ef --- /dev/null +++ b/components/.gitignore @@ -0,0 +1 @@ +/tools diff --git a/components/cpp/prophet-wasmstan/.gitignore b/components/cpp/prophet-wasmstan/.gitignore new file mode 100644 index 00000000..9aa99d9d --- /dev/null +++ b/components/cpp/prophet-wasmstan/.gitignore @@ -0,0 +1,3 @@ +*-core.wasm +*-component.wasm +*_component_type.o diff --git a/components/cpp/prophet-wasmstan/README.md b/components/cpp/prophet-wasmstan/README.md new file mode 100644 index 00000000..016f952b --- /dev/null +++ b/components/cpp/prophet-wasmstan/README.md @@ -0,0 +1,49 @@ +# prophet-wasmstan - a WASM Component for the Prophet Stan model + +`prophet-wasmstan` is a WASM component exposing the core model fitting +and sampling functionality of the [Prophet](https://github.com/facebook/prophet) +time series forecasting model. Specifically, this component uses the +generated Stan code (a C++ file) and the Stan library to expose +the `optimize` and `sample` functions of Stan using the Prophet model, +allowing it to be called from a WASM module. + +## Building + +To build the component you'll need to have several tools from the +WASM Component toolchain installed. The easiest way to do this is +using the `justfile` from the `components` directory of the repository, +which has an `install-dependencies` target that will install all +the necessary tools. + +```bash +just install-dependencies +``` + +Once the dependencies are installed, you can build the component +with the `build-lib-component` target: + +```bash +just build +``` + +This will generate a `prophet-wasmstan-component.wasm` file in the `prophet-wasmstan` +directory. This file can be used as a WASM component. + +## Using the component + +The interface exposed by the component is defined in the `prophet-wasmstan.wit` +file. + +See the [Component Model docs](https://component-model.bytecodealliance.org/language-support.html) +for instructions on how to use the component in a WASM component in other +languages. + +### Javascript + +Run the following command to generate Javascript bindings for the component: + +```bash +just transpile +``` + +You should now have Javascript bindings in the `js/prophet-wasmstan` directory. diff --git a/components/cpp/prophet-wasmstan/model/model.hpp b/components/cpp/prophet-wasmstan/model/model.hpp new file mode 100644 index 00000000..2d6ede8b --- /dev/null +++ b/components/cpp/prophet-wasmstan/model/model.hpp @@ -0,0 +1,1343 @@ +// Code generated by stanc v2.34.0 +#include +namespace model_model_namespace { +using stan::model::model_base_crtp; +using namespace stan::math; +stan::math::profile_map profiles__; +static constexpr std::array locations_array__ = + {" (found before start of program)", + " (in 'model.stan', line 110, column 2 to column 9)", + " (in 'model.stan', line 111, column 2 to column 9)", + " (in 'model.stan', line 112, column 2 to column 18)", + " (in 'model.stan', line 113, column 2 to column 26)", + " (in 'model.stan', line 114, column 2 to column 17)", + " (in 'model.stan', line 118, column 2 to column 18)", + " (in 'model.stan', line 124, column 4 to column 29)", + " (in 'model.stan', line 123, column 35 to line 125, column 3)", + " (in 'model.stan', line 123, column 9 to line 125, column 3)", + " (in 'model.stan', line 122, column 4 to column 64)", + " (in 'model.stan', line 121, column 35 to line 123, column 3)", + " (in 'model.stan', line 121, column 9 to line 125, column 3)", + " (in 'model.stan', line 120, column 4 to column 54)", + " (in 'model.stan', line 119, column 28 to line 121, column 3)", + " (in 'model.stan', line 119, column 2 to line 125, column 3)", + " (in 'model.stan', line 130, column 2 to column 19)", + " (in 'model.stan', line 131, column 2 to column 19)", + " (in 'model.stan', line 132, column 2 to column 37)", + " (in 'model.stan', line 133, column 2 to column 29)", + " (in 'model.stan', line 134, column 2 to column 27)", + " (in 'model.stan', line 137, column 2 to line 142, column 4)", + " (in 'model.stan', line 88, column 2 to column 8)", + " (in 'model.stan', line 89, column 2 to column 17)", + " (in 'model.stan', line 90, column 9 to column 10)", + " (in 'model.stan', line 90, column 2 to column 14)", + " (in 'model.stan', line 91, column 9 to column 10)", + " (in 'model.stan', line 91, column 2 to column 16)", + " (in 'model.stan', line 92, column 9 to column 10)", + " (in 'model.stan', line 92, column 2 to column 14)", + " (in 'model.stan', line 93, column 2 to column 8)", + " (in 'model.stan', line 94, column 9 to column 10)", + " (in 'model.stan', line 94, column 2 to column 21)", + " (in 'model.stan', line 95, column 9 to column 10)", + " (in 'model.stan', line 95, column 11 to column 12)", + " (in 'model.stan', line 95, column 2 to column 16)", + " (in 'model.stan', line 96, column 9 to column 10)", + " (in 'model.stan', line 96, column 2 to column 19)", + " (in 'model.stan', line 97, column 2 to column 20)", + " (in 'model.stan', line 98, column 2 to column 22)", + " (in 'model.stan', line 99, column 9 to column 10)", + " (in 'model.stan', line 99, column 2 to column 16)", + " (in 'model.stan', line 100, column 9 to column 10)", + " (in 'model.stan', line 100, column 2 to column 16)", + " (in 'model.stan', line 104, column 9 to column 10)", + " (in 'model.stan', line 104, column 12 to column 13)", + " (in 'model.stan', line 104, column 2 to column 61)", + " (in 'model.stan', line 105, column 9 to column 10)", + " (in 'model.stan', line 105, column 12 to column 13)", + " (in 'model.stan', line 105, column 2 to column 47)", + " (in 'model.stan', line 106, column 9 to column 10)", + " (in 'model.stan', line 106, column 12 to column 13)", + " (in 'model.stan', line 106, column 2 to column 47)", + " (in 'model.stan', line 112, column 9 to column 10)", + " (in 'model.stan', line 114, column 9 to column 10)", + " (in 'model.stan', line 118, column 9 to column 10)", + " (in 'model.stan', line 9, column 11 to column 12)", + " (in 'model.stan', line 9, column 14 to column 15)", + " (in 'model.stan', line 9, column 4 to column 19)", + " (in 'model.stan', line 10, column 15 to column 16)", + " (in 'model.stan', line 10, column 4 to column 24)", + " (in 'model.stan', line 11, column 4 to column 15)", + " (in 'model.stan', line 14, column 4 to column 28)", + " (in 'model.stan', line 15, column 4 to column 33)", + " (in 'model.stan', line 16, column 4 to column 15)", + " (in 'model.stan', line 21, column 8 to column 26)", + " (in 'model.stan', line 22, column 8 to column 28)", + " (in 'model.stan', line 20, column 58 to line 23, column 7)", + " (in 'model.stan', line 20, column 6 to line 23, column 7)", + " (in 'model.stan', line 24, column 6 to column 19)", + " (in 'model.stan', line 19, column 19 to line 25, column 5)", + " (in 'model.stan', line 19, column 4 to line 25, column 5)", + " (in 'model.stan', line 26, column 4 to column 13)", + " (in 'model.stan', line 7, column 73 to line 27, column 3)", + " (in 'model.stan', line 32, column 11 to column 12)", + " (in 'model.stan', line 32, column 4 to column 20)", + " (in 'model.stan', line 33, column 11 to column 16)", + " (in 'model.stan', line 33, column 4 to column 22)", + " (in 'model.stan', line 34, column 4 to column 14)", + " (in 'model.stan', line 37, column 4 to column 51)", + " (in 'model.stan', line 40, column 4 to column 13)", + " (in 'model.stan', line 42, column 6 to column 66)", + " (in 'model.stan', line 43, column 6 to column 29)", + " (in 'model.stan', line 41, column 19 to line 44, column 5)", + " (in 'model.stan', line 41, column 4 to line 44, column 5)", + " (in 'model.stan', line 45, column 4 to column 17)", + " (in 'model.stan', line 31, column 78 to line 46, column 3)", + " (in 'model.stan', line 58, column 11 to column 12)", + " (in 'model.stan', line 58, column 4 to column 20)", + " (in 'model.stan', line 60, column 4 to column 53)", + " (in 'model.stan', line 61, column 4 to column 70)", + " (in 'model.stan', line 57, column 4 to line 62, column 3)", + " (in 'model.stan', line 74, column 4 to column 65)", + " (in 'model.stan', line 73, column 4 to line 75, column 3)", + " (in 'model.stan', line 83, column 4 to column 28)", + " (in 'model.stan', line 82, column 4 to line 84, column 3)"}; +template , + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral, std::is_integral>* = nullptr> +Eigen::Matrix, + stan::base_type_t>,-1,-1> +get_changepoint_matrix(const T0__& t_arg__, const T1__& t_change_arg__, + const T2__& T, const T3__& S, std::ostream* pstream__); +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral>* = nullptr> +Eigen::Matrix, + stan::base_type_t>,-1,1> +logistic_gamma(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_change_arg__, const T4__& S, std::ostream* + pstream__); +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_eigen_matrix_dynamic, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral>* = nullptr> +Eigen::Matrix, + stan::base_type_t, stan::base_type_t, + stan::promote_args_t, + stan::base_type_t>>,-1,1> +logistic_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& cap_arg__, const T5__& + A_arg__, const T6__& t_change_arg__, const T7__& S, + std::ostream* pstream__); +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_eigen_matrix_dynamic, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex>* = nullptr> +Eigen::Matrix, + stan::base_type_t, stan::base_type_t, + stan::promote_args_t>>,-1,1> +linear_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& A_arg__, const T5__& + t_change_arg__, std::ostream* pstream__); +template , + std::is_floating_point>, + std::is_integral>* = nullptr> +Eigen::Matrix,-1,1> +flat_trend(const T0__& m, const T1__& T, std::ostream* pstream__); +// matrix get_changepoint_matrix(vector, vector, int, int) +template , + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral, std::is_integral>*> +Eigen::Matrix, + stan::base_type_t>,-1,-1> +get_changepoint_matrix(const T0__& t_arg__, const T1__& t_change_arg__, + const T2__& T, const T3__& S, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t, + stan::base_type_t>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& t = stan::math::to_ref(t_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 56; + stan::math::validate_non_negative_index("A", "T", T); + current_statement__ = 57; + stan::math::validate_non_negative_index("A", "S", S); + Eigen::Matrix A = + Eigen::Matrix::Constant(T, S, DUMMY_VAR__); + current_statement__ = 59; + stan::math::validate_non_negative_index("a_row", "S", S); + Eigen::Matrix a_row = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + int cp_idx = std::numeric_limits::min(); + current_statement__ = 62; + stan::model::assign(A, stan::math::rep_matrix(0, T, S), + "assigning variable A"); + current_statement__ = 63; + stan::model::assign(a_row, stan::math::rep_row_vector(0, S), + "assigning variable a_row"); + current_statement__ = 64; + cp_idx = 1; + current_statement__ = 71; + for (int i = 1; i <= T; ++i) { + current_statement__ = 68; + while ((stan::math::primitive_value(stan::math::logical_lte(cp_idx, S)) + && + stan::math::primitive_value( + stan::math::logical_gte( + stan::model::rvalue(t, "t", stan::model::index_uni(i)), + stan::model::rvalue(t_change, "t_change", + stan::model::index_uni(cp_idx)))))) { + current_statement__ = 65; + stan::model::assign(a_row, 1, "assigning variable a_row", + stan::model::index_uni(cp_idx)); + current_statement__ = 66; + cp_idx = (cp_idx + 1); + } + current_statement__ = 69; + stan::model::assign(A, a_row, "assigning variable A", + stan::model::index_uni(i)); + } + current_statement__ = 72; + return A; + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector logistic_gamma(real, real, vector, vector, int) +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral>*> +Eigen::Matrix, + stan::base_type_t>,-1,1> +logistic_gamma(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_change_arg__, const T4__& S, std::ostream* + pstream__) { + using local_scalar_t__ = stan::promote_args_t, + stan::base_type_t>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 74; + stan::math::validate_non_negative_index("gamma", "S", S); + Eigen::Matrix gamma = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + current_statement__ = 76; + stan::math::validate_non_negative_index("k_s", "S + 1", (S + 1)); + Eigen::Matrix k_s = + Eigen::Matrix::Constant((S + 1), DUMMY_VAR__); + local_scalar_t__ m_pr = DUMMY_VAR__; + current_statement__ = 79; + stan::model::assign(k_s, + stan::math::append_row(k, + stan::math::add(k, stan::math::cumulative_sum(delta))), + "assigning variable k_s"); + current_statement__ = 80; + m_pr = m; + current_statement__ = 84; + for (int i = 1; i <= S; ++i) { + current_statement__ = 81; + stan::model::assign(gamma, + ((stan::model::rvalue(t_change, "t_change", stan::model::index_uni(i)) + - m_pr) * (1 - + (stan::model::rvalue(k_s, "k_s", stan::model::index_uni(i)) / + stan::model::rvalue(k_s, "k_s", stan::model::index_uni((i + 1)))))), + "assigning variable gamma", stan::model::index_uni(i)); + current_statement__ = 82; + m_pr = (m_pr + + stan::model::rvalue(gamma, "gamma", stan::model::index_uni(i))); + } + current_statement__ = 85; + return gamma; + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +/* vector + logistic_trend(real, real, vector, vector, vector, matrix, vector, int) + */ +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_eigen_matrix_dynamic, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + std::is_integral>*> +Eigen::Matrix, + stan::base_type_t, stan::base_type_t, + stan::promote_args_t, + stan::base_type_t>>,-1,1> +logistic_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& cap_arg__, const T5__& + A_arg__, const T6__& t_change_arg__, const T7__& S, + std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t, + stan::base_type_t, + stan::base_type_t, + stan::promote_args_t, + stan::base_type_t>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t = stan::math::to_ref(t_arg__); + const auto& cap = stan::math::to_ref(cap_arg__); + const auto& A = stan::math::to_ref(A_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 87; + stan::math::validate_non_negative_index("gamma", "S", S); + Eigen::Matrix gamma = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + current_statement__ = 89; + stan::model::assign(gamma, + logistic_gamma(k, m, delta, t_change, S, pstream__), + "assigning variable gamma"); + current_statement__ = 90; + return stan::math::elt_multiply(cap, + stan::math::inv_logit( + stan::math::elt_multiply( + stan::math::add(k, stan::math::multiply(A, delta)), + stan::math::subtract(t, + stan::math::add(m, stan::math::multiply(A, gamma)))))); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector linear_trend(real, real, vector, vector, matrix, vector) +template , + std::is_floating_point>, + stan::math::disjunction, + std::is_floating_point>, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex, + stan::is_eigen_matrix_dynamic, + stan::is_vt_not_complex, + stan::is_col_vector, + stan::is_vt_not_complex>*> +Eigen::Matrix, + stan::base_type_t, stan::base_type_t, + stan::promote_args_t>>,-1,1> +linear_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& A_arg__, const T5__& + t_change_arg__, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t, + stan::base_type_t, + stan::base_type_t, + stan::promote_args_t>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t = stan::math::to_ref(t_arg__); + const auto& A = stan::math::to_ref(A_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 92; + return stan::math::add( + stan::math::elt_multiply( + stan::math::add(k, stan::math::multiply(A, delta)), t), + stan::math::add(m, + stan::math::multiply(A, + stan::math::elt_multiply(stan::math::minus(t_change), delta)))); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector flat_trend(real, int) +template , + std::is_floating_point>, + std::is_integral>*> +Eigen::Matrix,-1,1> +flat_trend(const T0__& m, const T1__& T, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 94; + return stan::math::rep_vector(m, T); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +class model_model final : public model_base_crtp { + private: + int T; + int K; + Eigen::Matrix t_data__; + Eigen::Matrix cap_data__; + Eigen::Matrix y_data__; + int S; + Eigen::Matrix t_change_data__; + Eigen::Matrix X_data__; + Eigen::Matrix sigmas_data__; + double tau; + int trend_indicator; + Eigen::Matrix s_a_data__; + Eigen::Matrix s_m_data__; + Eigen::Matrix A_data__; + Eigen::Matrix X_sa_data__; + Eigen::Matrix X_sm_data__; + Eigen::Map> t{nullptr, 0}; + Eigen::Map> cap{nullptr, 0}; + Eigen::Map> y{nullptr, 0}; + Eigen::Map> t_change{nullptr, 0}; + Eigen::Map> X{nullptr, 0, 0}; + Eigen::Map> sigmas{nullptr, 0}; + Eigen::Map> s_a{nullptr, 0}; + Eigen::Map> s_m{nullptr, 0}; + Eigen::Map> A{nullptr, 0, 0}; + Eigen::Map> X_sa{nullptr, 0, 0}; + Eigen::Map> X_sm{nullptr, 0, 0}; + public: + ~model_model() {} + model_model(stan::io::var_context& context__, unsigned int + random_seed__ = 0, std::ostream* pstream__ = nullptr) + : model_base_crtp(0) { + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + using local_scalar_t__ = double; + boost::ecuyer1988 base_rng__ = + stan::services::util::create_rng(random_seed__, 0); + // suppress unused var warning + (void) base_rng__; + static constexpr const char* function__ = + "model_model_namespace::model_model"; + // suppress unused var warning + (void) function__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + int pos__ = std::numeric_limits::min(); + pos__ = 1; + current_statement__ = 22; + context__.validate_dims("data initialization", "T", "int", + std::vector{}); + T = std::numeric_limits::min(); + current_statement__ = 22; + T = context__.vals_i("T")[(1 - 1)]; + current_statement__ = 23; + context__.validate_dims("data initialization", "K", "int", + std::vector{}); + K = std::numeric_limits::min(); + current_statement__ = 23; + K = context__.vals_i("K")[(1 - 1)]; + current_statement__ = 23; + stan::math::check_greater_or_equal(function__, "K", K, 1); + current_statement__ = 24; + stan::math::validate_non_negative_index("t", "T", T); + current_statement__ = 25; + context__.validate_dims("data initialization", "t", "double", + std::vector{static_cast(T)}); + t_data__ = Eigen::Matrix::Constant(T, + std::numeric_limits::quiet_NaN()); + new (&t) Eigen::Map>(t_data__.data(), T); + { + std::vector t_flat__; + current_statement__ = 25; + t_flat__ = context__.vals_r("t"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(t, t_flat__[(pos__ - 1)], + "assigning variable t", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 26; + stan::math::validate_non_negative_index("cap", "T", T); + current_statement__ = 27; + context__.validate_dims("data initialization", "cap", "double", + std::vector{static_cast(T)}); + cap_data__ = Eigen::Matrix::Constant(T, + std::numeric_limits::quiet_NaN()); + new (&cap) Eigen::Map>(cap_data__.data(), T); + { + std::vector cap_flat__; + current_statement__ = 27; + cap_flat__ = context__.vals_r("cap"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(cap, cap_flat__[(pos__ - 1)], + "assigning variable cap", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 28; + stan::math::validate_non_negative_index("y", "T", T); + current_statement__ = 29; + context__.validate_dims("data initialization", "y", "double", + std::vector{static_cast(T)}); + y_data__ = Eigen::Matrix::Constant(T, + std::numeric_limits::quiet_NaN()); + new (&y) Eigen::Map>(y_data__.data(), T); + { + std::vector y_flat__; + current_statement__ = 29; + y_flat__ = context__.vals_r("y"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(y, y_flat__[(pos__ - 1)], + "assigning variable y", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 30; + context__.validate_dims("data initialization", "S", "int", + std::vector{}); + S = std::numeric_limits::min(); + current_statement__ = 30; + S = context__.vals_i("S")[(1 - 1)]; + current_statement__ = 31; + stan::math::validate_non_negative_index("t_change", "S", S); + current_statement__ = 32; + context__.validate_dims("data initialization", "t_change", "double", + std::vector{static_cast(S)}); + t_change_data__ = Eigen::Matrix::Constant(S, + std::numeric_limits::quiet_NaN()); + new (&t_change) + Eigen::Map>(t_change_data__.data(), S); + { + std::vector t_change_flat__; + current_statement__ = 32; + t_change_flat__ = context__.vals_r("t_change"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + stan::model::assign(t_change, t_change_flat__[(pos__ - 1)], + "assigning variable t_change", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 33; + stan::math::validate_non_negative_index("X", "T", T); + current_statement__ = 34; + stan::math::validate_non_negative_index("X", "K", K); + current_statement__ = 35; + context__.validate_dims("data initialization", "X", "double", + std::vector{static_cast(T), static_cast(K)}); + X_data__ = Eigen::Matrix::Constant(T, K, + std::numeric_limits::quiet_NaN()); + new (&X) Eigen::Map>(X_data__.data(), T, K); + { + std::vector X_flat__; + current_statement__ = 35; + X_flat__ = context__.vals_r("X"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + for (int sym2__ = 1; sym2__ <= T; ++sym2__) { + stan::model::assign(X, X_flat__[(pos__ - 1)], + "assigning variable X", stan::model::index_uni(sym2__), + stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + } + current_statement__ = 36; + stan::math::validate_non_negative_index("sigmas", "K", K); + current_statement__ = 37; + context__.validate_dims("data initialization", "sigmas", "double", + std::vector{static_cast(K)}); + sigmas_data__ = Eigen::Matrix::Constant(K, + std::numeric_limits::quiet_NaN()); + new (&sigmas) + Eigen::Map>(sigmas_data__.data(), K); + { + std::vector sigmas_flat__; + current_statement__ = 37; + sigmas_flat__ = context__.vals_r("sigmas"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(sigmas, sigmas_flat__[(pos__ - 1)], + "assigning variable sigmas", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 38; + context__.validate_dims("data initialization", "tau", "double", + std::vector{}); + tau = std::numeric_limits::quiet_NaN(); + current_statement__ = 38; + tau = context__.vals_r("tau")[(1 - 1)]; + current_statement__ = 38; + stan::math::check_greater_or_equal(function__, "tau", tau, 0); + current_statement__ = 39; + context__.validate_dims("data initialization", "trend_indicator", + "int", std::vector{}); + trend_indicator = std::numeric_limits::min(); + current_statement__ = 39; + trend_indicator = context__.vals_i("trend_indicator")[(1 - 1)]; + current_statement__ = 40; + stan::math::validate_non_negative_index("s_a", "K", K); + current_statement__ = 41; + context__.validate_dims("data initialization", "s_a", "double", + std::vector{static_cast(K)}); + s_a_data__ = Eigen::Matrix::Constant(K, + std::numeric_limits::quiet_NaN()); + new (&s_a) Eigen::Map>(s_a_data__.data(), K); + { + std::vector s_a_flat__; + current_statement__ = 41; + s_a_flat__ = context__.vals_r("s_a"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(s_a, s_a_flat__[(pos__ - 1)], + "assigning variable s_a", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 42; + stan::math::validate_non_negative_index("s_m", "K", K); + current_statement__ = 43; + context__.validate_dims("data initialization", "s_m", "double", + std::vector{static_cast(K)}); + s_m_data__ = Eigen::Matrix::Constant(K, + std::numeric_limits::quiet_NaN()); + new (&s_m) Eigen::Map>(s_m_data__.data(), K); + { + std::vector s_m_flat__; + current_statement__ = 43; + s_m_flat__ = context__.vals_r("s_m"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(s_m, s_m_flat__[(pos__ - 1)], + "assigning variable s_m", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 44; + stan::math::validate_non_negative_index("A", "T", T); + current_statement__ = 45; + stan::math::validate_non_negative_index("A", "S", S); + current_statement__ = 46; + A_data__ = Eigen::Matrix::Constant(T, S, + std::numeric_limits::quiet_NaN()); + new (&A) Eigen::Map>(A_data__.data(), T, S); + current_statement__ = 46; + stan::model::assign(A, + get_changepoint_matrix(t, t_change, T, S, pstream__), + "assigning variable A"); + current_statement__ = 47; + stan::math::validate_non_negative_index("X_sa", "T", T); + current_statement__ = 48; + stan::math::validate_non_negative_index("X_sa", "K", K); + current_statement__ = 49; + X_sa_data__ = Eigen::Matrix::Constant(T, K, + std::numeric_limits::quiet_NaN()); + new (&X_sa) Eigen::Map>(X_sa_data__.data(), + T, K); + current_statement__ = 49; + stan::model::assign(X_sa, + stan::math::elt_multiply(X, + stan::math::rep_matrix(stan::math::transpose(s_a), T)), + "assigning variable X_sa"); + current_statement__ = 50; + stan::math::validate_non_negative_index("X_sm", "T", T); + current_statement__ = 51; + stan::math::validate_non_negative_index("X_sm", "K", K); + current_statement__ = 52; + X_sm_data__ = Eigen::Matrix::Constant(T, K, + std::numeric_limits::quiet_NaN()); + new (&X_sm) Eigen::Map>(X_sm_data__.data(), + T, K); + current_statement__ = 52; + stan::model::assign(X_sm, + stan::math::elt_multiply(X, + stan::math::rep_matrix(stan::math::transpose(s_m), T)), + "assigning variable X_sm"); + current_statement__ = 53; + stan::math::validate_non_negative_index("delta", "S", S); + current_statement__ = 54; + stan::math::validate_non_negative_index("beta", "K", K); + current_statement__ = 55; + stan::math::validate_non_negative_index("trend", "T", T); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + num_params_r__ = 1 + 1 + S + 1 + K; + } + inline std::string model_name() const final { + return "model_model"; + } + inline std::vector model_compile_info() const noexcept { + return std::vector{"stanc_version = stanc3 v2.34.0", + "stancflags = --warn-pedantic"}; + } + // Base log prob + template * = nullptr, + stan::require_vector_like_vt* = nullptr, + stan::require_not_st_var* = nullptr> + inline stan::scalar_type_t + log_prob_impl(VecR& params_r__, VecI& params_i__, std::ostream* + pstream__ = nullptr) const { + using T__ = stan::scalar_type_t; + using local_scalar_t__ = T__; + T__ lp__(0.0); + stan::math::accumulator lp_accum__; + stan::io::deserializer in__(params_r__, params_i__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + static constexpr const char* function__ = + "model_model_namespace::log_prob"; + // suppress unused var warning + (void) function__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.template read(); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.template read(); + Eigen::Matrix delta = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + delta = in__.template read>(S); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb(0, lp__); + Eigen::Matrix beta = + Eigen::Matrix::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + beta = in__.template read>(K); + Eigen::Matrix trend = + Eigen::Matrix::Constant(T, DUMMY_VAR__); + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + { + current_statement__ = 16; + lp_accum__.add(stan::math::normal_lpdf(k, 0, 5)); + current_statement__ = 17; + lp_accum__.add(stan::math::normal_lpdf(m, 0, 5)); + current_statement__ = 18; + lp_accum__.add(stan::math::double_exponential_lpdf(delta, + 0, tau)); + current_statement__ = 19; + lp_accum__.add(stan::math::normal_lpdf(sigma_obs, 0, 0.5)); + current_statement__ = 20; + lp_accum__.add(stan::math::normal_lpdf(beta, 0, sigmas)); + current_statement__ = 21; + lp_accum__.add(stan::math::normal_id_glm_lpdf(y, X_sa, + stan::math::elt_multiply(trend, + stan::math::add(1, + stan::math::multiply(X_sm, beta))), beta, + sigma_obs)); + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + lp_accum__.add(lp__); + return lp_accum__.sum(); + } + // Reverse mode autodiff log prob + template * = nullptr, + stan::require_vector_like_vt* = nullptr, + stan::require_st_var* = nullptr> + inline stan::scalar_type_t + log_prob_impl(VecR& params_r__, VecI& params_i__, std::ostream* + pstream__ = nullptr) const { + using T__ = stan::scalar_type_t; + using local_scalar_t__ = T__; + T__ lp__(0.0); + stan::math::accumulator lp_accum__; + stan::io::deserializer in__(params_r__, params_i__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + static constexpr const char* function__ = + "model_model_namespace::log_prob"; + // suppress unused var warning + (void) function__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.template read(); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.template read(); + Eigen::Matrix delta = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + delta = in__.template read>(S); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb(0, lp__); + Eigen::Matrix beta = + Eigen::Matrix::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + beta = in__.template read>(K); + Eigen::Matrix trend = + Eigen::Matrix::Constant(T, DUMMY_VAR__); + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + { + current_statement__ = 16; + lp_accum__.add(stan::math::normal_lpdf(k, 0, 5)); + current_statement__ = 17; + lp_accum__.add(stan::math::normal_lpdf(m, 0, 5)); + current_statement__ = 18; + lp_accum__.add(stan::math::double_exponential_lpdf(delta, + 0, tau)); + current_statement__ = 19; + lp_accum__.add(stan::math::normal_lpdf(sigma_obs, 0, 0.5)); + current_statement__ = 20; + lp_accum__.add(stan::math::normal_lpdf(beta, 0, sigmas)); + current_statement__ = 21; + lp_accum__.add(stan::math::normal_id_glm_lpdf(y, X_sa, + stan::math::elt_multiply(trend, + stan::math::add(1, + stan::math::multiply(X_sm, beta))), beta, + sigma_obs)); + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + lp_accum__.add(lp__); + return lp_accum__.sum(); + } + template * = nullptr, stan::require_vector_like_vt* = nullptr, stan::require_vector_vt* = nullptr> + inline void + write_array_impl(RNG& base_rng__, VecR& params_r__, VecI& params_i__, + VecVar& vars__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true, std::ostream* + pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::deserializer in__(params_r__, params_i__); + stan::io::serializer out__(vars__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + double lp__ = 0.0; + // suppress unused var warning + (void) lp__; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + stan::math::accumulator lp_accum__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + constexpr bool jacobian__ = false; + // suppress unused var warning + (void) jacobian__; + static constexpr const char* function__ = + "model_model_namespace::write_array"; + // suppress unused var warning + (void) function__; + try { + double k = std::numeric_limits::quiet_NaN(); + current_statement__ = 1; + k = in__.template read(); + double m = std::numeric_limits::quiet_NaN(); + current_statement__ = 2; + m = in__.template read(); + Eigen::Matrix delta = + Eigen::Matrix::Constant(S, + std::numeric_limits::quiet_NaN()); + current_statement__ = 3; + delta = in__.template read>(S); + double sigma_obs = std::numeric_limits::quiet_NaN(); + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb(0, lp__); + Eigen::Matrix beta = + Eigen::Matrix::Constant(K, + std::numeric_limits::quiet_NaN()); + current_statement__ = 5; + beta = in__.template read>(K); + Eigen::Matrix trend = + Eigen::Matrix::Constant(T, + std::numeric_limits::quiet_NaN()); + out__.write(k); + out__.write(m); + out__.write(delta); + out__.write(sigma_obs); + out__.write(beta); + if (stan::math::logical_negation( + (stan::math::primitive_value(emit_transformed_parameters__) || + stan::math::primitive_value(emit_generated_quantities__)))) { + return ; + } + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + if (emit_transformed_parameters__) { + out__.write(trend); + } + if (stan::math::logical_negation(emit_generated_quantities__)) { + return ; + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + template * = nullptr, + stan::require_vector_like_vt* = nullptr> + inline void + unconstrain_array_impl(const VecVar& params_r__, const VecI& params_i__, + VecVar& vars__, std::ostream* pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::deserializer in__(params_r__, params_i__); + stan::io::serializer out__(vars__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.read(); + out__.write(k); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.read(); + out__.write(m); + Eigen::Matrix delta = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + stan::model::assign(delta, + in__.read>(S), + "assigning variable delta"); + out__.write(delta); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.read(); + out__.write_free_lb(0, sigma_obs); + Eigen::Matrix beta = + Eigen::Matrix::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + stan::model::assign(beta, + in__.read>(K), + "assigning variable beta"); + out__.write(beta); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + template * = nullptr> + inline void + transform_inits_impl(const stan::io::var_context& context__, VecVar& + vars__, std::ostream* pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::serializer out__(vars__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 1; + context__.validate_dims("parameter initialization", "k", "double", + std::vector{}); + current_statement__ = 2; + context__.validate_dims("parameter initialization", "m", "double", + std::vector{}); + current_statement__ = 3; + context__.validate_dims("parameter initialization", "delta", "double", + std::vector{static_cast(S)}); + current_statement__ = 4; + context__.validate_dims("parameter initialization", "sigma_obs", + "double", std::vector{}); + current_statement__ = 5; + context__.validate_dims("parameter initialization", "beta", "double", + std::vector{static_cast(K)}); + int pos__ = std::numeric_limits::min(); + pos__ = 1; + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = context__.vals_r("k")[(1 - 1)]; + out__.write(k); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = context__.vals_r("m")[(1 - 1)]; + out__.write(m); + Eigen::Matrix delta = + Eigen::Matrix::Constant(S, DUMMY_VAR__); + { + std::vector delta_flat__; + current_statement__ = 3; + delta_flat__ = context__.vals_r("delta"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + stan::model::assign(delta, delta_flat__[(pos__ - 1)], + "assigning variable delta", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + out__.write(delta); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = context__.vals_r("sigma_obs")[(1 - 1)]; + out__.write_free_lb(0, sigma_obs); + Eigen::Matrix beta = + Eigen::Matrix::Constant(K, DUMMY_VAR__); + { + std::vector beta_flat__; + current_statement__ = 5; + beta_flat__ = context__.vals_r("beta"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(beta, beta_flat__[(pos__ - 1)], + "assigning variable beta", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + out__.write(beta); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + inline void + get_param_names(std::vector& names__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true) const { + names__ = std::vector{"k", "m", "delta", "sigma_obs", + "beta"}; + if (emit_transformed_parameters__) { + std::vector temp{"trend"}; + names__.reserve(names__.size() + temp.size()); + names__.insert(names__.end(), temp.begin(), temp.end()); + } + if (emit_generated_quantities__) {} + } + inline void + get_dims(std::vector>& dimss__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true) const { + dimss__ = std::vector>{std::vector{}, + std::vector{}, + std::vector{static_cast(S)}, + std::vector{}, + std::vector{static_cast(K)}}; + if (emit_transformed_parameters__) { + std::vector> + temp{std::vector{static_cast(T)}}; + dimss__.reserve(dimss__.size() + temp.size()); + dimss__.insert(dimss__.end(), temp.begin(), temp.end()); + } + if (emit_generated_quantities__) {} + } + inline void + constrained_param_names(std::vector& param_names__, bool + emit_transformed_parameters__ = true, bool + emit_generated_quantities__ = true) const final { + param_names__.emplace_back(std::string() + "k"); + param_names__.emplace_back(std::string() + "m"); + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + param_names__.emplace_back(std::string() + "delta" + '.' + + std::to_string(sym1__)); + } + param_names__.emplace_back(std::string() + "sigma_obs"); + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + param_names__.emplace_back(std::string() + "beta" + '.' + + std::to_string(sym1__)); + } + if (emit_transformed_parameters__) { + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + param_names__.emplace_back(std::string() + "trend" + '.' + + std::to_string(sym1__)); + } + } + if (emit_generated_quantities__) {} + } + inline void + unconstrained_param_names(std::vector& param_names__, bool + emit_transformed_parameters__ = true, bool + emit_generated_quantities__ = true) const final { + param_names__.emplace_back(std::string() + "k"); + param_names__.emplace_back(std::string() + "m"); + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + param_names__.emplace_back(std::string() + "delta" + '.' + + std::to_string(sym1__)); + } + param_names__.emplace_back(std::string() + "sigma_obs"); + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + param_names__.emplace_back(std::string() + "beta" + '.' + + std::to_string(sym1__)); + } + if (emit_transformed_parameters__) { + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + param_names__.emplace_back(std::string() + "trend" + '.' + + std::to_string(sym1__)); + } + } + if (emit_generated_quantities__) {} + } + inline std::string get_constrained_sizedtypes() const { + return std::string("[{\"name\":\"k\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"m\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(S) + "},\"block\":\"parameters\"},{\"name\":\"sigma_obs\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"beta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(K) + "},\"block\":\"parameters\"},{\"name\":\"trend\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(T) + "},\"block\":\"transformed_parameters\"}]"); + } + inline std::string get_unconstrained_sizedtypes() const { + return std::string("[{\"name\":\"k\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"m\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(S) + "},\"block\":\"parameters\"},{\"name\":\"sigma_obs\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"beta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(K) + "},\"block\":\"parameters\"},{\"name\":\"trend\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(T) + "},\"block\":\"transformed_parameters\"}]"); + } + // Begin method overload boilerplate + template inline void + write_array(RNG& base_rng, Eigen::Matrix& params_r, + Eigen::Matrix& vars, const bool + emit_transformed_parameters = true, const bool + emit_generated_quantities = true, std::ostream* + pstream = nullptr) const { + const size_t num_params__ = ((((1 + 1) + S) + 1) + K); + const size_t num_transformed = emit_transformed_parameters * (T); + const size_t num_gen_quantities = emit_generated_quantities * (0); + const size_t num_to_write = num_params__ + num_transformed + + num_gen_quantities; + std::vector params_i; + vars = Eigen::Matrix::Constant(num_to_write, + std::numeric_limits::quiet_NaN()); + write_array_impl(base_rng, params_r, params_i, vars, + emit_transformed_parameters, emit_generated_quantities, pstream); + } + template inline void + write_array(RNG& base_rng, std::vector& params_r, std::vector& + params_i, std::vector& vars, bool + emit_transformed_parameters = true, bool + emit_generated_quantities = true, std::ostream* + pstream = nullptr) const { + const size_t num_params__ = ((((1 + 1) + S) + 1) + K); + const size_t num_transformed = emit_transformed_parameters * (T); + const size_t num_gen_quantities = emit_generated_quantities * (0); + const size_t num_to_write = num_params__ + num_transformed + + num_gen_quantities; + vars = std::vector(num_to_write, + std::numeric_limits::quiet_NaN()); + write_array_impl(base_rng, params_r, params_i, vars, + emit_transformed_parameters, emit_generated_quantities, pstream); + } + template inline T_ + log_prob(Eigen::Matrix& params_r, std::ostream* pstream = nullptr) const { + Eigen::Matrix params_i; + return log_prob_impl(params_r, params_i, pstream); + } + template inline T_ + log_prob(std::vector& params_r, std::vector& params_i, + std::ostream* pstream = nullptr) const { + return log_prob_impl(params_r, params_i, pstream); + } + inline void + transform_inits(const stan::io::var_context& context, + Eigen::Matrix& params_r, std::ostream* + pstream = nullptr) const final { + std::vector params_r_vec(params_r.size()); + std::vector params_i; + transform_inits(context, params_i, params_r_vec, pstream); + params_r = Eigen::Map>(params_r_vec.data(), + params_r_vec.size()); + } + inline void + transform_inits(const stan::io::var_context& context, std::vector& + params_i, std::vector& vars, std::ostream* + pstream__ = nullptr) const { + vars.resize(num_params_r__); + transform_inits_impl(context, vars, pstream__); + } + inline void + unconstrain_array(const std::vector& params_constrained, + std::vector& params_unconstrained, std::ostream* + pstream = nullptr) const { + const std::vector params_i; + params_unconstrained = std::vector(num_params_r__, + std::numeric_limits::quiet_NaN()); + unconstrain_array_impl(params_constrained, params_i, + params_unconstrained, pstream); + } + inline void + unconstrain_array(const Eigen::Matrix& params_constrained, + Eigen::Matrix& params_unconstrained, + std::ostream* pstream = nullptr) const { + const std::vector params_i; + params_unconstrained = Eigen::Matrix::Constant(num_params_r__, + std::numeric_limits::quiet_NaN()); + unconstrain_array_impl(params_constrained, params_i, + params_unconstrained, pstream); + } +}; +} +using stan_model = model_model_namespace::model_model; +#ifndef USING_R +// Boilerplate +stan::model::model_base& +new_model(stan::io::var_context& data_context, unsigned int seed, + std::ostream* msg_stream) { + stan_model* m = new stan_model(data_context, seed, msg_stream); + return *m; +} +stan::math::profile_map& get_stan_profile_data() { + return model_model_namespace::profiles__; +} +#endif diff --git a/components/cpp/prophet-wasmstan/model/model.stan b/components/cpp/prophet-wasmstan/model/model.stan new file mode 100644 index 00000000..05bcb34a --- /dev/null +++ b/components/cpp/prophet-wasmstan/model/model.stan @@ -0,0 +1,143 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +functions { + matrix get_changepoint_matrix(vector t, vector t_change, int T, int S) { + // Assumes t and t_change are sorted. + matrix[T, S] A; + row_vector[S] a_row; + int cp_idx; + + // Start with an empty matrix. + A = rep_matrix(0, T, S); + a_row = rep_row_vector(0, S); + cp_idx = 1; + + // Fill in each row of A. + for (i in 1:T) { + while ((cp_idx <= S) && (t[i] >= t_change[cp_idx])) { + a_row[cp_idx] = 1; + cp_idx = cp_idx + 1; + } + A[i] = a_row; + } + return A; + } + + // Logistic trend functions + + vector logistic_gamma(real k, real m, vector delta, vector t_change, int S) { + vector[S] gamma; // adjusted offsets, for piecewise continuity + vector[S + 1] k_s; // actual rate in each segment + real m_pr; + + // Compute the rate in each segment + k_s = append_row(k, k + cumulative_sum(delta)); + + // Piecewise offsets + m_pr = m; // The offset in the previous segment + for (i in 1:S) { + gamma[i] = (t_change[i] - m_pr) * (1 - k_s[i] / k_s[i + 1]); + m_pr = m_pr + gamma[i]; // update for the next segment + } + return gamma; + } + + vector logistic_trend( + real k, + real m, + vector delta, + vector t, + vector cap, + matrix A, + vector t_change, + int S + ) { + vector[S] gamma; + + gamma = logistic_gamma(k, m, delta, t_change, S); + return cap .* inv_logit((k + A * delta) .* (t - (m + A * gamma))); + } + + // Linear trend function + + vector linear_trend( + real k, + real m, + vector delta, + vector t, + matrix A, + vector t_change + ) { + return (k + A * delta) .* t + (m + A * (-t_change .* delta)); + } + + // Flat trend function + + vector flat_trend( + real m, + int T + ) { + return rep_vector(m, T); + } +} + +data { + int T; // Number of time periods + int K; // Number of regressors + vector[T] t; // Time + vector[T] cap; // Capacities for logistic trend + vector[T] y; // Time series + int S; // Number of changepoints + vector[S] t_change; // Times of trend changepoints + matrix[T,K] X; // Regressors + vector[K] sigmas; // Scale on seasonality prior + real tau; // Scale on changepoints prior + int trend_indicator; // 0 for linear, 1 for logistic, 2 for flat + vector[K] s_a; // Indicator of additive features + vector[K] s_m; // Indicator of multiplicative features +} + +transformed data { + matrix[T, S] A = get_changepoint_matrix(t, t_change, T, S); + matrix[T, K] X_sa = X .* rep_matrix(s_a', T); + matrix[T, K] X_sm = X .* rep_matrix(s_m', T); +} + +parameters { + real k; // Base trend growth rate + real m; // Trend offset + vector[S] delta; // Trend rate adjustments + real sigma_obs; // Observation noise + vector[K] beta; // Regressor coefficients +} + +transformed parameters { + vector[T] trend; + if (trend_indicator == 0) { + trend = linear_trend(k, m, delta, t, A, t_change); + } else if (trend_indicator == 1) { + trend = logistic_trend(k, m, delta, t, cap, A, t_change, S); + } else if (trend_indicator == 2) { + trend = flat_trend(m, T); + } +} + +model { + //priors + k ~ normal(0, 5); + m ~ normal(0, 5); + delta ~ double_exponential(0, tau); + sigma_obs ~ normal(0, 0.5); + beta ~ normal(0, sigmas); + + // Likelihood + y ~ normal_id_glm( + X_sa, + trend .* (1 + X_sm * beta), + beta, + sigma_obs + ); +} diff --git a/components/cpp/prophet-wasmstan/optimizer.cpp b/components/cpp/prophet-wasmstan/optimizer.cpp new file mode 100644 index 00000000..1aeca2e8 --- /dev/null +++ b/components/cpp/prophet-wasmstan/optimizer.cpp @@ -0,0 +1,459 @@ +// Implementation of the `optimizer` interface found in the +// `prophet_wasmstan.wit` file. This effectively: +// - converts the inputs to the interface into something that Stan can +// understand, +// using a `stan::io::array_var_context` to hold data and initial parameters +// for Stan +// - uses the `model.hpp` file generated by `stanc` to create a new model with +// that data +// and optimize it using the relevant class from `stan::services::optimize`, +// passing it a `structured_writer` to write the output to (rather than a file +// writer, which is what Stan does in normal usage) +// - converts the output of the optimization into a format matching the WIT +// interface. + +#include "prophet_wasmstan.h" +#include +#include +#include +#include +#include +#include + +#include "model/model.hpp" +#include "structured_writer.cpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Convert the input data into a `stan::io::array_var_context` which can be used +// to create a Stan model. +stan::io::array_var_context +data_context(exports_augurs_prophet_wasmstan_optimizer_data_t *data) { + using size_vec = std::vector; + // Create the var context. There's a constructor which accepts + // two sets of three vectors: the first set defines the names, + // values and dimensions of the `double` type data, while the + // second is similar for the `int` type data. + std::vector names_r = { + "y", // Time series. + "t", // Timestamps. + "cap", // Capacities for logistic trend. + "t_change", // Times of trend changepoints. + "X", // Regressors. + "sigmas", // Scale on seasonality prior. + "tau", // Scale on changepoints prior. + }; + std::vector values_r; + // We can't use range based for loops here because these aren't + // vectors, they're just pointers to C-style arrays. + values_r.reserve(data->y.len + data->t.len + data->cap.len + + data->t_change.len + data->x.len + data->sigmas.len + + 1); // Add one for tau. + for (size_t i = 0; i < data->y.len; i++) { + values_r.push_back(data->y.ptr[i]); + } + for (size_t i = 0; i < data->t.len; i++) { + values_r.push_back(data->t.ptr[i]); + } + for (size_t i = 0; i < data->cap.len; i++) { + values_r.push_back(data->cap.ptr[i]); + } + for (size_t i = 0; i < data->t_change.len; i++) { + values_r.push_back(data->t_change.ptr[i]); + } + for (size_t i = 0; i < data->x.len; i++) { + values_r.push_back(data->x.ptr[i]); + } + for (size_t i = 0; i < data->sigmas.len; i++) { + values_r.push_back(data->sigmas.ptr[i]); + } + values_r.push_back(data->tau); + std::vector dims_r{ + size_vec{data->y.len}, // y + size_vec{data->t.len}, // t + size_vec{data->cap.len}, // cap + size_vec{data->t_change.len}, // t_change + size_vec{data->y.len, static_cast(data->k)}, // X + size_vec{data->sigmas.len}, // sigmas + size_vec{}, // tau + }; + + std::vector names_i = { + "T", // Number of time periods. + "S", // Number of changepoints. + "K", // Number of regressors. + "trend_indicator", + "s_a", // Indicator of additive features. + "s_m", // Indicator of multiplicative features. + }; + std::vector values_i; + values_i.reserve(names_i.size()); + // This is `T` in the STAN model definition but WIT identifiers + // must be lower-kebab-case so we used `n` instead. + values_i.push_back(data->n); + values_i.push_back(data->s); + values_i.push_back(data->k); + values_i.push_back(data->trend_indicator); + for (size_t i = 0; i < data->s_a.len; i++) { + values_i.push_back(data->s_a.ptr[i]); + } + for (size_t i = 0; i < data->s_m.len; i++) { + values_i.push_back(data->s_m.ptr[i]); + } + std::vector dims_i{size_vec{}, // T + size_vec{}, // S + size_vec{}, // K + size_vec{}, // trend_indicator + size_vec{data->s_a.len}, // s_a + size_vec{data->s_m.len}}; // s_m + + return stan::io::array_var_context(names_r, values_r, dims_r, names_i, + values_i, dims_i); +} + +// Convert the input parameters into a `stan::io::array_var_context` which can +// be used to optimize a Stan model. +stan::io::array_var_context +init_context(exports_augurs_prophet_wasmstan_optimizer_inits_t *inits) { + using size_vec = std::vector; + + std::vector names = { + "k", // Base trend growth rate + "m", // Trend offset + "delta", // Trend rate adjustments + "beta", // Regressor coefficients + "sigma_obs", // Observation noise + }; + std::vector values; + values.reserve(inits->delta.len + inits->beta.len + 3); + values.push_back(inits->k); + values.push_back(inits->m); + for (size_t i = 0; i < inits->delta.len; i++) { + values.push_back(inits->delta.ptr[i]); + } + for (size_t i = 0; i < inits->beta.len; i++) { + values.push_back(inits->beta.ptr[i]); + } + values.push_back(inits->sigma_obs); + std::vector dims{ + size_vec{}, // k + size_vec{}, // m + size_vec{inits->delta.len}, // delta + size_vec{inits->beta.len}, // beta + size_vec{}, // sigma_obs + }; + + return stan::io::array_var_context(names, values, dims); +} + +// Args to the Newton optimizer. +struct NewtonArgs { + int seed; + int chain = 1; + double init_radius = 2.0; + int iter = 2000; + + // Constructor for the default values. + NewtonArgs() {} + + // Constructor with optional overrides. + NewtonArgs(exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *opts) { + if (opts->seed.is_some) { + seed = opts->seed.val; + } + if (opts->chain.is_some) { + chain = opts->chain.val; + }; + // if (opts->init_radius.is_some) { + // init_radius = opts->init_radius.val; + // }; + if (opts->iter.is_some) { + iter = opts->iter.val; + }; + // if (opts->refresh.is_some) { + // refresh = opts->refresh.val; + // }; + } +}; + +// Args to the LBFGS optimizer. +// +// Also used for the BFGS optimizer. +struct LBFGSArgs { + int seed; + int chain = 1; + double init_radius = 2.0; + double init_alpha = 0.001; + double tol_obj = 1e-12; + double tol_rel_obj = 10000; + double tol_grad = 1e-08; + double tol_rel_grad = 1e07; + double tol_param = 1e-08; + int iter = 2000; + int refresh = 100; + // Only applies for LBFGS, not BFGS. + double history_size = 5; + + // Constructor for the default values. + LBFGSArgs() {} + + // Constructor with optional overrides. + LBFGSArgs(exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *opts) { + if (opts->seed.is_some) { + seed = opts->seed.val; + } + if (opts->chain.is_some) { + chain = opts->chain.val; + }; + // if (opts->init_radius.is_some) { + // init_radius = opts->init_radius.val; + // }; + if (opts->history_size.is_some) { + history_size = opts->history_size.val; + }; + if (opts->init_alpha.is_some) { + init_alpha = opts->init_alpha.val; + }; + if (opts->tol_obj.is_some) { + tol_obj = opts->tol_obj.val; + }; + if (opts->tol_rel_obj.is_some) { + tol_rel_obj = opts->tol_rel_obj.val; + }; + if (opts->tol_grad.is_some) { + tol_grad = opts->tol_grad.val; + }; + if (opts->tol_rel_grad.is_some) { + tol_rel_grad = opts->tol_rel_grad.val; + }; + if (opts->tol_param.is_some) { + tol_param = opts->tol_param.val; + }; + if (opts->iter.is_some) { + iter = opts->iter.val; + }; + if (opts->refresh.is_some) { + refresh = opts->refresh.val; + }; + } + + void log(stan::callbacks::stream_logger &logger) { + std::stringstream message; + message << "method = optimize" << std::endl; + message << " optimize" << std::endl; + message << " algorithm = lbfgs" << std::endl; + message << " lbfgs" << std::endl; + message << " init_alpha = " << init_alpha << std::endl; + message << " tol_obj = " << tol_obj << std::endl; + message << " tol_rel_obj = " << tol_rel_obj << std::endl; + message << " tol_grad = " << tol_grad << std::endl; + message << " tol_rel_grad = " << tol_rel_grad << std::endl; + message << " tol_param = " << tol_param << std::endl; + message << " history_size = " << history_size << std::endl; + message << " jacobian = 0" << std::endl; + message << " iter = " << iter << std::endl; + message << " save_iterations = 0" << std::endl; + message << "id = " << chain << std::endl; + message << "random" << std::endl; + message << " seed = " << seed << std::endl; + logger.debug(message); + } +}; + +// Extract the parameter values from the list of names and values. +// +// The parameter writer just writes parameters to vectors of strings +// and doubles respectively, so we need to turn those into something +// more structured. +bool store_optimized_params( + std::vector &names, std::vector &values, + augurs_prophet_wasmstan_types_optimized_params_t *ret, + prophet_wasmstan_string_t *err) { + std::vector beta; + std::vector delta; + std::vector trend; + std::vector beta_indices; + std::vector delta_indices; + std::vector trend_indices; + for (size_t i = 0; i < names.size(); i++) { + if (names[i] == "k") { + ret->k = values[i]; + } + if (names[i] == "m") { + ret->m = values[i]; + } + if (names[i] == "sigma_obs") { + ret->sigma_obs = values[i]; + } + if (names[i].substr(0, 4) == "beta") { + int index = std::stoi(names[i].substr(5)); + beta.push_back(values[i]); + // Indexes are 1-indexed in the STAN model so subtract 1. + beta_indices.push_back(index - 1); + } + if (names[i].substr(0, 5) == "delta") { + int index = std::stoi(names[i].substr(6)); + delta.push_back(values[i]); + // Indexes are 1-indexed in the STAN model so subtract 1. + delta_indices.push_back(index - 1); + } + if (names[i].substr(0, 5) == "trend") { + int index = std::stoi(names[i].substr(6)); + trend.push_back(values[i]); + // Indexes are 1-indexed in the STAN model so subtract 1. + trend_indices.push_back(index - 1); + } + } + ret->beta.len = beta.size(); + ret->delta.len = delta.size(); + ret->trend.len = trend.size(); + + ret->beta.ptr = (double *)malloc(sizeof(double) * beta.size()); + if (ret->beta.ptr == NULL) { + prophet_wasmstan_string_set(err, "Memory allocation failed for beta"); + return false; + } + for (size_t i = 0; i < beta.size(); i++) { + ret->beta.ptr[i] = beta[beta_indices[i]]; + } + + ret->delta.ptr = (double *)malloc(sizeof(double) * delta.size()); + if (ret->delta.ptr == NULL) { + prophet_wasmstan_string_set(err, "Memory allocation failed for delta"); + return false; + } + for (size_t i = 0; i < delta.size(); i++) { + ret->delta.ptr[i] = delta[delta_indices[i]]; + } + + ret->trend.ptr = (double *)malloc(sizeof(double) * trend.size()); + if (ret->trend.ptr == NULL) { + prophet_wasmstan_string_set(err, "Memory allocation failed for trend"); + return false; + } + for (size_t i = 0; i < trend.size(); i++) { + ret->trend.ptr[i] = trend[trend_indices[i]]; + } +} + +// Optimize a Prophet model using Stan. +// +// This satisfies the `optimize` interface from the `prophet_wasmstan.wit` file. +// The `prophet_wasmstan.h` file generated by `wit-bindgen` contains the +// declaration of this function; if the interface is updated, the header file +// can be updated by running `just generate-lib-skeleton`, then this +// implementation will need updating too. +bool exports_augurs_prophet_wasmstan_optimizer_optimize( + exports_augurs_prophet_wasmstan_optimizer_inits_t *init, + exports_augurs_prophet_wasmstan_optimizer_data_t *data, + exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *opts, + exports_augurs_prophet_wasmstan_optimizer_optimize_output_t *ret, + prophet_wasmstan_string_t *err) { + + // Write all logs to a single stream for now. + std::stringstream debug; + std::stringstream info; + std::stringstream warn; + std::stringstream error; + std::stringstream fatal; + stan::callbacks::stream_logger logger(debug, info, warn, error, fatal); + // We need an interrupt of some sort. + stan::callbacks::interrupt interrupt; + StructuredWriter init_writer = StructuredWriter(); + StructuredWriter parameter_writer = StructuredWriter(); + + int seed = -1; + if (opts->seed.is_some) { + seed = opts->seed.val; + } else { + seed = std::chrono::system_clock::now().time_since_epoch().count(); + } + + // Create the data context. + stan::io::array_var_context data_ctx = data_context(data); + + // Create a model. + std::stringstream msg_stream; + auto model = stan_model(data_ctx, seed, &msg_stream); + + // Create the init context. + stan::io::array_var_context init_ctx = init_context(init); + + int return_code; + // Default to the lbfgs algorithm. + int algorithm = 2; + if (opts->algorithm.is_some) { + algorithm = opts->algorithm.val; + } + NewtonArgs n_args; + LBFGSArgs args; + // Run optimization. + switch (algorithm) { + case 0: + return_code = stan::services::optimize::newton( + model, init_ctx, n_args.seed, n_args.chain, n_args.init_radius, + n_args.iter, + false, // never save iterations. + interrupt, logger, init_writer, parameter_writer); + break; + case 1: + args = LBFGSArgs(opts); + args.log(logger); + return_code = stan::services::optimize::bfgs( + model, init_ctx, args.seed, args.chain, args.init_radius, + args.init_alpha, args.tol_obj, args.tol_rel_obj, args.tol_grad, + args.tol_rel_grad, args.tol_param, args.iter, + false, // never save iterations. + args.refresh, interrupt, logger, init_writer, parameter_writer); + break; + case 2: + args = LBFGSArgs(opts); + args.log(logger); + return_code = stan::services::optimize::lbfgs( + model, init_ctx, args.seed, args.chain, args.init_radius, + args.history_size, args.init_alpha, args.tol_obj, args.tol_rel_obj, + args.tol_grad, args.tol_rel_grad, args.tol_param, args.iter, + false, // never save iterations. + args.refresh, interrupt, logger, init_writer, parameter_writer); + break; + } + + if (return_code != 0) { + std::cerr << "optimization failed: " << return_code << std::endl; + prophet_wasmstan_string_dup(err, error.str().c_str()); + return false; + } + + // Read the names and values from the parameter stream and save to the + // result. + std::vector names = parameter_writer.get_names(); + std::vector> values = parameter_writer.get_values(); + if (values.size() != 1) { + prophet_wasmstan_string_set(err, "Expected 1 parameter vector"); + return false; + } + std::vector params = values[0]; + if (params.size() != names.size()) { + prophet_wasmstan_string_set(err, + "Expected names and values lengths to match"); + } + + bool success = store_optimized_params(names, params, &ret->params, err); + if (!success) { + return false; + } + prophet_wasmstan_string_dup(&ret->logs.debug, debug.str().c_str()); + prophet_wasmstan_string_dup(&ret->logs.info, info.str().c_str()); + prophet_wasmstan_string_dup(&ret->logs.warn, warn.str().c_str()); + prophet_wasmstan_string_dup(&ret->logs.error, error.str().c_str()); + prophet_wasmstan_string_dup(&ret->logs.fatal, fatal.str().c_str()); + + return true; +} diff --git a/components/cpp/prophet-wasmstan/prophet_wasmstan.cpp b/components/cpp/prophet-wasmstan/prophet_wasmstan.cpp new file mode 100644 index 00000000..cc6563d9 --- /dev/null +++ b/components/cpp/prophet-wasmstan/prophet_wasmstan.cpp @@ -0,0 +1,458 @@ +// Generated by `wit-bindgen` 0.34.0. DO NOT EDIT! +#include "prophet_wasmstan.h" +#include +#include + +// Exported Functions from `augurs:prophet-wasmstan/optimizer` + +__attribute__((__weak__, __export_name__("cabi_post_augurs:prophet-wasmstan/optimizer#optimize"))) +void __wasm_export_exports_augurs_prophet_wasmstan_optimizer_optimize_post_return(uint8_t * arg0) { + switch ((int32_t) (int32_t) *((uint8_t*) (arg0 + 0))) { + case 0: { + if ((*((size_t*) (arg0 + 12))) > 0) { + free(*((uint8_t **) (arg0 + 8))); + } + if ((*((size_t*) (arg0 + 20))) > 0) { + free(*((uint8_t **) (arg0 + 16))); + } + if ((*((size_t*) (arg0 + 28))) > 0) { + free(*((uint8_t **) (arg0 + 24))); + } + if ((*((size_t*) (arg0 + 36))) > 0) { + free(*((uint8_t **) (arg0 + 32))); + } + if ((*((size_t*) (arg0 + 44))) > 0) { + free(*((uint8_t **) (arg0 + 40))); + } + size_t len = *((size_t*) (arg0 + 68)); + if (len > 0) { + uint8_t *ptr = *((uint8_t **) (arg0 + 64)); + for (size_t i = 0; i < len; i++) { + uint8_t *base = ptr + i * 8; + (void) base; + } + free(ptr); + } + size_t len0 = *((size_t*) (arg0 + 76)); + if (len0 > 0) { + uint8_t *ptr1 = *((uint8_t **) (arg0 + 72)); + for (size_t i2 = 0; i2 < len0; i2++) { + uint8_t *base = ptr1 + i2 * 8; + (void) base; + } + free(ptr1); + } + size_t len3 = *((size_t*) (arg0 + 92)); + if (len3 > 0) { + uint8_t *ptr4 = *((uint8_t **) (arg0 + 88)); + for (size_t i5 = 0; i5 < len3; i5++) { + uint8_t *base = ptr4 + i5 * 8; + (void) base; + } + free(ptr4); + } + break; + } + case 1: { + if ((*((size_t*) (arg0 + 12))) > 0) { + free(*((uint8_t **) (arg0 + 8))); + } + break; + } + } +} + +// Canonical ABI intrinsics + +__attribute__((__weak__, __export_name__("cabi_realloc"))) +void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) { + (void) old_size; + if (new_size == 0) return (void*) align; + void *ret = realloc(ptr, new_size); + if (!ret) abort(); + return ret; +} + +// Helper Functions + +void prophet_wasmstan_list_f64_free(prophet_wasmstan_list_f64_t *ptr) { + size_t list_len = ptr->len; + if (list_len > 0) { + double *list_ptr = ptr->ptr; + for (size_t i = 0; i < list_len; i++) { + } + free(list_ptr); + } +} + +void augurs_prophet_wasmstan_types_inits_free(augurs_prophet_wasmstan_types_inits_t *ptr) { + prophet_wasmstan_list_f64_free(&ptr->delta); + prophet_wasmstan_list_f64_free(&ptr->beta); +} + +void prophet_wasmstan_list_s32_free(prophet_wasmstan_list_s32_t *ptr) { + size_t list_len = ptr->len; + if (list_len > 0) { + int32_t *list_ptr = ptr->ptr; + for (size_t i = 0; i < list_len; i++) { + } + free(list_ptr); + } +} + +void augurs_prophet_wasmstan_types_data_free(augurs_prophet_wasmstan_types_data_t *ptr) { + prophet_wasmstan_list_f64_free(&ptr->y); + prophet_wasmstan_list_f64_free(&ptr->t); + prophet_wasmstan_list_f64_free(&ptr->cap); + prophet_wasmstan_list_f64_free(&ptr->t_change); + prophet_wasmstan_list_s32_free(&ptr->s_a); + prophet_wasmstan_list_s32_free(&ptr->s_m); + prophet_wasmstan_list_f64_free(&ptr->x); + prophet_wasmstan_list_f64_free(&ptr->sigmas); +} + +void augurs_prophet_wasmstan_types_option_algorithm_free(augurs_prophet_wasmstan_types_option_algorithm_t *ptr) { + if (ptr->is_some) { + } +} + +void prophet_wasmstan_option_u32_free(prophet_wasmstan_option_u32_t *ptr) { + if (ptr->is_some) { + } +} + +void prophet_wasmstan_option_f64_free(prophet_wasmstan_option_f64_t *ptr) { + if (ptr->is_some) { + } +} + +void prophet_wasmstan_option_bool_free(prophet_wasmstan_option_bool_t *ptr) { + if (ptr->is_some) { + } +} + +void augurs_prophet_wasmstan_types_optimize_opts_free(augurs_prophet_wasmstan_types_optimize_opts_t *ptr) { + augurs_prophet_wasmstan_types_option_algorithm_free(&ptr->algorithm); + prophet_wasmstan_option_u32_free(&ptr->seed); + prophet_wasmstan_option_u32_free(&ptr->chain); + prophet_wasmstan_option_f64_free(&ptr->init_alpha); + prophet_wasmstan_option_f64_free(&ptr->tol_obj); + prophet_wasmstan_option_f64_free(&ptr->tol_rel_obj); + prophet_wasmstan_option_f64_free(&ptr->tol_grad); + prophet_wasmstan_option_f64_free(&ptr->tol_rel_grad); + prophet_wasmstan_option_f64_free(&ptr->tol_param); + prophet_wasmstan_option_u32_free(&ptr->history_size); + prophet_wasmstan_option_u32_free(&ptr->iter); + prophet_wasmstan_option_bool_free(&ptr->jacobian); + prophet_wasmstan_option_u32_free(&ptr->refresh); +} + +void augurs_prophet_wasmstan_types_logs_free(augurs_prophet_wasmstan_types_logs_t *ptr) { + prophet_wasmstan_string_free(&ptr->debug); + prophet_wasmstan_string_free(&ptr->info); + prophet_wasmstan_string_free(&ptr->warn); + prophet_wasmstan_string_free(&ptr->error); + prophet_wasmstan_string_free(&ptr->fatal); +} + +void augurs_prophet_wasmstan_types_optimized_params_free(augurs_prophet_wasmstan_types_optimized_params_t *ptr) { + prophet_wasmstan_list_f64_free(&ptr->delta); + prophet_wasmstan_list_f64_free(&ptr->beta); + prophet_wasmstan_list_f64_free(&ptr->trend); +} + +void augurs_prophet_wasmstan_types_optimize_output_free(augurs_prophet_wasmstan_types_optimize_output_t *ptr) { + augurs_prophet_wasmstan_types_logs_free(&ptr->logs); + augurs_prophet_wasmstan_types_optimized_params_free(&ptr->params); +} + +void exports_augurs_prophet_wasmstan_optimizer_inits_free(exports_augurs_prophet_wasmstan_optimizer_inits_t *ptr) { + augurs_prophet_wasmstan_types_inits_free(ptr); +} + +void exports_augurs_prophet_wasmstan_optimizer_data_free(exports_augurs_prophet_wasmstan_optimizer_data_t *ptr) { + augurs_prophet_wasmstan_types_data_free(ptr); +} + +void exports_augurs_prophet_wasmstan_optimizer_optimize_opts_free(exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *ptr) { + augurs_prophet_wasmstan_types_optimize_opts_free(ptr); +} + +void exports_augurs_prophet_wasmstan_optimizer_optimize_output_free(exports_augurs_prophet_wasmstan_optimizer_optimize_output_t *ptr) { + augurs_prophet_wasmstan_types_optimize_output_free(ptr); +} + +void exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_free(exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_t *ptr) { + if (!ptr->is_err) { + exports_augurs_prophet_wasmstan_optimizer_optimize_output_free(&ptr->val.ok); + } else { + prophet_wasmstan_string_free(&ptr->val.err); + } +} + +void prophet_wasmstan_string_set(prophet_wasmstan_string_t *ret, const char*s) { + ret->ptr = (uint8_t*) s; + ret->len = strlen(s); +} + +void prophet_wasmstan_string_dup(prophet_wasmstan_string_t *ret, const char*s) { + ret->len = strlen(s); + ret->ptr = (uint8_t*) cabi_realloc(NULL, 0, 1, ret->len * 1); + memcpy(ret->ptr, s, ret->len * 1); +} + +void prophet_wasmstan_string_free(prophet_wasmstan_string_t *ret) { + if (ret->len > 0) { + free(ret->ptr); + } + ret->ptr = NULL; + ret->len = 0; +} + +// Component Adapters + +__attribute__((__aligned__(8))) +static uint8_t RET_AREA[96]; + +__attribute__((__export_name__("augurs:prophet-wasmstan/optimizer#optimize"))) +uint8_t * __wasm_export_exports_augurs_prophet_wasmstan_optimizer_optimize(uint8_t * arg) { + augurs_prophet_wasmstan_types_option_algorithm_t option; + switch ((int32_t) *((uint8_t*) (arg + 128))) { + case 0: { + option.is_some = false; + break; + } + case 1: { + option.is_some = true; + option.val = (int32_t) *((uint8_t*) (arg + 129)); + break; + } + } + prophet_wasmstan_option_u32_t option0; + switch ((int32_t) *((uint8_t*) (arg + 132))) { + case 0: { + option0.is_some = false; + break; + } + case 1: { + option0.is_some = true; + option0.val = (uint32_t) (*((int32_t*) (arg + 136))); + break; + } + } + prophet_wasmstan_option_u32_t option1; + switch ((int32_t) *((uint8_t*) (arg + 140))) { + case 0: { + option1.is_some = false; + break; + } + case 1: { + option1.is_some = true; + option1.val = (uint32_t) (*((int32_t*) (arg + 144))); + break; + } + } + prophet_wasmstan_option_f64_t option2; + switch ((int32_t) *((uint8_t*) (arg + 152))) { + case 0: { + option2.is_some = false; + break; + } + case 1: { + option2.is_some = true; + option2.val = *((double*) (arg + 160)); + break; + } + } + prophet_wasmstan_option_f64_t option3; + switch ((int32_t) *((uint8_t*) (arg + 168))) { + case 0: { + option3.is_some = false; + break; + } + case 1: { + option3.is_some = true; + option3.val = *((double*) (arg + 176)); + break; + } + } + prophet_wasmstan_option_f64_t option4; + switch ((int32_t) *((uint8_t*) (arg + 184))) { + case 0: { + option4.is_some = false; + break; + } + case 1: { + option4.is_some = true; + option4.val = *((double*) (arg + 192)); + break; + } + } + prophet_wasmstan_option_f64_t option5; + switch ((int32_t) *((uint8_t*) (arg + 200))) { + case 0: { + option5.is_some = false; + break; + } + case 1: { + option5.is_some = true; + option5.val = *((double*) (arg + 208)); + break; + } + } + prophet_wasmstan_option_f64_t option6; + switch ((int32_t) *((uint8_t*) (arg + 216))) { + case 0: { + option6.is_some = false; + break; + } + case 1: { + option6.is_some = true; + option6.val = *((double*) (arg + 224)); + break; + } + } + prophet_wasmstan_option_f64_t option7; + switch ((int32_t) *((uint8_t*) (arg + 232))) { + case 0: { + option7.is_some = false; + break; + } + case 1: { + option7.is_some = true; + option7.val = *((double*) (arg + 240)); + break; + } + } + prophet_wasmstan_option_u32_t option8; + switch ((int32_t) *((uint8_t*) (arg + 248))) { + case 0: { + option8.is_some = false; + break; + } + case 1: { + option8.is_some = true; + option8.val = (uint32_t) (*((int32_t*) (arg + 252))); + break; + } + } + prophet_wasmstan_option_u32_t option9; + switch ((int32_t) *((uint8_t*) (arg + 256))) { + case 0: { + option9.is_some = false; + break; + } + case 1: { + option9.is_some = true; + option9.val = (uint32_t) (*((int32_t*) (arg + 260))); + break; + } + } + prophet_wasmstan_option_bool_t option10; + switch ((int32_t) *((uint8_t*) (arg + 264))) { + case 0: { + option10.is_some = false; + break; + } + case 1: { + option10.is_some = true; + option10.val = (int32_t) *((uint8_t*) (arg + 265)); + break; + } + } + prophet_wasmstan_option_u32_t option11; + switch ((int32_t) *((uint8_t*) (arg + 268))) { + case 0: { + option11.is_some = false; + break; + } + case 1: { + option11.is_some = true; + option11.val = (uint32_t) (*((int32_t*) (arg + 272))); + break; + } + } + exports_augurs_prophet_wasmstan_optimizer_inits_t arg12 = (augurs_prophet_wasmstan_types_inits_t) { + (double) *((double*) (arg + 0)), + (double) *((double*) (arg + 8)), + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 16))), (*((size_t*) (arg + 20))) }, + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 24))), (*((size_t*) (arg + 28))) }, + (double) *((double*) (arg + 32)), + }; + exports_augurs_prophet_wasmstan_optimizer_data_t arg13 = (augurs_prophet_wasmstan_types_data_t) { + (int32_t) *((int32_t*) (arg + 40)), + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 44))), (*((size_t*) (arg + 48))) }, + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 52))), (*((size_t*) (arg + 56))) }, + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 60))), (*((size_t*) (arg + 64))) }, + (int32_t) *((int32_t*) (arg + 68)), + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 72))), (*((size_t*) (arg + 76))) }, + (augurs_prophet_wasmstan_types_trend_indicator_t) (int32_t) *((uint8_t*) (arg + 80)), + (int32_t) *((int32_t*) (arg + 84)), + (prophet_wasmstan_list_s32_t) (prophet_wasmstan_list_s32_t) { (int32_t*)(*((uint8_t **) (arg + 88))), (*((size_t*) (arg + 92))) }, + (prophet_wasmstan_list_s32_t) (prophet_wasmstan_list_s32_t) { (int32_t*)(*((uint8_t **) (arg + 96))), (*((size_t*) (arg + 100))) }, + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 104))), (*((size_t*) (arg + 108))) }, + (prophet_wasmstan_list_f64_t) (prophet_wasmstan_list_f64_t) { (double*)(*((uint8_t **) (arg + 112))), (*((size_t*) (arg + 116))) }, + (double) *((double*) (arg + 120)), + }; + exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t arg14 = (augurs_prophet_wasmstan_types_optimize_opts_t) { + (augurs_prophet_wasmstan_types_option_algorithm_t) option, + (prophet_wasmstan_option_u32_t) option0, + (prophet_wasmstan_option_u32_t) option1, + (prophet_wasmstan_option_f64_t) option2, + (prophet_wasmstan_option_f64_t) option3, + (prophet_wasmstan_option_f64_t) option4, + (prophet_wasmstan_option_f64_t) option5, + (prophet_wasmstan_option_f64_t) option6, + (prophet_wasmstan_option_f64_t) option7, + (prophet_wasmstan_option_u32_t) option8, + (prophet_wasmstan_option_u32_t) option9, + (prophet_wasmstan_option_bool_t) option10, + (prophet_wasmstan_option_u32_t) option11, + }; + exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_t ret; + exports_augurs_prophet_wasmstan_optimizer_optimize_output_t ok; + prophet_wasmstan_string_t err; + ret.is_err = !exports_augurs_prophet_wasmstan_optimizer_optimize(&arg12, &arg13, &arg14, &ok, &err); + if (ret.is_err) { + ret.val.err = err; + } + if (!ret.is_err) { + ret.val.ok = ok; + } + free(arg); + uint8_t *ptr = (uint8_t *) &RET_AREA; + if ((ret).is_err) { + const prophet_wasmstan_string_t *payload15 = &(ret).val.err;*((int8_t*)(ptr + 0)) = 1; + *((size_t*)(ptr + 12)) = (*payload15).len; + *((uint8_t **)(ptr + 8)) = (uint8_t *) (*payload15).ptr; + } else { + const exports_augurs_prophet_wasmstan_optimizer_optimize_output_t *payload = &(ret).val.ok;*((int8_t*)(ptr + 0)) = 0; + *((size_t*)(ptr + 12)) = (((*payload).logs).debug).len; + *((uint8_t **)(ptr + 8)) = (uint8_t *) (((*payload).logs).debug).ptr; + *((size_t*)(ptr + 20)) = (((*payload).logs).info).len; + *((uint8_t **)(ptr + 16)) = (uint8_t *) (((*payload).logs).info).ptr; + *((size_t*)(ptr + 28)) = (((*payload).logs).warn).len; + *((uint8_t **)(ptr + 24)) = (uint8_t *) (((*payload).logs).warn).ptr; + *((size_t*)(ptr + 36)) = (((*payload).logs).error).len; + *((uint8_t **)(ptr + 32)) = (uint8_t *) (((*payload).logs).error).ptr; + *((size_t*)(ptr + 44)) = (((*payload).logs).fatal).len; + *((uint8_t **)(ptr + 40)) = (uint8_t *) (((*payload).logs).fatal).ptr; + *((double*)(ptr + 48)) = ((*payload).params).k; + *((double*)(ptr + 56)) = ((*payload).params).m; + *((size_t*)(ptr + 68)) = (((*payload).params).delta).len; + *((uint8_t **)(ptr + 64)) = (uint8_t *) (((*payload).params).delta).ptr; + *((size_t*)(ptr + 76)) = (((*payload).params).beta).len; + *((uint8_t **)(ptr + 72)) = (uint8_t *) (((*payload).params).beta).ptr; + *((double*)(ptr + 80)) = ((*payload).params).sigma_obs; + *((size_t*)(ptr + 92)) = (((*payload).params).trend).len; + *((uint8_t **)(ptr + 88)) = (uint8_t *) (((*payload).params).trend).ptr; + } + return ptr; +} + +// Ensure that the *_component_type.o object is linked in + +extern void __component_type_object_force_link_prophet_wasmstan(void); +void __component_type_object_force_link_prophet_wasmstan_public_use_in_this_compilation_unit(void) { + __component_type_object_force_link_prophet_wasmstan(); +} diff --git a/components/cpp/prophet-wasmstan/prophet_wasmstan.h b/components/cpp/prophet-wasmstan/prophet_wasmstan.h new file mode 100644 index 00000000..bc7048b4 --- /dev/null +++ b/components/cpp/prophet-wasmstan/prophet_wasmstan.h @@ -0,0 +1,272 @@ +// Generated by `wit-bindgen` 0.34.0. DO NOT EDIT! +#ifndef __BINDINGS_PROPHET_WASMSTAN_H +#define __BINDINGS_PROPHET_WASMSTAN_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct prophet_wasmstan_string_t { + uint8_t*ptr; + size_t len; +} prophet_wasmstan_string_t; + +typedef struct { + double *ptr; + size_t len; +} prophet_wasmstan_list_f64_t; + +// The initial parameters for the optimization. +typedef struct augurs_prophet_wasmstan_types_inits_t { + // Base trend growth rate. + double k; + // Trend offset. + double m; + // Trend rate adjustments, length s in data. + prophet_wasmstan_list_f64_t delta; + // Regressor coefficients, length k in data. + prophet_wasmstan_list_f64_t beta; + // Observation noise. + double sigma_obs; +} augurs_prophet_wasmstan_types_inits_t; + +// The type of trend to use. +typedef uint8_t augurs_prophet_wasmstan_types_trend_indicator_t; + +// Linear trend (default). +#define AUGURS_PROPHET_WASMSTAN_TYPES_TREND_INDICATOR_LINEAR 0 +// 0 +// Logistic trend. +#define AUGURS_PROPHET_WASMSTAN_TYPES_TREND_INDICATOR_LOGISTIC 1 +// 1 +// Flat trend. +#define AUGURS_PROPHET_WASMSTAN_TYPES_TREND_INDICATOR_FLAT 2 + +typedef struct { + int32_t *ptr; + size_t len; +} prophet_wasmstan_list_s32_t; + +// Data for the Prophet model. +typedef struct augurs_prophet_wasmstan_types_data_t { + // Number of time periods. + // This is `T` in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + int32_t n; + // Time series, length n. + prophet_wasmstan_list_f64_t y; + // Time, length n. + prophet_wasmstan_list_f64_t t; + // Capacities for logistic trend, length n. + prophet_wasmstan_list_f64_t cap; + // Number of changepoints. + // This is 'S' in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + int32_t s; + // Times of trend changepoints, length s. + prophet_wasmstan_list_f64_t t_change; + // The type of trend to use. + augurs_prophet_wasmstan_types_trend_indicator_t trend_indicator; + // Number of regressors. + // Must be greater than or equal to 1. + // This is `K` in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + int32_t k; + // Indicator of additive features, length k. + // This is `s_a` in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + prophet_wasmstan_list_s32_t s_a; + // Indicator of multiplicative features, length k. + // This is `s_m` in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + prophet_wasmstan_list_s32_t s_m; + // Regressors. + // This is `X` in the Prophet STAN model definition, + // but WIT identifiers must be lower kebab-case. + // This is passed as a flat array but should be treated as + // a matrix with shape (n, k) (i.e. strides of length n). + prophet_wasmstan_list_f64_t x; + // Scale on seasonality prior. + prophet_wasmstan_list_f64_t sigmas; + // Scale on changepoints prior. + // Must be greater than 0. + double tau; +} augurs_prophet_wasmstan_types_data_t; + +// The algorithm to use for optimization. One of: 'BFGS', 'LBFGS', 'Newton'. +typedef uint8_t augurs_prophet_wasmstan_types_algorithm_t; + +// Use the Newton algorithm. +#define AUGURS_PROPHET_WASMSTAN_TYPES_ALGORITHM_NEWTON 0 +// Use the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm. +#define AUGURS_PROPHET_WASMSTAN_TYPES_ALGORITHM_BFGS 1 +// Use the Limited-memory BFGS (L-BFGS) algorithm. +#define AUGURS_PROPHET_WASMSTAN_TYPES_ALGORITHM_LBFGS 2 + +typedef struct { + bool is_some; + augurs_prophet_wasmstan_types_algorithm_t val; +} augurs_prophet_wasmstan_types_option_algorithm_t; + +typedef struct { + bool is_some; + uint32_t val; +} prophet_wasmstan_option_u32_t; + +typedef struct { + bool is_some; + double val; +} prophet_wasmstan_option_f64_t; + +typedef struct { + bool is_some; + bool val; +} prophet_wasmstan_option_bool_t; + +// Arguments for optimization. +typedef struct augurs_prophet_wasmstan_types_optimize_opts_t { + // Algorithm to use. + augurs_prophet_wasmstan_types_option_algorithm_t algorithm; + // The random seed to use for the optimization. + prophet_wasmstan_option_u32_t seed; + // The chain id to advance the PRNG. + prophet_wasmstan_option_u32_t chain; + // Line search step size for first iteration. + prophet_wasmstan_option_f64_t init_alpha; + // Convergence tolerance on changes in objective function value. + prophet_wasmstan_option_f64_t tol_obj; + // Convergence tolerance on relative changes in objective function value. + prophet_wasmstan_option_f64_t tol_rel_obj; + // Convergence tolerance on the norm of the gradient. + prophet_wasmstan_option_f64_t tol_grad; + // Convergence tolerance on the relative norm of the gradient. + prophet_wasmstan_option_f64_t tol_rel_grad; + // Convergence tolerance on changes in parameter value. + prophet_wasmstan_option_f64_t tol_param; + // Size of the history for LBFGS Hessian approximation. The value should + // be less than the dimensionality of the parameter space. 5-10 usually + // sufficient. + prophet_wasmstan_option_u32_t history_size; + // Total number of iterations. + prophet_wasmstan_option_u32_t iter; + // When `true`, use the Jacobian matrix to approximate the Hessian. + // Default is `false`. + prophet_wasmstan_option_bool_t jacobian; + // How frequently to update the log message, in number of iterations. + prophet_wasmstan_option_u32_t refresh; +} augurs_prophet_wasmstan_types_optimize_opts_t; + +// Log lines produced during optimization. +typedef struct augurs_prophet_wasmstan_types_logs_t { + // Debug log lines. + prophet_wasmstan_string_t debug; + // Info log lines. + prophet_wasmstan_string_t info; + // Warning log lines. + prophet_wasmstan_string_t warn; + // Error log lines. + prophet_wasmstan_string_t error; + // Fatal log lines. + prophet_wasmstan_string_t fatal; +} augurs_prophet_wasmstan_types_logs_t; + +// The optimal parameter values found by optimization. +typedef struct augurs_prophet_wasmstan_types_optimized_params_t { + // Base trend growth rate. + double k; + // Trend offset. + double m; + // Trend rate adjustments, length s in data. + prophet_wasmstan_list_f64_t delta; + // Regressor coefficients, length k in data. + prophet_wasmstan_list_f64_t beta; + // Observation noise. + double sigma_obs; + // Transformed trend. + prophet_wasmstan_list_f64_t trend; +} augurs_prophet_wasmstan_types_optimized_params_t; + +// The result of optimization. +// +// This includes both the parameters and any logs produced by the +// process. +typedef struct augurs_prophet_wasmstan_types_optimize_output_t { + // Logs produced by the optimization process. + augurs_prophet_wasmstan_types_logs_t logs; + // The optimized parameters. + augurs_prophet_wasmstan_types_optimized_params_t params; +} augurs_prophet_wasmstan_types_optimize_output_t; + +typedef augurs_prophet_wasmstan_types_inits_t exports_augurs_prophet_wasmstan_optimizer_inits_t; + +typedef augurs_prophet_wasmstan_types_data_t exports_augurs_prophet_wasmstan_optimizer_data_t; + +typedef augurs_prophet_wasmstan_types_optimize_opts_t exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t; + +typedef augurs_prophet_wasmstan_types_optimize_output_t exports_augurs_prophet_wasmstan_optimizer_optimize_output_t; + +typedef struct { + bool is_err; + union { + exports_augurs_prophet_wasmstan_optimizer_optimize_output_t ok; + prophet_wasmstan_string_t err; + } val; +} exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_t; + +// Exported Functions from `augurs:prophet-wasmstan/optimizer` +bool exports_augurs_prophet_wasmstan_optimizer_optimize(exports_augurs_prophet_wasmstan_optimizer_inits_t *init, exports_augurs_prophet_wasmstan_optimizer_data_t *data, exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *opts, exports_augurs_prophet_wasmstan_optimizer_optimize_output_t *ret, prophet_wasmstan_string_t *err); + +// Helper Functions + +void prophet_wasmstan_list_f64_free(prophet_wasmstan_list_f64_t *ptr); + +void augurs_prophet_wasmstan_types_inits_free(augurs_prophet_wasmstan_types_inits_t *ptr); + +void prophet_wasmstan_list_s32_free(prophet_wasmstan_list_s32_t *ptr); + +void augurs_prophet_wasmstan_types_data_free(augurs_prophet_wasmstan_types_data_t *ptr); + +void augurs_prophet_wasmstan_types_option_algorithm_free(augurs_prophet_wasmstan_types_option_algorithm_t *ptr); + +void prophet_wasmstan_option_u32_free(prophet_wasmstan_option_u32_t *ptr); + +void prophet_wasmstan_option_f64_free(prophet_wasmstan_option_f64_t *ptr); + +void prophet_wasmstan_option_bool_free(prophet_wasmstan_option_bool_t *ptr); + +void augurs_prophet_wasmstan_types_optimize_opts_free(augurs_prophet_wasmstan_types_optimize_opts_t *ptr); + +void augurs_prophet_wasmstan_types_logs_free(augurs_prophet_wasmstan_types_logs_t *ptr); + +void augurs_prophet_wasmstan_types_optimized_params_free(augurs_prophet_wasmstan_types_optimized_params_t *ptr); + +void augurs_prophet_wasmstan_types_optimize_output_free(augurs_prophet_wasmstan_types_optimize_output_t *ptr); + +void exports_augurs_prophet_wasmstan_optimizer_inits_free(exports_augurs_prophet_wasmstan_optimizer_inits_t *ptr); + +void exports_augurs_prophet_wasmstan_optimizer_data_free(exports_augurs_prophet_wasmstan_optimizer_data_t *ptr); + +void exports_augurs_prophet_wasmstan_optimizer_optimize_opts_free(exports_augurs_prophet_wasmstan_optimizer_optimize_opts_t *ptr); + +void exports_augurs_prophet_wasmstan_optimizer_optimize_output_free(exports_augurs_prophet_wasmstan_optimizer_optimize_output_t *ptr); + +void exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_free(exports_augurs_prophet_wasmstan_optimizer_result_optimize_output_string_t *ptr); + +// Transfers ownership of `s` into the string `ret` +void prophet_wasmstan_string_set(prophet_wasmstan_string_t *ret, const char*s); + +// Creates a copy of the input nul-terminate string `s` and +// stores it into the component model string `ret`. +void prophet_wasmstan_string_dup(prophet_wasmstan_string_t *ret, const char*s); + +// Deallocates the string pointed to by `ret`, deallocating +// the memory behind the string. +void prophet_wasmstan_string_free(prophet_wasmstan_string_t *ret); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/components/cpp/prophet-wasmstan/shim/cpp/exceptions.cpp b/components/cpp/prophet-wasmstan/shim/cpp/exceptions.cpp new file mode 100644 index 00000000..54c35f2b --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/cpp/exceptions.cpp @@ -0,0 +1,17 @@ +// Stub out calls to exception-related functions until WASI supports them. +#include +#include +#include + +extern "C" { +void *__cxa_allocate_exception(size_t) { + std::cerr << "Exception thrown" << std::endl; + abort(); +}; + +void __cxa_throw(void *thrown_exception, std::type_info *tinfo, + void(_LIBCXXABI_DTOR_FUNC)(void *)) { + std::cerr << "Exception thrown: " << tinfo->name() << std::endl; + abort(); +} +} diff --git a/components/cpp/prophet-wasmstan/shim/tbb/blocked_range.h b/components/cpp/prophet-wasmstan/shim/tbb/blocked_range.h new file mode 100644 index 00000000..5d47ee4d --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/blocked_range.h @@ -0,0 +1,22 @@ +#ifndef __TBB_blocked_range_H +#define __TBB_blocked_range_H + +namespace tbb { + +template +class blocked_range { + public: + blocked_range(Value begin, Value end, std::size_t grainsize) + : begin_(begin), end_(end) {} + Value begin() const { return begin_; } + Value end() const { return end_; } + std::size_t size() const { return end_ - begin_; } + bool empty() const { return !(begin_ < end_); } + private: + Value begin_; + Value end_; +}; + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/parallel_for.h b/components/cpp/prophet-wasmstan/shim/tbb/parallel_for.h new file mode 100644 index 00000000..9e018649 --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/parallel_for.h @@ -0,0 +1,18 @@ +#ifndef __TBB_parallel_for_H +#define __TBB_parallel_for_H + +#include "partitioner.h" +#include "blocked_range.h" + +namespace tbb { + +template +void parallel_for(const blocked_range& range, const Body& body, const simple_partitioner& partitioner) { + for (RangeType idx = range.begin(); idx < range.end(); idx++) { + body(idx); + } +} + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/parallel_reduce.h b/components/cpp/prophet-wasmstan/shim/tbb/parallel_reduce.h new file mode 100644 index 00000000..fe2155d6 --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/parallel_reduce.h @@ -0,0 +1,21 @@ +#ifndef __TBB_parallel_reduce_H +#define __TBB_parallel_reduce_H + +#include "partitioner.h" + +namespace tbb { + +template +void parallel_reduce(const Range& range, Body& body) { + body(range); +} + +template +void parallel_deterministic_reduce(const Range& range, Body& body, + const simple_partitioner& partitioner) { + body(range); +} + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/partitioner.h b/components/cpp/prophet-wasmstan/shim/tbb/partitioner.h new file mode 100644 index 00000000..e69eafd1 --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/partitioner.h @@ -0,0 +1,15 @@ +#ifndef __TBB_partitioner_H +#define __TBB_partitioner_H + +namespace tbb { + +class split {}; + +class simple_partitioner { + public: + simple_partitioner() {} +}; + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/task_arena.h b/components/cpp/prophet-wasmstan/shim/tbb/task_arena.h new file mode 100644 index 00000000..d6e16388 --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/task_arena.h @@ -0,0 +1,15 @@ +#ifndef __TBB_task_arena_H +#define __TBB_task_arena_H + +namespace tbb { +namespace this_task_arena { + +template +auto isolate(const F& f) { + return f(); +} + +} +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_init.h b/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_init.h new file mode 100644 index 00000000..6b81156e --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_init.h @@ -0,0 +1,17 @@ +#ifndef __TBB_task_scheduler_init_H +#define __TBB_task_scheduler_init_H + +#include + +namespace tbb { + +typedef size_t stack_size_type; + +class task_scheduler_init { + public: + task_scheduler_init(size_t, size_t) {} +}; + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_observer.h b/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_observer.h new file mode 100644 index 00000000..d8a62b00 --- /dev/null +++ b/components/cpp/prophet-wasmstan/shim/tbb/task_scheduler_observer.h @@ -0,0 +1,13 @@ +#ifndef __TBB_task_scheduler_observer_H +#define __TBB_task_scheduler_observer_H + +namespace tbb { + +class task_scheduler_observer { + public: + void observe(bool) {} +}; + +} + +#endif diff --git a/components/cpp/prophet-wasmstan/shim/tbb/tbb_stddef.h b/components/cpp/prophet-wasmstan/shim/tbb/tbb_stddef.h new file mode 100644 index 00000000..e69de29b diff --git a/components/cpp/prophet-wasmstan/stan b/components/cpp/prophet-wasmstan/stan new file mode 160000 index 00000000..16f723b8 --- /dev/null +++ b/components/cpp/prophet-wasmstan/stan @@ -0,0 +1 @@ +Subproject commit 16f723b895d79b40ebfef9b20a56df951664ac6f diff --git a/components/cpp/prophet-wasmstan/structured_writer.cpp b/components/cpp/prophet-wasmstan/structured_writer.cpp new file mode 100644 index 00000000..82decc66 --- /dev/null +++ b/components/cpp/prophet-wasmstan/structured_writer.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +#include + +// An implementation of stan::callbacks::writer that stores the +// names and values written to the stream into vectors. +class StructuredWriter : public stan::callbacks::writer { +public: + StructuredWriter(const std::string &comment_prefix = "#") + : comment_prefix(comment_prefix) {} + + void operator()(const std::vector &names) { + this->names = names; + } + + void operator()(const std::vector &values) { + this->values.push_back(values); + } + + void operator()() { comment << comment_prefix << std::endl; } + void operator()(const std::string &message) { + comment << comment_prefix << message << std::endl; + } + + std::vector get_names() { return names; } + std::vector> get_values() { return values; } + + std::string get_comment() { return comment.str(); } + +private: + std::vector names; + std::vector> values; + std::stringstream comment; + std::string comment_prefix; +}; diff --git a/components/cpp/prophet-wasmstan/wit/prophet-wasmstan.wit b/components/cpp/prophet-wasmstan/wit/prophet-wasmstan.wit new file mode 100644 index 00000000..f765f684 --- /dev/null +++ b/components/cpp/prophet-wasmstan/wit/prophet-wasmstan.wit @@ -0,0 +1,175 @@ +package augurs:prophet-wasmstan; + +/// Types used by prophet-wasmstan. +/// +/// These are split out into a separate interface to work around +/// https://github.com/bytecodealliance/wac/issues/141. +interface types { + /// The initial parameters for the optimization. + record inits { + /// Base trend growth rate. + k: f64, + /// Trend offset. + m: f64, + /// Trend rate adjustments, length s in data. + delta: list, + /// Regressor coefficients, length k in data. + beta: list, + /// Observation noise. + sigma-obs: f64, + } + + /// The type of trend to use. + enum trend-indicator { + /// Linear trend (default). + linear, // 0 + /// Logistic trend. + logistic, // 1 + /// Flat trend. + flat, // 2 + } + + /// Data for the Prophet model. + record data { + /// Number of time periods. + /// This is `T` in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + n: s32, + /// Time series, length n. + y: list, + /// Time, length n. + t: list, + /// Capacities for logistic trend, length n. + cap: list, + + /// Number of changepoints. + /// This is 'S' in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + s: s32, + /// Times of trend changepoints, length s. + t-change: list, + + /// The type of trend to use. + trend-indicator: trend-indicator, + + /// Number of regressors. + /// Must be greater than or equal to 1. + /// This is `K` in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + k: s32, + /// Indicator of additive features, length k. + /// This is `s_a` in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + s-a: list, + /// Indicator of multiplicative features, length k. + /// This is `s_m` in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + s-m: list, + /// Regressors. + /// This is `X` in the Prophet STAN model definition, + /// but WIT identifiers must be lower kebab-case. + /// This is passed as a flat array but should be treated as + /// a matrix with shape (n, k) (i.e. strides of length n). + x: list, + + /// Scale on seasonality prior. + sigmas: list, + /// Scale on changepoints prior. + /// Must be greater than 0. + tau: f64, + } + + /// The algorithm to use for optimization. One of: 'BFGS', 'LBFGS', 'Newton'. + enum algorithm { + /// Use the Newton algorithm. + newton, + /// Use the Broyden-Fletcher-Goldfarb-Shanno (BFGS) algorithm. + bfgs, + /// Use the Limited-memory BFGS (L-BFGS) algorithm. + lbfgs, + } + + /// Arguments for optimization. + record optimize-opts { + /// Algorithm to use. + algorithm: option, + /// The random seed to use for the optimization. + seed: option, + /// The chain id to advance the PRNG. + chain: option, + /// Line search step size for first iteration. + init-alpha: option, + /// Convergence tolerance on changes in objective function value. + tol-obj: option, + /// Convergence tolerance on relative changes in objective function value. + tol-rel-obj: option, + /// Convergence tolerance on the norm of the gradient. + tol-grad: option, + /// Convergence tolerance on the relative norm of the gradient. + tol-rel-grad: option, + /// Convergence tolerance on changes in parameter value. + tol-param: option, + /// Size of the history for LBFGS Hessian approximation. The value should + /// be less than the dimensionality of the parameter space. 5-10 usually + /// sufficient. + history-size: option, + /// Total number of iterations. + iter: option, + /// When `true`, use the Jacobian matrix to approximate the Hessian. + /// Default is `false`. + jacobian: option, + + /// How frequently to update the log message, in number of iterations. + refresh: option, + } + + /// Log lines produced during optimization. + record logs { + /// Debug log lines. + debug: string, + /// Info log lines. + info: string, + /// Warning log lines. + warn: string, + /// Error log lines. + error: string, + /// Fatal log lines. + fatal: string, + } + + /// The optimal parameter values found by optimization. + record optimized-params { + /// Base trend growth rate. + k: f64, + /// Trend offset. + m: f64, + /// Trend rate adjustments, length s in data. + delta: list, + /// Regressor coefficients, length k in data. + beta: list, + /// Observation noise. + sigma-obs: f64, + /// Transformed trend. + trend: list, + } + + /// The result of optimization. + /// + /// This includes both the parameters and any logs produced by the + /// process. + record optimize-output { + /// Logs produced by the optimization process. + logs: logs, + /// The optimized parameters. + params: optimized-params, + } +} + +interface optimizer { + use types.{inits, data, optimize-opts, optimize-output}; + optimize: func(init: inits, data: data, opts: optimize-opts) -> result; +} + +world prophet-wasmstan { + export optimizer; +} diff --git a/components/js/prophet-wasmstan/.gitignore b/components/js/prophet-wasmstan/.gitignore new file mode 100644 index 00000000..7b9806cf --- /dev/null +++ b/components/js/prophet-wasmstan/.gitignore @@ -0,0 +1,6 @@ +/interfaces +/node_modules +prophet-wasmstan.*.wasm +prophet-wasmstan.d.ts +prophet-wasmstan.js +bsull-augurs-prophet-wasmstan-*.tgz diff --git a/components/js/prophet-wasmstan/README.md b/components/js/prophet-wasmstan/README.md new file mode 100644 index 00000000..5d7f6e72 --- /dev/null +++ b/components/js/prophet-wasmstan/README.md @@ -0,0 +1,28 @@ +# Prophet Stan model, compiled to WASM + +This is a WASM-compiled version of the [Prophet](https://facebook.github.io/prophet/) Stan model, for use with the [@bsull/augurs](https://github.com/grafana/augurs) library. + +## Usage + +```js +import { Prophet } from '@bsull/augurs'; +import { optimizer } from '@bsull/augurs-prophet-wasmstan'; + +// Create some fake data. +// `ds` must be timestamps since the epoch, in seconds. +const ds = [1704067200, 1704871384, 1705675569, 1706479753, 1707283938, 1708088123, + 1708892307, 1709696492, 1710500676, 1711304861, 1712109046, 1712913230, +]; +const y = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]; +const trainingData = { ds, y }; + +// Create a Prophet model and fit it to the training data. +const prophet = new Prophet(); +prophet.fit(trainingdata); +// Predict for the training set. +prophet.predict(); +// Predict for a new time point. +prophet.predict({ ds: [ 1713717414 ]}) +``` + +See the documentation for `@bsull/augurs` for more details. diff --git a/components/js/prophet-wasmstan/package-lock.json b/components/js/prophet-wasmstan/package-lock.json new file mode 100644 index 00000000..294fc8a2 --- /dev/null +++ b/components/js/prophet-wasmstan/package-lock.json @@ -0,0 +1,607 @@ +{ + "name": "@bsull/augurs-prophet-wasmstan", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@bsull/augurs-prophet-wasmstan", + "version": "0.1.0", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@bytecodealliance/preview2-shim": "^0.17.0" + }, + "devDependencies": { + "vitest": "^2.1.3" + } + }, + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.17.0", + "license": "(Apache-2.0 WITH LLVM-exception)" + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.3", + "@vitest/utils": "2.1.3", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.3", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.11" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/spy": "2.1.3", + "msw": "^2.3.5", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.3", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.3", + "magic-string": "^0.30.11", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/loupe": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.47", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.9", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.6", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.3", + "@vitest/mocker": "2.1.3", + "@vitest/pretty-format": "^2.1.3", + "@vitest/runner": "2.1.3", + "@vitest/snapshot": "2.1.3", + "@vitest/spy": "2.1.3", + "@vitest/utils": "2.1.3", + "chai": "^5.1.1", + "debug": "^4.3.6", + "magic-string": "^0.30.11", + "pathe": "^1.1.2", + "std-env": "^3.7.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.0", + "tinypool": "^1.0.0", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.3", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.3", + "@vitest/ui": "2.1.3", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/components/js/prophet-wasmstan/package.json b/components/js/prophet-wasmstan/package.json new file mode 100644 index 00000000..f6a850f3 --- /dev/null +++ b/components/js/prophet-wasmstan/package.json @@ -0,0 +1,40 @@ +{ + "name": "@bsull/augurs-prophet-wasmstan", + "type": "module", + "collaborators": [ + "Ben Sully " + ], + "description": "Prophet's Stan model, compiled to WASM, for use with the @bsull/augurs library.", + "version": "0.1.0", + "license": "(MIT OR Apache-2.0)", + "repository": { + "type": "git", + "url": "git+https://github.com/grafana/augurs.git" + }, + "readme": "README.md", + "files": [ + "interfaces/*", + "prophet-wasmstan.core*.wasm", + "prophet-wasmstan.d.ts", + "prophet-wasmstan.js", + "README.md" + ], + "main": "prophet-wasmstan.js", + "types": "prophet-wasmstan.d.ts", + "keywords": [ + "augurs", + "forecasting", + "prophet", + "stan" + ], + "dependencies": { + "@bytecodealliance/preview2-shim": "^0.17.0" + }, + "devDependencies": { + "vitest": "^2.1.3" + }, + "scripts": { + "test": "vitest", + "test:ci": "vitest run" + } +} diff --git a/components/js/prophet-wasmstan/prophet-wasmstan.test.js b/components/js/prophet-wasmstan/prophet-wasmstan.test.js new file mode 100644 index 00000000..6fe49b1d --- /dev/null +++ b/components/js/prophet-wasmstan/prophet-wasmstan.test.js @@ -0,0 +1,4997 @@ +import { expect, test } from 'vitest'; + +import { optimizer } from './prophet-wasmstan'; + +test('smoke test Prophet model', () => { + const { optimize } = optimizer; + const inits = { + beta: new Float64Array(Array(6).fill(0.0)), + delta: new Float64Array(Array(25).fill(0.0)), + k: 0.29834791059280863, + m: 0.5307510759405802, + sigmaObs: 1.0, + }; + const x = [ + [ + 0.7818314824684807, + 0.6234898018581682, + 0.9749279121815018, + -0.22252093395772451, + 0.4338837391123257, + -0.9009688679049389 + ], + [ + -0.43388373911729416, + -0.9009688679025463, + 0.7818314824676644, + 0.6234898018591917, + -0.9749279121820328, + -0.22252093395539796 + ], + [ + -0.9749279121815481, + -0.2225209339575214, + 0.433883739119789, + -0.9009688679013448, + 0.78183148246458, + 0.6234898018630595 + ], + [ + -0.7818314824682568, + 0.6234898018584488, + -0.9749279121816615, + -0.22252093395702438, + -0.4338837391198517, + -0.9009688679013146 + ], + [ + 5.098195049821593e-13, + 1.0, + 1.0196390099643185e-12, + 1.0, + -3.927509695691092e-12, + 1.0 + ], + [ + 0.7818314824677585, + 0.6234898018590738, + 0.9749279121820174, + -0.22252093395546577, + 0.43388373912037337, + -0.9009688679010633 + ], + [ + -0.9749279121816951, + -0.22252093395687741, + 0.43388373911859873, + -0.900968867901918, + 0.7818314824680838, + 0.6234898018586659 + ], + [ + -0.781831482468979, + 0.6234898018575432, + -0.974927912181146, + -0.22252093395928313, + -0.43388373911835937, + -0.9009688679020332 + ], + [ + -6.486100836666336e-13, + 1.0, + -1.2972201673332671e-12, + 1.0, + -5.583809058091613e-12, + 1.0 + ], + [ + 0.7818314824681702, + 0.6234898018585574, + 0.9749279121817234, + -0.22252093395675376, + 0.43388373911531025, + -0.9009688679035016 + ], + [ + -0.43388373911848443, + -0.9009688679019731, + 0.7818314824693119, + 0.6234898018571259, + -0.9749279121812957, + -0.2225209339586275 + ], + [ + -0.9749279121814374, + -0.2225209339580068, + 0.4338837391206861, + -0.9009688679009128, + 0.7818314824625145, + 0.6234898018656494 + ], + [ + -0.7818314824685673, + 0.6234898018580596, + -0.97492791218144, + -0.22252093395799516, + -0.4338837391168671, + -0.9009688679027519 + ], + [ + 1.1949731230430158e-14, + 1.0, + 2.3899462460860316e-14, + 1.0, + 3.5849193691290474e-14, + 1.0 + ], + [ + 0.781831482467448, + 0.623489801859463, + 0.9749279121822388, + -0.222520933954495, + 0.4338837391233579, + -0.900968867899626 + ], + [ + -0.4338837391174407, + -0.9009688679024757, + 0.7818314824678674, + 0.6234898018589373, + -0.9749279121809271, + -0.22252093396024228 + ], + [ + -0.9749279121815844, + -0.2225209339573628, + 0.43388373911949585, + -0.900968867901486, + 0.7818314824660184, + 0.6234898018612558 + ], + [ + -0.7818314824681554, + 0.623489801858576, + -0.9749279121817339, + -0.22252093395670716, + -0.43388373911537487, + -0.9009688679034705 + ], + [ + 6.725095461274939e-13, + 1.0, + 1.3450190922549877e-12, + 1.0, + 5.6555074454741945e-12, + 1.0 + ], + [ + 0.7818314824667257, + 0.6234898018603687, + 0.9749279121827544, + -0.2225209339522362, + 0.4338837391182948, + -0.9009688679020643 + ], + [ + -0.433883739116397, + -0.9009688679029783, + 0.7818314824664228, + 0.6234898018607486, + -0.9749279121805585, + -0.22252093396185704 + ], + [ + -0.9749279121817314, + -0.2225209339567188, + 0.4338837391183056, + -0.9009688679020592, + 0.7818314824649857, + 0.6234898018625508 + ], + [ + -0.7818314824677436, + 0.6234898018590925, + -0.9749279121820279, + -0.22252093395541916, + -0.433883739120438, + -0.9009688679010323 + ], + [ + -4.859200425212989e-13, + 1.0, + -9.718400850425977e-13, + 1.0, + 3.999208083073673e-12, + 1.0 + ], + [ + 0.7818314824671376, + 0.6234898018598524, + 0.9749279121824604, + -0.2225209339535242, + 0.43388373911978706, + -0.9009688679013457 + ], + [ + -0.4338837391169922, + -0.9009688679026917, + 0.7818314824672465, + 0.6234898018597158, + -0.9749279121801899, + -0.2225209339634718 + ], + [ + -0.9749279121814736, + -0.2225209339578482, + 0.43388373912039296, + -0.9009688679010539, + 0.7818314824684895, + 0.6234898018581571 + ], + [ + -0.7818314824684658, + 0.6234898018581868, + -0.9749279121815124, + -0.2225209339576779, + -0.4338837391123903, + -0.9009688679049078 + ], + [ + 1.7463977237576478e-13, + 1.0, + 3.4927954475152957e-13, + 1.0, + 2.342908720673151e-12, + 1.0 + ], + [ + 0.7818314824675494, + 0.6234898018593359, + 0.9749279121821665, + -0.2225209339548122, + 0.43388373912127937, + -0.9009688679006271 + ], + [ + -0.43388373911594846, + -0.9009688679031943, + 0.7818314824658019, + 0.6234898018615271, + -0.9749279121814405, + -0.22252093395799305 + ], + [ + -0.9749279121816206, + -0.22252093395720418, + 0.4338837391192027, + -0.9009688679016271, + 0.7818314824674568, + 0.623489801859452 + ], + [ + -9.83789816273028e-13, + 1.0, + -1.967579632546056e-12, + 1.0, + -6.589348255910797e-12, + 1.0 + ], + [ + 0.7818314824679613, + 0.6234898018588194, + 0.9749279121818725, + -0.2225209339561002, + 0.4338837391227716, + -0.9009688678999085 + ], + [ + -0.4338837391165436, + -0.9009688679029076, + 0.7818314824666257, + 0.6234898018604943, + -0.9749279121794528, + -0.22252093396670136 + ], + [ + -0.9749279121817676, + -0.2225209339565602, + 0.4338837391180124, + -0.9009688679022003, + 0.7818314824664241, + 0.623489801860747 + ], + [ + -0.7818314824676421, + 0.6234898018592197, + -0.9749279121821004, + -0.22252093395510192, + -0.4338837391159612, + -0.9009688679031882 + ], + [ + -2.1422194049218206e-12, + 1.0, + -4.284438809843641e-12, + 1.0, + -9.696900041278929e-13, + 1.0 + ], + [ + 0.781831482467239, + 0.6234898018597251, + 0.9749279121823881, + -0.22252093395384143, + 0.4338837391177085, + -0.9009688679023468 + ], + [ + -0.43388373911713873, + -0.9009688679026211, + 0.7818314824674494, + 0.6234898018594613, + -0.9749279121807033, + -0.2225209339612226 + ], + [ + -0.9749279121819145, + -0.22252093395591618, + 0.4338837391168221, + -0.9009688679027735, + 0.7818314824653915, + 0.623489801862042 + ], + [ + -0.7818314824683644, + 0.623489801858314, + -0.9749279121815848, + -0.2225209339573607, + -0.4338837391210243, + -0.9009688679007499 + ], + [ + -1.4816595900247571e-12, + 1.0, + -2.9633191800495142e-12, + 1.0, + -2.6259893665284147e-12, + 1.0 + ], + [ + 0.7818314824676509, + 0.6234898018592087, + 0.9749279121820941, + -0.22252093395512942, + 0.4338837391257562, + -0.9009688678984712 + ], + [ + -0.433883739116095, + -0.9009688679031237, + 0.7818314824660049, + 0.6234898018612728, + -0.9749279121819538, + -0.22252093395574382 + ], + [ + -0.9749279121816568, + -0.22252093395704559, + 0.43388373911890954, + -0.9009688679017683, + 0.7818314824688952, + 0.6234898018576484 + ], + [ + -0.7818314824679525, + 0.6234898018588304, + -0.9749279121818788, + -0.2225209339560727, + -0.43388373911953204, + -0.9009688679014686 + ], + [ + -8.210997751276934e-13, + 1.0, + -1.6421995502553867e-12, + 1.0, + 2.9936688852544893e-12, + 1.0 + ], + [ + 0.7818314824680628, + 0.6234898018586922, + 0.9749279121818001, + -0.22252093395641742, + 0.433883739120693, + -0.9009688679009095 + ], + [ + -0.43388373911669015, + -0.9009688679028371, + 0.7818314824668285, + 0.6234898018602398, + -0.9749279121815853, + -0.2225209339573586 + ], + [ + -0.9749279121818037, + -0.22252093395640157, + 0.43388373911771927, + -0.9009688679023415, + 0.7818314824633261, + 0.6234898018646319 + ], + [ + -0.7818314824686748, + 0.6234898018579248, + -0.9749279121813632, + -0.22252093395833147, + -0.4338837391114843, + -0.9009688679053441 + ], + [ + -1.6053996023062966e-13, + 1.0, + -3.210799204612593e-13, + 1.0, + -5.938588091329458e-12, + 1.0 + ], + [ + 0.7818314824673405, + 0.6234898018595979, + 0.9749279121823157, + -0.22252093395415865, + 0.4338837391156299, + -0.9009688679033477 + ], + [ + -0.43388373911728534, + -0.9009688679025505, + 0.7818314824676522, + 0.623489801859207, + -0.9749279121828358, + -0.22252093395187986 + ], + [ + -0.9749279121819507, + -0.2225209339557576, + 0.43388373911652894, + -0.9009688679029147, + 0.7818314824668299, + 0.6234898018602382 + ], + [ + -0.781831482469397, + 0.6234898018570191, + -0.9749279121808476, + -0.22252093396059025, + -0.43388373910999206, + -0.9009688679060628 + ], + [ + -1.3189695488794224e-12, + 1.0, + -2.637939097758845e-12, + 1.0, + -3.1892983954655433e-13, + 1.0 + ], + [ + 0.7818314824677524, + 0.6234898018590814, + 0.9749279121820217, + -0.22252093395544664, + 0.43388373911712214, + -0.9009688679026291 + ], + [ + -0.4338837391178805, + -0.9009688679022639, + 0.7818314824684759, + 0.623489801858174, + -0.9749279121808482, + -0.22252093396058814 + ], + [ + -0.974927912181693, + -0.22252093395688696, + 0.4338837391186164, + -0.9009688679019096, + 0.7818314824703336, + 0.6234898018558446 + ], + [ + -0.7818314824689853, + 0.6234898018575354, + -0.9749279121811416, + -0.22252093395930225, + -0.4338837391150552, + -0.9009688679036245 + ], + [ + -6.584097339823587e-13, + 1.0, + -1.3168194679647174e-12, + 1.0, + -1.9752292019470763e-12, + 1.0 + ], + [ + 0.7818314824681641, + 0.6234898018585651, + 0.9749279121817277, + -0.22252093395673464, + 0.433883739112059, + -0.9009688679050674 + ], + [ + -0.43388373911683675, + -0.9009688679027665, + 0.7818314824670314, + 0.6234898018599855, + -0.9749279121820986, + -0.22252093395510938 + ], + [ + -0.9749279121818399, + -0.22252093395624298, + 0.43388373911742606, + -0.9009688679024828, + 0.781831482469301, + 0.6234898018571395 + ], + [ + -0.7818314824685734, + 0.6234898018580519, + -0.9749279121814356, + -0.22252093395801426, + -0.4338837391135629, + -0.9009688679043432 + ], + [ + 2.1500809147049793e-15, + 1.0, + 4.3001618294099586e-15, + 1.0, + -3.631528564347598e-12, + 1.0 + ], + [ + 0.781831482468576, + 0.6234898018580486, + 0.9749279121814337, + -0.22252093395802264, + 0.4338837391201067, + -0.9009688679011918 + ], + [ + -0.4338837391174319, + -0.9009688679024799, + 0.781831482467855, + 0.6234898018589526, + -0.97492791218173, + -0.22252093395672415 + ], + [ + -0.9749279121819869, + -0.22252093395559897, + 0.4338837391162358, + -0.900968867903056, + 0.7818314824728048, + 0.6234898018527459 + ], + [ + -0.7818314824681615, + 0.6234898018585684, + -0.9749279121817296, + -0.22252093395672626, + -0.43388373911862604, + -0.9009688679019048 + ], + [ + -1.1562795077340877e-12, + 1.0, + -2.3125590154681755e-12, + 1.0, + -5.2878279267481195e-12, + 1.0 + ], + [ + 0.7818314824678537, + 0.6234898018589543, + 0.9749279121819493, + -0.22252093395576386, + 0.4338837391150436, + -0.9009688679036301 + ], + [ + -0.9749279121813244, + -0.22252093395850173, + 0.43388373912160094, + -0.9009688679004723, + 0.7818314824626992, + 0.623489801865418 + ], + [ + -0.7818314824688838, + 0.6234898018576627, + -0.9749279121812141, + -0.22252093395898503, + -0.43388373911057837, + -0.9009688679057803 + ], + [ + -4.957196928370241e-13, + 1.0, + -9.914393856740482e-13, + 1.0, + 3.318303250347842e-13, + 1.0 + ], + [ + 0.7818314824682656, + 0.6234898018584378, + 0.9749279121816553, + -0.22252093395705186, + 0.4338837391165358, + -0.9009688679029114 + ], + [ + -0.43388373911698336, + -0.9009688679026959, + 0.7818314824672343, + 0.6234898018597311, + -0.974927912180993, + -0.2225209339599537 + ], + [ + -0.9749279121814713, + -0.22252093395785774, + 0.4338837391204106, + -0.9009688679010455, + 0.7818314824662029, + 0.6234898018610243 + ], + [ + -0.7818314824684719, + 0.6234898018581791, + -0.974927912181508, + -0.22252093395769704, + -0.4338837391156415, + -0.9009688679033421 + ], + [ + 1.648401220600396e-13, + 1.0, + 3.296802441200792e-13, + 1.0, + -1.3244690373657376e-12, + 1.0 + ], + [ + 0.7818314824675433, + 0.6234898018593436, + 0.9749279121821708, + -0.22252093395479308, + 0.43388373911802813, + -0.9009688679021928 + ], + [ + -0.4338837391175785, + -0.9009688679024094, + 0.781831482468058, + 0.6234898018586982, + -0.9749279121822435, + -0.22252093395447495 + ], + [ + -0.9749279121816183, + -0.22252093395721373, + 0.43388373911922035, + -0.9009688679016187, + 0.7818314824651702, + 0.6234898018623193 + ], + [ + -0.7818314824680601, + 0.6234898018586956, + -0.974927912181802, + -0.22252093395640904, + -0.43388373912070466, + -0.9009688679009038 + ], + [ + 8.253999369571033e-13, + 1.0, + 1.6507998739142066e-12, + 1.0, + 4.295189214417167e-12, + 1.0 + ], + [ + 0.7818314824668211, + 0.6234898018602493, + 0.9749279121826864, + -0.22252093395253433, + 0.4338837391195204, + -0.9009688679014741 + ], + [ + -0.43388373911817363, + -0.9009688679021227, + 0.7818314824688817, + 0.6234898018576653, + -0.9749279121818749, + -0.2225209339560897 + ], + [ + -0.9749279121817653, + -0.22252093395656974, + 0.4338837391180301, + -0.9009688679021919, + 0.7818314824686741, + 0.6234898018579257 + ], + [ + -0.7818314824687823, + 0.6234898018577899, + -0.9749279121812865, + -0.22252093395866782, + -0.433883739112657, + -0.9009688679047794 + ], + [ + -3.3302965169168946e-13, + 1.0, + -6.660593033833789e-13, + 1.0, + -4.6370677621667816e-12, + 1.0 + ], + [ + 0.7818314824672329, + 0.6234898018597328, + 0.9749279121823924, + -0.22252093395382233, + 0.4338837391210127, + -0.9009688679007555 + ], + [ + -0.43388373911549105, + -0.9009688679034146, + 0.7818314824651689, + 0.623489801862321, + -0.9749279121815063, + -0.2225209339577045 + ], + [ + -0.9749279121815075, + -0.22252093395769912, + 0.43388373912011746, + -0.9009688679011866, + 0.7818314824676413, + 0.6234898018592206 + ], + [ + -0.7818314824683705, + 0.6234898018583064, + -0.9749279121815805, + -0.22252093395737982, + -0.4338837391177201, + -0.9009688679023411 + ], + [ + 3.2753016320537424e-13, + 1.0, + 6.550603264107485e-13, + 1.0, + 9.825904896161227e-13, + 1.0 + ], + [ + 0.7818314824676448, + 0.6234898018592163, + 0.9749279121820984, + -0.22252093395511033, + 0.43388373912250494, + -0.9009688679000368 + ], + [ + -0.4338837391160862, + -0.9009688679031279, + 0.7818314824659927, + 0.6234898018612881, + -0.9749279121795187, + -0.2225209339664128 + ], + [ + -0.9749279121816545, + -0.22252093395705513, + 0.4338837391189272, + -0.9009688679017598, + 0.7818314824666087, + 0.6234898018605156 + ], + [ + -0.7818314824679586, + 0.6234898018588227, + -0.9749279121818744, + -0.22252093395609182, + -0.43388373911622785, + -0.9009688679030597 + ], + [ + 9.880899781024379e-13, + 1.0, + 1.9761799562048758e-12, + 1.0, + 6.602248741399027e-12, + 1.0 + ], + [ + 0.7818314824669225, + 0.623489801860122, + 0.974927912182614, + -0.22252093395285155, + 0.4338837391174418, + -0.9009688679024751 + ], + [ + -0.4338837391166813, + -0.9009688679028414, + 0.7818314824668163, + 0.6234898018602552, + -0.9749279121807692, + -0.22252093396093403 + ], + [ + -0.9749279121818015, + -0.22252093395641112, + 0.4338837391177369, + -0.900968867902333, + 0.781831482465576, + 0.6234898018618106 + ], + [ + -0.7818314824675467, + 0.6234898018593392, + -0.9749279121821683, + -0.22252093395480382, + -0.43388373912129097, + -0.9009688679006215 + ], + [ + -1.9893290140922114e-12, + 1.0, + -3.978658028184423e-12, + 1.0, + -2.330008235184921e-12, + 1.0 + ], + [ + 0.7818314824673344, + 0.6234898018596056, + 0.97492791218232, + -0.22252093395413955, + 0.4338837391254895, + -0.9009688678985995 + ], + [ + -0.4338837391172765, + -0.9009688679025547, + 0.78183148246764, + 0.6234898018592223, + -0.9749279121804006, + -0.2225209339625488 + ], + [ + -0.9749279121815437, + -0.22252093395754052, + 0.4338837391198243, + -0.9009688679013278, + 0.7818314824690797, + 0.6234898018574169 + ], + [ + -0.7818314824682691, + 0.6234898018584335, + -0.9749279121816529, + -0.2225209339570626, + -0.43388373911979866, + -0.9009688679013401 + ], + [ + -1.3287691991951476e-12, + 1.0, + -2.657538398390295e-12, + 1.0, + 3.289650016597983e-12, + 1.0 + ], + [ + 0.7818314824677463, + 0.6234898018590891, + 0.974927912182026, + -0.22252093395542755, + 0.4338837391204264, + -0.9009688679010378 + ], + [ + -0.7818314824678572, + 0.62348980185895, + -0.9749279121819469, + -0.2225209339557746, + -0.4338837391183064, + -0.9009688679020588 + ], + [ + -6.682093842980839e-13, + 1.0, + -1.3364187685961678e-12, + 1.0, + -5.6426069599859645e-12, + 1.0 + ], + [ + 0.781831482468158, + 0.6234898018585727, + 0.974927912181732, + -0.22252093395671554, + 0.43388373912191863, + -0.9009688679003193 + ], + [ + -0.4338837391168279, + -0.9009688679027708, + 0.7818314824670192, + 0.6234898018600008, + -0.9749279121829016, + -0.22252093395159128 + ], + [ + -0.9749279121818377, + -0.22252093395625253, + 0.43388373911744377, + -0.9009688679024742, + 0.7818314824670144, + 0.6234898018600068 + ], + [ + -0.7818314824674454, + 0.6234898018594665, + -0.9749279121822408, + -0.2225209339544866, + -0.43388373911681416, + -0.9009688679027774 + ], + [ + -1.8266389729468765e-12, + 1.0, + -3.653277945893753e-12, + 1.0, + -2.29487082030606e-14, + 1.0 + ], + [ + 0.7818314824674358, + 0.6234898018594783, + 0.9749279121822476, + -0.22252093395445677, + 0.4338837391168555, + -0.9009688679027575 + ], + [ + -0.43388373911742306, + -0.9009688679024842, + 0.7818314824678428, + 0.623489801858968, + -0.974927912180914, + -0.2225209339602996 + ], + [ + -0.9749279121819847, + -0.2225209339556085, + 0.43388373911625344, + -0.9009688679030474, + 0.7818314824659818, + 0.6234898018613018 + ], + [ + -0.7818314824693018, + 0.6234898018571385, + -0.9749279121809157, + -0.22252093396029213, + -0.43388373911532185, + -0.9009688679034961 + ], + [ + -1.166079158049813e-12, + 1.0, + -2.332158316099626e-12, + 1.0, + -1.6792480706035825e-12, + 1.0 + ], + [ + 0.7818314824678476, + 0.623489801858962, + 0.9749279121819536, + -0.22252093395574477, + 0.43388373911179234, + -0.9009688679051958 + ], + [ + -0.43388373911637934, + -0.9009688679029868, + 0.7818314824663983, + 0.6234898018607793, + -0.9749279121821645, + -0.22252093395482084 + ], + [ + -0.9749279121817269, + -0.22252093395673792, + 0.4338837391183409, + -0.9009688679020422, + 0.7818314824694855, + 0.6234898018569082 + ], + [ + -0.7818314824688899, + 0.623489801857655, + -0.9749279121812097, + -0.22252093395900413, + -0.4338837391138296, + -0.9009688679042147 + ], + [ + 0.7818314824682595, + 0.6234898018584455, + 0.9749279121816596, + -0.22252093395703276, + 0.43388373911984, + -0.9009688679013202 + ], + [ + -0.4338837391169745, + -0.9009688679027001, + 0.781831482467222, + 0.6234898018597465, + -0.974927912181796, + -0.2225209339564356 + ], + [ + -0.9749279121818739, + -0.2225209339560939, + 0.4338837391171506, + -0.9009688679026154, + 0.7818314824729893, + 0.6234898018525145 + ], + [ + -0.781831482468478, + 0.6234898018581715, + -0.9749279121815037, + -0.22252093395771613, + -0.4338837391188927, + -0.9009688679017764 + ], + [ + 1.5504047174431443e-13, + 1.0, + 3.1008094348862887e-13, + 1.0, + -4.9918467954046265e-12, + 1.0 + ], + [ + 0.7818314824675372, + 0.6234898018593512, + 0.9749279121821752, + -0.222520933954774, + 0.4338837391147769, + -0.9009688679037585 + ], + [ + -0.43388373911756967, + -0.9009688679024136, + 0.7818314824680458, + 0.6234898018587135, + -0.9749279121814274, + -0.22252093395805037 + ], + [ + -0.9749279121820209, + -0.22252093395544992, + 0.4338837391159603, + -0.9009688679031886, + 0.7818314824674202, + 0.623489801859498 + ], + [ + -0.7818314824692003, + 0.6234898018572658, + -0.9749279121809881, + -0.2225209339599749, + -0.43388373911084505, + -0.900968867905652 + ], + [ + -1.0033891169044784e-12, + 1.0, + -2.0067782338089568e-12, + 1.0, + 6.278114563782779e-13, + 1.0 + ], + [ + 0.7818314824679491, + 0.6234898018588347, + 0.9749279121818812, + -0.22252093395606198, + 0.43388373911626915, + -0.9009688679030399 + ], + [ + -0.4338837391181648, + -0.9009688679021269, + 0.7818314824688695, + 0.6234898018576807, + -0.9749279121810588, + -0.22252093395966516 + ], + [ + -0.9749279121813584, + -0.22252093395835268, + 0.43388373912132544, + -0.9009688679006049, + 0.781831482461851, + 0.6234898018664815 + ], + [ + -0.7818314824687884, + 0.6234898018577822, + -0.974927912181282, + -0.2225209339586869, + -0.43388373911590816, + -0.9009688679032137 + ], + [ + -3.4282930200741464e-13, + 1.0, + -6.856586040148293e-13, + 1.0, + -1.028487906022244e-12, + 1.0 + ], + [ + 0.781831482468361, + 0.6234898018583183, + 0.9749279121815873, + -0.22252093395734998, + 0.43388373911776146, + -0.9009688679023212 + ], + [ + -0.4338837391171211, + -0.9009688679026296, + 0.781831482467425, + 0.623489801859492, + -0.9749279121823093, + -0.22252093395418637 + ], + [ + -0.9749279121815053, + -0.2225209339577087, + 0.4338837391201351, + -0.9009688679011781, + 0.7818314824653548, + 0.6234898018620879 + ], + [ + -0.7818314824683766, + 0.6234898018582987, + -0.974927912181576, + -0.22252093395739891, + -0.4338837391144159, + -0.9009688679039324 + ], + [ + 3.1773051288964907e-13, + 1.0, + 6.354610257792981e-13, + 1.0, + 4.5911703457606605e-12, + 1.0 + ], + [ + 0.7818314824687728, + 0.6234898018578019, + 0.9749279121812933, + -0.22252093395863798, + 0.4338837391192537, + -0.9009688679016026 + ], + [ + -0.4338837391177162, + -0.900968867902343, + 0.7818314824682486, + 0.6234898018584591, + -0.9749279121819407, + -0.22252093395580116 + ], + [ + -0.7818314824679647, + 0.6234898018588151, + -0.97492791218187, + -0.22252093395611092, + -0.4338837391129236, + -0.900968867904651 + ], + [ + -8.406990757591437e-13, + 1.0, + -1.6813981515182874e-12, + 1.0, + -4.341086630823288e-12, + 1.0 + ], + [ + 0.7818314824669164, + 0.6234898018601297, + 0.9749279121826183, + -0.22252093395283243, + 0.433883739120746, + -0.9009688679008839 + ], + [ + -0.43388373911831135, + -0.9009688679020564, + 0.7818314824690723, + 0.6234898018574262, + -0.9749279121831912, + -0.2225209339503224 + ], + [ + -0.7818314824686871, + 0.6234898018579095, + -0.9749279121813546, + -0.2225209339583697, + -0.43388373911143135, + -0.9009688679053697 + ], + [ + -1.8013926086208e-13, + 1.0, + -3.6027852172416e-13, + 1.0, + 1.2785716209596165e-12, + 1.0 + ], + [ + 0.7818314824673283, + 0.6234898018596132, + 0.9749279121823243, + -0.22252093395412043, + 0.43388373912223827, + -0.9009688679001653 + ], + [ + -0.4338837391172677, + -0.900968867902559, + 0.7818314824676278, + 0.6234898018592376, + -0.9749279121812037, + -0.2225209339590307 + ], + [ + -0.9749279121815416, + -0.22252093395755007, + 0.43388373911984196, + -0.9009688679013192, + 0.7818314824667932, + 0.6234898018602841 + ], + [ + -0.7818314824682752, + 0.6234898018584258, + -0.9749279121816484, + -0.2225209339570817, + -0.43388373911649447, + -0.9009688679029313 + ], + [ + 4.804205540349837e-13, + 1.0, + 9.608411080699674e-13, + 1.0, + -3.777277414409054e-13, + 1.0 + ], + [ + 0.7818314824677401, + 0.6234898018590967, + 0.9749279121820303, + -0.22252093395540842, + 0.43388373911717515, + -0.9009688679026036 + ], + [ + -0.43388373911622397, + -0.9009688679030616, + 0.7818314824661833, + 0.6234898018610491, + -0.9749279121808351, + -0.22252093396064548 + ], + [ + -0.9749279121816886, + -0.2225209339569061, + 0.4338837391186517, + -0.9009688679018925, + 0.7818314824657605, + 0.6234898018615791 + ], + [ + -0.7818314824678633, + 0.6234898018589423, + -0.9749279121819424, + -0.2225209339557937, + -0.43388373912155764, + -0.900968867900493 + ], + [ + 1.1409803689320475e-12, + 1.0, + 2.281960737864095e-12, + 1.0, + -2.034027103841427e-12, + 1.0 + ], + [ + 0.7818314824670178, + 0.6234898018600025, + 0.9749279121825459, + -0.22252093395314965, + 0.4338837391252228, + -0.900968867898728 + ], + [ + -0.9749279121818355, + -0.22252093395626207, + 0.4338837391174614, + -0.9009688679024657, + 0.7818314824692644, + 0.6234898018571855 + ], + [ + -0.7818314824685856, + 0.6234898018580366, + -0.9749279121814269, + -0.22252093395805247, + -0.43388373912006534, + -0.9009688679012117 + ], + [ + -1.836438623262602e-12, + 1.0, + -3.672877246525204e-12, + 1.0, + -3.690326466241949e-12, + 1.0 + ], + [ + 0.7818314824674297, + 0.6234898018594861, + 0.9749279121822519, + -0.22252093395443764, + 0.4338837391201597, + -0.9009688679011663 + ], + [ + -0.4338837391157754, + -0.9009688679032777, + 0.7818314824655624, + 0.6234898018618276, + -0.974927912181717, + -0.2225209339567815 + ], + [ + -0.9749279121815778, + -0.22252093395739145, + 0.4338837391195488, + -0.9009688679014605, + 0.7818314824636952, + 0.623489801864169 + ], + [ + -0.7818314824681737, + 0.6234898018585531, + -0.9749279121817209, + -0.22252093395676448, + -0.4338837391185731, + -0.9009688679019303 + ], + [ + -1.1758788083655382e-12, + 1.0, + -2.3517576167310764e-12, + 1.0, + -5.346625828642471e-12, + 1.0 + ], + [ + 0.7818314824678415, + 0.6234898018589696, + 0.974927912181958, + -0.22252093395572564, + 0.43388373912165196, + -0.9009688679004476 + ], + [ + -0.4338837391163705, + -0.900968867902991, + 0.7818314824663861, + 0.6234898018607946, + -0.9749279121813484, + -0.22252093395839626 + ], + [ + -0.9749279121817248, + -0.22252093395674746, + 0.43388373911835854, + -0.9009688679020337, + 0.7818314824671989, + 0.6234898018597754 + ], + [ + -0.7818314824677619, + 0.6234898018590695, + -0.9749279121820149, + -0.22252093395547648, + -0.43388373911708084, + -0.900968867902649 + ], + [ + -5.153189934684744e-13, + 1.0, + -1.0306379869369489e-12, + 1.0, + -7.002925191042993e-12, + 1.0 + ], + [ + 0.7818314824671193, + 0.6234898018598753, + 0.9749279121824735, + -0.2225209339534669, + 0.43388373911658884, + -0.9009688679028859 + ], + [ + -0.43388373911696565, + -0.9009688679027045, + 0.7818314824672098, + 0.6234898018597618, + -0.9749279121809798, + -0.22252093396001102 + ], + [ + -0.9749279121818718, + -0.22252093395610345, + 0.43388373911716827, + -0.9009688679026069, + 0.7818314824661663, + 0.6234898018610703 + ], + [ + -0.78183148246735, + 0.6234898018595859, + -0.9749279121823088, + -0.22252093395418848, + -0.43388373912214395, + -0.9009688679002107 + ], + [ + -1.6737485821172672e-12, + 1.0, + -3.3474971642345343e-12, + 1.0, + -1.3832669392600888e-12, + 1.0 + ], + [ + 0.7818314824675311, + 0.6234898018593589, + 0.9749279121821796, + -0.2225209339547549, + 0.4338837391180811, + -0.9009688679021672 + ], + [ + -0.974927912181614, + -0.22252093395723285, + 0.43388373911925565, + -0.9009688679016017, + 0.78183148246967, + 0.6234898018566767 + ], + [ + -0.7818314824680723, + 0.6234898018586803, + -0.9749279121817933, + -0.22252093395644726, + -0.4338837391140963, + -0.9009688679040863 + ], + [ + -1.0131887672202035e-12, + 1.0, + -2.026377534440407e-12, + 1.0, + -1.0315523915844036e-11, + 1.0 + ], + [ + 0.781831482467943, + 0.6234898018588424, + 0.9749279121818856, + -0.2225209339560429, + 0.4338837391195734, + -0.9009688679014486 + ], + [ + -0.4338837391165171, + -0.9009688679029204, + 0.781831482466589, + 0.6234898018605403, + -0.9749279121818618, + -0.22252093395614705 + ], + [ + -0.974927912181761, + -0.22252093395658884, + 0.4338837391180654, + -0.9009688679021749, + 0.7818314824686374, + 0.6234898018579716 + ], + [ + -0.7818314824687945, + 0.6234898018577746, + -0.9749279121812777, + -0.22252093395870604, + -0.4338837391191594, + -0.900968867901648 + ], + [ + -3.526289523231398e-13, + 1.0, + -7.052579046462796e-13, + 1.0, + -4.695865664061133e-12, + 1.0 + ], + [ + 0.7818314824683549, + 0.6234898018583259, + 0.9749279121815916, + -0.22252093395733086, + 0.43388373912106565, + -0.9009688679007299 + ], + [ + -0.43388373911711225, + -0.9009688679026339, + 0.7818314824674127, + 0.6234898018595073, + -0.9749279121798742, + -0.22252093396485534 + ], + [ + -0.974927912181908, + -0.22252093395594486, + 0.4338837391168751, + -0.9009688679027481, + 0.7818314824676047, + 0.6234898018592666 + ], + [ + -0.7818314824683827, + 0.6234898018582911, + -0.9749279121815717, + -0.22252093395741804, + -0.4338837391111117, + -0.9009688679055236 + ], + [ + -1.5110585409719327e-12, + 1.0, + -3.0221170819438654e-12, + 1.0, + 9.237925877217716e-13, + 1.0 + ], + [ + 0.7818314824676326, + 0.6234898018592316, + 0.9749279121821072, + -0.2225209339550721, + 0.43388373911600253, + -0.9009688679031683 + ], + [ + -0.4338837391177074, + -0.9009688679023472, + 0.7818314824682364, + 0.6234898018584745, + -0.9749279121811247, + -0.22252093395937658 + ], + [ + -0.974927912182055, + -0.22252093395530084, + 0.4338837391156848, + -0.9009688679033213, + 0.781831482466572, + 0.6234898018605616 + ], + [ + -0.7818314824691049, + 0.6234898018573853, + -0.9749279121810561, + -0.2225209339596768, + -0.43388373911617484, + -0.9009688679030853 + ], + [ + -8.504987260748689e-13, + 1.0, + -1.7009974521497379e-12, + 1.0, + -7.325067746787502e-13, + 1.0 + ], + [ + 0.7818314824680445, + 0.6234898018587152, + 0.9749279121818132, + -0.2225209339563601, + 0.4338837391240502, + -0.9009688678992928 + ], + [ + -0.43388373911666367, + -0.9009688679028499, + 0.7818314824667919, + 0.6234898018602858, + -0.9749279121823752, + -0.22252093395389783 + ], + [ + -0.9749279121817972, + -0.22252093395643024, + 0.4338837391177722, + -0.900968867902316, + 0.7818314824700758, + 0.6234898018561679 + ], + [ + -0.7818314824686932, + 0.6234898018579018, + -0.9749279121813501, + -0.2225209339583888, + -0.4338837391146826, + -0.9009688679038039 + ], + [ + -1.8993891117780518e-13, + 1.0, + -3.7987782235561036e-13, + 1.0, + 4.8871514771041535e-12, + 1.0 + ], + [ + 0.7818314824684562, + 0.6234898018581988, + 0.9749279121815192, + -0.2225209339576481, + 0.43388373911898703, + -0.900968867901731 + ], + [ + -0.4338837391172588, + -0.9009688679025633, + 0.7818314824676156, + 0.623489801859253, + -0.9749279121820066, + -0.2225209339555126 + ], + [ + -0.9749279121815394, + -0.22252093395755962, + 0.4338837391198596, + -0.9009688679013108, + 0.7818314824645066, + 0.6234898018631514 + ], + [ + -0.7818314824682813, + 0.6234898018584182, + -0.9749279121816441, + -0.2225209339571008, + -0.4338837391131903, + -0.9009688679045226 + ], + [ + 4.706209037192585e-13, + 1.0, + 9.41241807438517e-13, + 1.0, + -4.045105499479794e-12, + 1.0 + ], + [ + -0.433883739117854, + -0.9009688679022767, + 0.7818314824684393, + 0.6234898018582201, + -0.9749279121832571, + -0.22252093395003383 + ], + [ + -0.9749279121816864, + -0.22252093395691563, + 0.43388373911866934, + -0.900968867901884, + 0.7818314824680105, + 0.6234898018587578 + ], + [ + -0.7818314824690036, + 0.6234898018575125, + -0.9749279121811286, + -0.22252093395935957, + -0.43388373911169803, + -0.9009688679052412 + ], + [ + -6.878086849295343e-13, + 1.0, + -1.3756173698590685e-12, + 1.0, + 1.57455275230311e-12, + 1.0 + ], + [ + 0.7818314824681458, + 0.623489801858588, + 0.9749279121817408, + -0.22252093395667732, + 0.43388373911541617, + -0.9009688679034507 + ], + [ + -0.43388373911844913, + -0.90096886790199, + 0.781831482469263, + 0.6234898018571872, + -0.9749279121812695, + -0.22252093395874215 + ], + [ + -0.9749279121814286, + -0.222520933958045, + 0.4338837391207568, + -0.9009688679008787, + 0.7818314824624413, + 0.6234898018657413 + ], + [ + -0.7818314824685917, + 0.6234898018580289, + -0.9749279121814225, + -0.22252093395807157, + -0.43388373911676115, + -0.900968867902803 + ], + [ + -2.7248870032470558e-14, + 1.0, + -5.4497740064941117e-14, + 1.0, + -8.174661009741167e-14, + 1.0 + ], + [ + 0.7818314824674236, + 0.6234898018594938, + 0.9749279121822563, + -0.22252093395441855, + 0.4338837391169085, + -0.900968867902732 + ], + [ + -0.4338837391174054, + -0.9009688679024926, + 0.7818314824678184, + 0.6234898018589986, + -0.97492791218252, + -0.2225209339532634 + ], + [ + -0.9749279121815756, + -0.22252093395740102, + 0.43388373911956646, + -0.9009688679014519, + 0.781831482465945, + 0.6234898018613477 + ], + [ + -0.7818314824681798, + 0.6234898018585454, + -0.9749279121817165, + -0.22252093395678357, + -0.4338837391152689, + -0.9009688679035216 + ], + [ + 6.333109448645932e-13, + 1.0, + 1.2666218897291863e-12, + 1.0, + -1.7380459724979335e-12, + 1.0 + ], + [ + 0.7818314824667013, + 0.6234898018603994, + 0.9749279121827719, + -0.22252093395215977, + 0.43388373912495615, + -0.9009688678988564 + ], + [ + -0.4338837391163617, + -0.9009688679029952, + 0.7818314824663739, + 0.6234898018608099, + -0.9749279121805323, + -0.2225209339619717 + ], + [ + -0.9749279121817226, + -0.222520933956757, + 0.4338837391183762, + -0.9009688679020251, + 0.7818314824694489, + 0.6234898018569541 + ], + [ + -0.781831482467768, + 0.6234898018590619, + -0.9749279121820105, + -0.22252093395549558, + -0.433883739120332, + -0.9009688679010833 + ], + [ + -5.251186437841997e-13, + 1.0, + -1.0502372875683993e-12, + 1.0, + -3.3943453348984553e-12, + 1.0 + ], + [ + 0.7818314824671132, + 0.623489801859883, + 0.9749279121824779, + -0.22252093395344777, + 0.43388373911989303, + -0.9009688679012947 + ], + [ + -0.4338837391169568, + -0.9009688679027087, + 0.7818314824671976, + 0.6234898018597771, + -0.9749279121817829, + -0.22252093395649292 + ], + [ + -0.9749279121814648, + -0.2225209339578864, + 0.43388373912046363, + -0.9009688679010199, + 0.7818314824638797, + 0.6234898018639377 + ], + [ + -0.7818314824684902, + 0.6234898018581562, + -0.974927912181495, + -0.22252093395775435, + -0.43388373911228434, + -0.9009688679049589 + ], + [ + 1.3544117111286408e-13, + 1.0, + 2.7088234222572817e-13, + 1.0, + 2.2253129168844486e-12, + 1.0 + ], + [ + 0.781831482467525, + 0.6234898018593665, + 0.9749279121821839, + -0.22252093395473577, + 0.4338837391213853, + -0.9009688679005761 + ], + [ + -0.43388373911591316, + -0.9009688679032113, + 0.7818314824657531, + 0.6234898018615884, + -0.9749279121814143, + -0.2225209339581077 + ], + [ + -0.9749279121816118, + -0.2225209339572424, + 0.4338837391192733, + -0.9009688679015931, + 0.7818314824673835, + 0.623489801859544 + ], + [ + -0.7818314824680784, + 0.6234898018586726, + -0.9749279121817889, + -0.22252093395646635, + -0.43388373911734746, + -0.9009688679025206 + ], + [ + -1.0229884175359286e-12, + 1.0, + -2.0459768350718573e-12, + 1.0, + -6.706944059699499e-12, + 1.0 + ], + [ + 0.7818314824679369, + 0.6234898018588501, + 0.9749279121818899, + -0.22252093395602376, + 0.43388373911632216, + -0.9009688679030143 + ], + [ + -0.4338837391165083, + -0.9009688679029247, + 0.7818314824665767, + 0.6234898018605556, + -0.9749279121810457, + -0.22252093395972247 + ], + [ + -0.9749279121817588, + -0.22252093395659842, + 0.43388373911808303, + -0.9009688679021663, + 0.7818314824663508, + 0.6234898018608389 + ], + [ + -0.7818314824676665, + 0.623489801859189, + -0.9749279121820829, + -0.22252093395517836, + -0.4338837391224106, + -0.9009688679000822 + ], + [ + -2.1814180061847215e-12, + 1.0, + -4.362836012369443e-12, + 1.0, + -1.087285807916595e-12, + 1.0 + ], + [ + 0.7818314824672146, + 0.6234898018597558, + 0.9749279121824055, + -0.222520933953765, + 0.4338837391178144, + -0.9009688679022957 + ], + [ + -0.43388373911710343, + -0.9009688679026381, + 0.7818314824674005, + 0.6234898018595226, + -0.9749279121806772, + -0.22252093396133724 + ], + [ + -0.9749279121819058, + -0.2225209339559544, + 0.43388373911689276, + -0.9009688679027396, + 0.7818314824698546, + 0.6234898018564453 + ], + [ + -0.7818314824683888, + 0.6234898018582834, + -0.9749279121815674, + -0.22252093395743713, + -0.43388373911436295, + -0.9009688679039578 + ], + [ + -1.5208581912876578e-12, + 1.0, + -3.0417163825753156e-12, + 1.0, + -1.0019542784500542e-11, + 1.0 + ], + [ + 0.7818314824676265, + 0.6234898018592393, + 0.9749279121821115, + -0.22252093395505299, + 0.4338837391193067, + -0.900968867901577 + ], + [ + -0.974927912181648, + -0.2225209339570838, + 0.43388373911898015, + -0.9009688679017344, + 0.781831482468822, + 0.6234898018577403 + ], + [ + -0.781831482467977, + 0.6234898018587998, + -0.9749279121818614, + -0.22252093395614914, + -0.43388373911942607, + -0.9009688679015195 + ], + [ + -8.602983763905941e-13, + 1.0, + -1.7205967527811881e-12, + 1.0, + -4.399884532717639e-12, + 1.0 + ], + [ + 0.7818314824680384, + 0.6234898018587228, + 0.9749279121818175, + -0.22252093395634098, + 0.433883739120799, + -0.9009688679008584 + ], + [ + -0.43388373911665484, + -0.9009688679028541, + 0.7818314824667797, + 0.6234898018603012, + -0.97492791217994, + -0.2225209339645668 + ], + [ + -0.974927912181795, + -0.2225209339564398, + 0.4338837391177899, + -0.9009688679023076, + 0.7818314824677892, + 0.6234898018590352 + ], + [ + -0.7818314824686993, + 0.6234898018578942, + -0.9749279121813458, + -0.2225209339584079, + -0.4338837391113784, + -0.9009688679053951 + ], + [ + -1.9973856149353036e-13, + 1.0, + -3.994771229870607e-13, + 1.0, + -6.0561838951181605e-12, + 1.0 + ], + [ + 0.781831482467316, + 0.6234898018596285, + 0.9749279121823331, + -0.2225209339540822, + 0.43388373911573586, + -0.9009688679032967 + ], + [ + -0.43388373911725, + -0.9009688679025675, + 0.7818314824676034, + 0.6234898018592683, + -0.9749279121811906, + -0.22252093395908804 + ], + [ + -0.974927912181942, + -0.2225209339557958, + 0.4338837391165996, + -0.9009688679028808, + 0.7818314824667566, + 0.6234898018603301 + ], + [ + -0.7818314824694215, + 0.6234898018569884, + -0.9749279121808302, + -0.2225209339606667, + -0.4338837391164415, + -0.9009688679029568 + ], + [ + -1.3581681501423231e-12, + 1.0, + -2.7163363002846463e-12, + 1.0, + -4.365256433352565e-13, + 1.0 + ], + [ + 0.7818314824677279, + 0.6234898018591121, + 0.9749279121820391, + -0.2225209339553702, + 0.43388373912378353, + -0.9009688678994211 + ], + [ + -0.43388373911784517, + -0.9009688679022809, + 0.781831482468427, + 0.6234898018582354, + -0.974927912180822, + -0.2225209339607028 + ], + [ + -0.9749279121816842, + -0.22252093395692518, + 0.433883739118687, + -0.9009688679018755, + 0.7818314824702604, + 0.6234898018559365 + ], + [ + -0.7818314824690097, + 0.6234898018575048, + -0.9749279121811242, + -0.2225209339593787, + -0.43388373911494926, + -0.9009688679036755 + ], + [ + -6.976083352452595e-13, + 1.0, + -1.395216670490519e-12, + 1.0, + 5.183132608447647e-12, + 1.0 + ], + [ + 0.7818314824681397, + 0.6234898018585957, + 0.9749279121817451, + -0.2225209339566582, + 0.43388373911872036, + -0.9009688679018594 + ], + [ + -0.43388373911680145, + -0.9009688679027835, + 0.7818314824669825, + 0.6234898018600468, + -0.9749279121820725, + -0.22252093395522404 + ], + [ + -0.9749279121818312, + -0.22252093395628117, + 0.4338837391174967, + -0.9009688679024487, + 0.7818314824646911, + 0.62348980186292 + ], + [ + -0.7818314824685978, + 0.6234898018580213, + -0.9749279121814182, + -0.2225209339580907, + -0.43388373911345696, + -0.9009688679043941 + ], + [ + -3.7048520348195737e-14, + 1.0, + -7.409704069639147e-14, + 1.0, + -3.7491243681363e-12, + 1.0 + ], + [ + 0.7818314824685516, + 0.6234898018580792, + 0.9749279121814511, + -0.2225209339579462, + 0.43388373912021266, + -0.9009688679011407 + ], + [ + -0.4338837391173966, + -0.900968867902497, + 0.7818314824678062, + 0.6234898018590139, + -0.974927912183323, + -0.2225209339497453 + ], + [ + -0.9749279121819782, + -0.22252093395563718, + 0.43388373911630645, + -0.9009688679030219, + 0.781831482468195, + 0.6234898018585264 + ], + [ + -0.7818314824681859, + 0.6234898018585378, + -0.9749279121817122, + -0.2225209339568027, + -0.4338837391119647, + -0.9009688679051128 + ], + [ + 0.7818314824678293, + 0.623489801858985, + 0.9749279121819667, + -0.22252093395568745, + 0.43388373911514955, + -0.900968867903579 + ], + [ + -0.4338837391179917, + -0.9009688679022103, + 0.7818314824686299, + 0.623489801857981, + -0.9749279121813353, + -0.22252093395845357 + ], + [ + -0.9749279121813157, + -0.22252093395853995, + 0.43388373912167155, + -0.9009688679004382, + 0.7818314824626258, + 0.62348980186551 + ], + [ + -0.7818314824689082, + 0.623489801857632, + -0.9749279121811966, + -0.22252093395906147, + -0.4338837391170278, + -0.9009688679026745 + ], + [ + -5.349182940999248e-13, + 1.0, + -1.0698365881998496e-12, + 1.0, + 2.1423452124608204e-13, + 1.0 + ], + [ + 0.7818314824682412, + 0.6234898018584685, + 0.9749279121816727, + -0.22252093395697542, + 0.4338837391100864, + -0.9009688679060174 + ], + [ + -0.433883739116948, + -0.9009688679027129, + 0.7818314824671854, + 0.6234898018597924, + -0.9749279121825859, + -0.22252093395297481 + ], + [ + -0.9749279121814626, + -0.22252093395789596, + 0.4338837391204813, + -0.9009688679010114, + 0.7818314824661297, + 0.6234898018611164 + ], + [ + -0.7818314824684963, + 0.6234898018581485, + -0.9749279121814906, + -0.22252093395777348, + -0.43388373911553557, + -0.9009688679033931 + ], + [ + 1.2564152079713888e-13, + 1.0, + 2.5128304159427777e-13, + 1.0, + -1.4420648411544397e-12, + 1.0 + ], + [ + 0.7818314824686531, + 0.623489801857952, + 0.9749279121813788, + -0.22252093395826342, + 0.43388373911813405, + -0.9009688679021418 + ], + [ + -0.43388373911754313, + -0.9009688679024264, + 0.7818314824680092, + 0.6234898018587595, + -0.9749279121822173, + -0.2225209339545896 + ], + [ + -0.9749279121816096, + -0.22252093395725195, + 0.43388373911929096, + -0.9009688679015846, + 0.7818314824650969, + 0.6234898018624112 + ], + [ + -0.7818314824680845, + 0.623489801858665, + -0.9749279121817845, + -0.22252093395648548, + -0.4338837391205987, + -0.9009688679009549 + ], + [ + 7.862013356942026e-13, + 1.0, + 1.5724026713884052e-12, + 1.0, + -3.0983642035549615e-12, + 1.0 + ], + [ + 0.7818314824667967, + 0.6234898018602799, + 0.9749279121827038, + -0.2225209339524579, + 0.4338837391261818, + -0.9009688678982662 + ], + [ + -0.4338837391181383, + -0.9009688679021397, + 0.7818314824688328, + 0.6234898018577266, + -0.9749279121818487, + -0.22252093395620437 + ], + [ + -0.9749279121817566, + -0.22252093395660796, + 0.4338837391181007, + -0.9009688679021578, + 0.7818314824640642, + 0.6234898018637062 + ], + [ + -0.7818314824688067, + 0.6234898018577593, + -0.9749279121812691, + -0.22252093395874423, + -0.433883739112551, + -0.9009688679048304 + ], + [ + -3.7222825295459016e-13, + 1.0, + -7.444565059091803e-13, + 1.0, + 2.5212940482279424e-12, + 1.0 + ], + [ + 0.7818314824672085, + 0.6234898018597634, + 0.9749279121824098, + -0.2225209339537459, + 0.4338837391211186, + -0.9009688679007045 + ], + [ + -0.43388373911545575, + -0.9009688679034316, + 0.78183148246512, + 0.6234898018623822, + -0.9749279121814801, + -0.22252093395781913 + ], + [ + -0.9749279121814989, + -0.22252093395773734, + 0.4338837391201881, + -0.9009688679011526, + 0.7818314824630316, + 0.6234898018650011 + ], + [ + -0.781831482468395, + 0.6234898018582757, + -0.9749279121815629, + -0.22252093395745623, + -0.43388373911761413, + -0.9009688679023922 + ], + [ + 2.8833156194247354e-13, + 1.0, + 5.766631238849471e-13, + 1.0, + 8.649946858274206e-13, + 1.0 + ], + [ + 0.7818314824676204, + 0.623489801859247, + 0.9749279121821158, + -0.2225209339550339, + 0.4338837391160555, + -0.9009688679031428 + ], + [ + -0.4338837391160509, + -0.900968867903145, + 0.7818314824659437, + 0.6234898018613494, + -0.9749279121811116, + -0.2225209339594339 + ], + [ + -0.9749279121816459, + -0.22252093395709335, + 0.4338837391189978, + -0.9009688679017258, + 0.7818314824665353, + 0.6234898018606075 + ], + [ + -0.7818314824679831, + 0.6234898018587921, + -0.9749279121818569, + -0.22252093395616823, + -0.4338837391161219, + -0.9009688679031108 + ], + [ + 9.488913768395372e-13, + 1.0, + 1.8977827536790744e-12, + 1.0, + 6.484652937610325e-12, + 1.0 + ], + [ + 0.781831482466898, + 0.6234898018601527, + 0.9749279121826314, + -0.2225209339527751, + 0.43388373911754774, + -0.9009688679024241 + ], + [ + -0.433883739116646, + -0.9009688679028584, + 0.7818314824667675, + 0.6234898018603166, + -0.974927912180743, + -0.2225209339610487 + ], + [ + -0.9749279121817928, + -0.22252093395644934, + 0.43388373911780753, + -0.900968867902299, + 0.7818314824700392, + 0.6234898018562139 + ], + [ + -0.7818314824675712, + 0.6234898018593086, + -0.9749279121821509, + -0.22252093395488026, + -0.4338837391146296, + -0.9009688679038295 + ], + [ + -2.028527615355112e-12, + 1.0, + -4.057055230710224e-12, + 1.0, + -9.723561653157049e-12, + 1.0 + ], + [ + 0.7818314824673099, + 0.6234898018596362, + 0.9749279121823374, + -0.2225209339540631, + 0.43388373911904005, + -0.9009688679017055 + ], + [ + -0.43388373911724115, + -0.9009688679025718, + 0.7818314824675912, + 0.6234898018592836, + -0.9749279121819935, + -0.22252093395556993 + ], + [ + -0.9749279121815351, + -0.22252093395757874, + 0.433883739119895, + -0.9009688679012937, + 0.7818314824690065, + 0.6234898018575088 + ], + [ + -0.7818314824682935, + 0.6234898018584029, + -0.9749279121816354, + -0.222520933957139, + -0.4338837391131373, + -0.9009688679045481 + ], + [ + -1.3679678004580483e-12, + 1.0, + -2.7359356009160965e-12, + 1.0, + -4.103903401374145e-12, + 1.0 + ], + [ + 0.7818314824677218, + 0.6234898018591197, + 0.9749279121820434, + -0.2225209339553511, + 0.4338837391205323, + -0.9009688679009868 + ], + [ + -0.9749279121816821, + -0.22252093395693473, + 0.43388373911870465, + -0.900968867901867, + 0.7818314824679737, + 0.6234898018588038 + ], + [ + -0.7818314824678816, + 0.6234898018589193, + -0.9749279121819294, + -0.222520933955851, + -0.43388373911820044, + -0.9009688679021098 + ], + [ + -7.074079855609846e-13, + 1.0, + -1.4148159711219692e-12, + 1.0, + -5.760202763774667e-12, + 1.0 + ], + [ + 0.7818314824681336, + 0.6234898018586034, + 0.9749279121817495, + -0.2225209339566391, + 0.4338837391154692, + -0.9009688679034251 + ], + [ + -0.4338837391167926, + -0.9009688679027877, + 0.7818314824669703, + 0.6234898018600621, + -0.9749279121812564, + -0.22252093395879946 + ], + [ + -0.9749279121818291, + -0.22252093395629075, + 0.4338837391175144, + -0.9009688679024402, + 0.7818314824669411, + 0.6234898018600987 + ], + [ + -0.7818314824674698, + 0.6234898018594358, + -0.9749279121822233, + -0.22252093395456302, + -0.4338837391232636, + -0.9009688678996716 + ], + [ + -1.8658375742097774e-12, + 1.0, + -3.731675148419555e-12, + 1.0, + -1.4054451199176275e-13, + 1.0 + ], + [ + 0.7818314824674114, + 0.6234898018595091, + 0.974927912182265, + -0.22252093395438033, + 0.43388373912351685, + -0.9009688678995496 + ], + [ + -0.43388373911738776, + -0.9009688679025012, + 0.781831482467794, + 0.6234898018590292, + -0.9749279121808878, + -0.22252093396041422 + ], + [ + -0.9749279121819759, + -0.22252093395564673, + 0.4338837391163241, + -0.9009688679030134, + 0.7818314824704449, + 0.6234898018557051 + ], + [ + -0.7818314824693262, + 0.6234898018571079, + -0.9749279121808982, + -0.22252093396036857, + -0.43388373911521594, + -0.900968867903547 + ], + [ + -1.2052777593127138e-12, + 1.0, + -2.4105555186254275e-12, + 1.0, + -1.7968438743922846e-12, + 1.0 + ], + [ + 0.7818314824678232, + 0.6234898018589926, + 0.9749279121819711, + -0.22252093395566833, + 0.43388373911845374, + -0.9009688679019878 + ], + [ + -0.43388373911634404, + -0.9009688679030038, + 0.7818314824663495, + 0.6234898018608406, + -0.9749279121821384, + -0.22252093395493547 + ], + [ + -0.9749279121817183, + -0.22252093395677613, + 0.4338837391184115, + -0.9009688679020081, + 0.7818314824648758, + 0.6234898018626887 + ], + [ + -0.7818314824689143, + 0.6234898018576244, + -0.9749279121811922, + -0.22252093395908057, + -0.4338837391071682, + -0.9009688679074226 + ], + [ + -5.4471794441565e-13, + 1.0, + -1.0894358888313e-12, + 1.0, + -3.4531432367928064e-12, + 1.0 + ], + [ + 0.7818314824682351, + 0.6234898018584761, + 0.9749279121816771, + -0.22252093395695632, + 0.433883739119946, + -0.9009688679012692 + ], + [ + -0.43388373911693917, + -0.9009688679027172, + 0.7818314824671732, + 0.6234898018598077, + -0.9749279121817698, + -0.22252093395655026 + ], + [ + -0.9749279121818653, + -0.22252093395613212, + 0.4338837391172212, + -0.9009688679025813, + 0.7818314824683795, + 0.6234898018582951 + ], + [ + -0.7818314824685024, + 0.6234898018581408, + -0.9749279121814862, + -0.22252093395779257, + -0.4338837391122314, + -0.9009688679049843 + ], + [ + 1.158418704814137e-13, + 1.0, + 2.316837409628274e-13, + 1.0, + -5.109442599193328e-12, + 1.0 + ], + [ + 0.7818314824675128, + 0.6234898018593819, + 0.9749279121821927, + -0.22252093395469755, + 0.43388373911488287, + -0.9009688679037074 + ], + [ + -0.4338837391175343, + -0.9009688679024306, + 0.7818314824679968, + 0.6234898018587748, + -0.9749279121814012, + -0.22252093395816502 + ], + [ + -0.9749279121820122, + -0.22252093395548814, + 0.43388373911603095, + -0.9009688679031546, + 0.7818314824673468, + 0.6234898018595899 + ], + [ + -0.7818314824692247, + 0.6234898018572351, + -0.9749279121809706, + -0.22252093396005135, + -0.4338837391172945, + -0.900968867902546 + ], + [ + -1.042587718167379e-12, + 1.0, + -2.085175436334758e-12, + 1.0, + 5.102156525895758e-13, + 1.0 + ], + [ + 0.7818314824679247, + 0.6234898018588654, + 0.9749279121818987, + -0.22252093395598554, + 0.4338837391163751, + -0.9009688679029888 + ], + [ + -0.4338837391181295, + -0.900968867902144, + 0.7818314824688206, + 0.6234898018577419, + -0.9749279121810327, + -0.2225209339597798 + ], + [ + -0.9749279121817545, + -0.2225209339566175, + 0.43388373911811834, + -0.9009688679021494, + 0.7818314824708507, + 0.6234898018551963 + ], + [ + -0.7818314824688128, + 0.6234898018577516, + -0.9749279121812646, + -0.22252093395876335, + -0.43388373911580225, + -0.9009688679032647 + ], + [ + -3.8202790327031534e-13, + 1.0, + -7.640558065406307e-13, + 1.0, + -8.422041323994371e-12, + 1.0 + ], + [ + 0.7818314824683366, + 0.6234898018583489, + 0.9749279121816047, + -0.22252093395727354, + 0.4338837391178674, + -0.9009688679022702 + ], + [ + -0.4338837391170858, + -0.9009688679026466, + 0.781831482467376, + 0.6234898018595533, + -0.9749279121822831, + -0.22252093395430103 + ], + [ + -0.9749279121814967, + -0.22252093395774689, + 0.4338837391202058, + -0.900968867901144, + 0.7818314824652814, + 0.6234898018621798 + ], + [ + -0.7818314824684011, + 0.6234898018582681, + -0.9749279121815586, + -0.22252093395747535, + -0.43388373912086536, + -0.9009688679008264 + ], + [ + 2.7853191162674836e-13, + 1.0, + 5.570638232534967e-13, + 1.0, + -2.802383072211468e-12, + 1.0 + ], + [ + 0.7818314824687483, + 0.6234898018578325, + 0.9749279121813107, + -0.22252093395856154, + 0.4338837391193597, + -0.9009688679015515 + ], + [ + -0.4338837391176809, + -0.90096886790236, + 0.7818314824681998, + 0.6234898018585204, + -0.9749279121802955, + -0.22252093396300934 + ], + [ + -0.9749279121816437, + -0.2225209339571029, + 0.43388373911901545, + -0.9009688679017173, + 0.7818314824642488, + 0.6234898018634748 + ], + [ + -0.7818314824679892, + 0.6234898018587844, + -0.9749279121818526, + -0.22252093395618736, + -0.4338837391128177, + -0.900968867904702 + ], + [ + -8.798976770220444e-13, + 1.0, + -1.7597953540440888e-12, + 1.0, + 2.817275179571436e-12, + 1.0 + ], + [ + 0.7818314824668919, + 0.6234898018601603, + 0.9749279121826357, + -0.22252093395275602, + 0.43388373912085193, + -0.9009688679008329 + ], + [ + -0.43388373911827605, + -0.9009688679020734, + 0.7818314824690235, + 0.6234898018574876, + -0.9749279121815461, + -0.2225209339575306 + ], + [ + -0.9749279121813859, + -0.22252093395823228, + 0.4338837391211029, + -0.9009688679007121, + 0.7818314824632161, + 0.6234898018647698 + ], + [ + -0.7818314824687115, + 0.6234898018578787, + -0.974927912181337, + -0.22252093395844613, + -0.4338837391178808, + -0.9009688679022637 + ], + [ + -2.1933786212498073e-13, + 1.0, + -4.3867572424996146e-13, + 1.0, + 1.1609758171709142e-12, + 1.0 + ], + [ + 0.7818314824673038, + 0.6234898018596439, + 0.9749279121823418, + -0.22252093395404401, + 0.43388373912234424, + -0.9009688679001142 + ], + [ + -0.4338837391172323, + -0.900968867902576, + 0.7818314824675789, + 0.6234898018592989, + -0.9749279121827965, + -0.2225209339520518 + ], + [ + -0.9749279121815329, + -0.2225209339575883, + 0.4338837391199126, + -0.9009688679012853, + 0.7818314824667199, + 0.6234898018603761 + ], + [ + -0.7818314824682996, + 0.6234898018583952, + -0.974927912181631, + -0.22252093395715813, + -0.43388373911638856, + -0.9009688679029824 + ], + [ + 4.41221952772083e-13, + 1.0, + 8.82443905544166e-13, + 1.0, + 6.7806340689538185e-12, + 1.0 + ], + [ + 0.7818314824677157, + 0.6234898018591274, + 0.9749279121820479, + -0.222520933955332, + 0.43388373911728106, + -0.9009688679025525 + ], + [ + -0.43388373911618866, + -0.9009688679030786, + 0.7818314824661344, + 0.6234898018611104, + -0.9749279121808089, + -0.22252093396076011 + ], + [ + -0.9749279121816798, + -0.22252093395694428, + 0.4338837391187223, + -0.9009688679018585, + 0.7818314824656872, + 0.623489801861671 + ], + [ + -0.7818314824678877, + 0.6234898018589117, + -0.974927912181925, + -0.22252093395587014, + -0.43388373911489625, + -0.900968867903701 + ], + [ + 1.1017817676691467e-12, + 1.0, + 2.2035635353382935e-12, + 1.0, + -2.1516229076301294e-12, + 1.0 + ], + [ + 0.7818314824669934, + 0.6234898018600331, + 0.9749279121825634, + -0.22252093395307324, + 0.4338837391253288, + -0.900968867898677 + ], + [ + -0.4338837391167838, + -0.9009688679027921, + 0.7818314824669581, + 0.6234898018600774, + -0.9749279121820594, + -0.22252093395528136 + ], + [ + -0.9749279121818268, + -0.2225209339563003, + 0.43388373911753203, + -0.9009688679024317, + 0.781831482469191, + 0.6234898018572774 + ], + [ + -0.78183148246861, + 0.623489801858006, + -0.9749279121814095, + -0.2225209339581289, + -0.433883739113404, + -0.9009688679044197 + ], + [ + 0.7818314824674053, + 0.6234898018595167, + 0.9749279121822694, + -0.22252093395436123, + 0.4338837391202656, + -0.9009688679011153 + ], + [ + -0.4338837391157401, + -0.9009688679032947, + 0.7818314824655136, + 0.6234898018618888, + -0.9749279121800718, + -0.22252093396398967 + ], + [ + -0.974927912181569, + -0.22252093395742967, + 0.43388373911961947, + -0.9009688679014265, + 0.7818314824636219, + 0.623489801864261 + ], + [ + -0.7818314824681981, + 0.6234898018585224, + -0.9749279121817034, + -0.22252093395684092, + -0.4338837391184671, + -0.9009688679019814 + ], + [ + -1.2150774096284389e-12, + 1.0, + -2.4301548192568778e-12, + 1.0, + -5.464221632431173e-12, + 1.0 + ], + [ + 0.7818314824678171, + 0.6234898018590003, + 0.9749279121819754, + -0.22252093395564923, + 0.4338837391152025, + -0.9009688679035536 + ], + [ + -0.4338837391163352, + -0.900968867903008, + 0.7818314824663373, + 0.6234898018608559, + -0.9749279121813222, + -0.2225209339585109 + ], + [ + -0.974927912181716, + -0.22252093395678568, + 0.43388373911842915, + -0.9009688679019997, + 0.7818314824671256, + 0.6234898018598674 + ], + [ + -0.7818314824677863, + 0.6234898018590389, + -0.9749279121819974, + -0.22252093395555292, + -0.43388373911697486, + -0.9009688679027 + ], + [ + -5.545175947313751e-13, + 1.0, + -1.1090351894627503e-12, + 1.0, + 1.55436619351731e-13, + 1.0 + ], + [ + 0.7818314824670949, + 0.623489801859906, + 0.974927912182491, + -0.22252093395339045, + 0.4338837391232502, + -0.900968867899678 + ], + [ + -0.43388373911693034, + -0.9009688679027215, + 0.7818314824671609, + 0.6234898018598231, + -0.9749279121809538, + -0.22252093396012568 + ], + [ + -0.974927912181863, + -0.22252093395614167, + 0.4338837391172389, + -0.9009688679025729, + 0.7818314824706294, + 0.6234898018554736 + ], + [ + -0.7818314824673744, + 0.6234898018595553, + -0.9749279121822914, + -0.22252093395426492, + -0.433883739122038, + -0.9009688679002618 + ], + [ + -1.7129471833801679e-12, + 1.0, + -3.4258943667603357e-12, + 1.0, + -1.5008627430487909e-12, + 1.0 + ], + [ + 0.7818314824675067, + 0.6234898018593895, + 0.974927912182197, + -0.22252093395467845, + 0.43388373911818706, + -0.9009688679021163 + ], + [ + -0.4338837391175255, + -0.9009688679024348, + 0.7818314824679846, + 0.6234898018587901, + -0.9749279121822042, + -0.22252093395464692 + ], + [ + -0.9749279121816052, + -0.22252093395727107, + 0.4338837391193263, + -0.9009688679015676, + 0.7818314824650603, + 0.6234898018624572 + ], + [ + -1.0523873684831042e-12, + 1.0, + -2.1047747369662084e-12, + 1.0, + -3.1571621054493126e-12, + 1.0 + ], + [ + 0.7818314824679186, + 0.623489801858873, + 0.974927912181903, + -0.22252093395596645, + 0.4338837391196793, + -0.9009688679013976 + ], + [ + -0.4338837391164818, + -0.9009688679029375, + 0.7818314824665401, + 0.6234898018606015, + -0.9749279121818356, + -0.22252093395626169 + ], + [ + -0.9749279121817522, + -0.22252093395662706, + 0.433883739118136, + -0.9009688679021408, + 0.781831482468564, + 0.6234898018580636 + ], + [ + -3.918275535860405e-13, + 1.0, + -7.83655107172081e-13, + 1.0, + -4.813461467849834e-12, + 1.0 + ], + [ + 0.7818314824683303, + 0.6234898018583566, + 0.974927912181609, + -0.22252093395725445, + 0.4338837391146162, + -0.9009688679038359 + ], + [ + -0.43388373911707695, + -0.9009688679026508, + 0.7818314824673638, + 0.6234898018595686, + -0.9749279121814671, + -0.22252093395787645 + ], + [ + -0.9749279121818992, + -0.22252093395598307, + 0.4338837391169457, + -0.900968867902714, + 0.7818314824675314, + 0.6234898018593585 + ], + [ + -0.7818314824684072, + 0.6234898018582604, + -0.9749279121815543, + -0.22252093395749445, + -0.43388373911100575, + -0.9009688679055746 + ], + [ + -1.5502571422348334e-12, + 1.0, + -3.1005142844696668e-12, + 1.0, + 8.061967839330695e-13, + 1.0 + ], + [ + 0.7818314824676081, + 0.6234898018592623, + 0.9749279121821246, + -0.22252093395499567, + 0.43388373911610845, + -0.9009688679031173 + ], + [ + -0.4338837391176721, + -0.9009688679023643, + 0.7818314824681876, + 0.6234898018585358, + -0.9749279121810985, + -0.22252093395949124 + ], + [ + -0.9749279121820462, + -0.22252093395533906, + 0.43388373911575545, + -0.9009688679032872, + 0.7818314824710352, + 0.6234898018549649 + ], + [ + -0.7818314824691294, + 0.6234898018573547, + -0.9749279121810387, + -0.22252093395975323, + -0.4338837391160689, + -0.9009688679031364 + ], + [ + -8.896973273377696e-13, + 1.0, + -1.7793946546755393e-12, + 1.0, + -8.126060192650879e-12, + 1.0 + ], + [ + 0.78183148246802, + 0.6234898018587458, + 0.9749279121818306, + -0.22252093395628367, + 0.43388373911760075, + -0.9009688679023986 + ], + [ + -0.9749279121817884, + -0.22252093395646846, + 0.43388373911784284, + -0.900968867902282, + 0.7818314824700024, + 0.6234898018562599 + ], + [ + -0.7818314824687176, + 0.6234898018578711, + -0.9749279121813327, + -0.22252093395846523, + -0.43388373912113204, + -0.900968867900698 + ], + [ + -2.291375124407059e-13, + 1.0, + -4.582750248814118e-13, + 1.0, + -2.5064019408679743e-12, + 1.0 + ], + [ + 0.7818314824684318, + 0.6234898018582294, + 0.9749279121815366, + -0.22252093395757166, + 0.433883739119093, + -0.90096886790168 + ], + [ + -0.4338837391172235, + -0.9009688679025802, + 0.7818314824675667, + 0.6234898018593142, + -0.9749279121803613, + -0.22252093396272077 + ], + [ + -0.9749279121815306, + -0.22252093395759784, + 0.4338837391199303, + -0.9009688679012767, + 0.7818314824644333, + 0.6234898018632434 + ], + [ + -0.7818314824683057, + 0.6234898018583875, + -0.9749279121816267, + -0.22252093395717723, + -0.43388373911308437, + -0.9009688679045735 + ], + [ + 4.314223024563578e-13, + 1.0, + 8.628446049127156e-13, + 1.0, + -4.162701303268496e-12, + 1.0 + ], + [ + 0.7818314824677096, + 0.623489801859135, + 0.9749279121820522, + -0.2225209339553129, + 0.4338837391140299, + -0.9009688679041182 + ], + [ + -0.43388373911781863, + -0.9009688679022937, + 0.7818314824683904, + 0.6234898018582814, + -0.9749279121816119, + -0.222520933957242 + ], + [ + -0.9749279121816776, + -0.22252093395695385, + 0.43388373911874, + -0.9009688679018499, + 0.7818314824634006, + 0.6234898018645383 + ], + [ + -0.781831482469028, + 0.6234898018574818, + -0.9749279121811111, + -0.222520933959436, + -0.4338837391181475, + -0.9009688679021353 + ], + [ + -7.27007286192435e-13, + 1.0, + -1.45401457238487e-12, + 1.0, + 1.456956948514408e-12, + 1.0 + ], + [ + 0.7818314824681214, + 0.6234898018586187, + 0.9749279121817582, + -0.22252093395660089, + 0.43388373912207756, + -0.9009688679002427 + ], + [ + -0.4338837391184138, + -0.900968867902007, + 0.7818314824692141, + 0.6234898018572484, + -0.9749279121812433, + -0.22252093395885678 + ], + [ + -0.9749279121814198, + -0.22252093395808323, + 0.4338837391208274, + -0.9009688679008447, + 0.7818314824669045, + 0.6234898018601447 + ], + [ + -0.7818314824686161, + 0.6234898018579983, + -0.9749279121814051, + -0.222520933958148, + -0.43388373911665523, + -0.9009688679028539 + ], + [ + -6.644747129537127e-14, + 1.0, + -1.3289494259074255e-13, + 1.0, + 7.076615200297312e-12, + 1.0 + ], + [ + 0.7818314824673992, + 0.6234898018595244, + 0.9749279121822738, + -0.2225209339543421, + 0.4338837391170144, + -0.9009688679026809 + ], + [ + -0.9749279121815668, + -0.22252093395743924, + 0.4338837391196371, + -0.900968867901418, + 0.7818314824658718, + 0.6234898018614397 + ], + [ + -0.7818314824682042, + 0.6234898018585148, + -0.974927912181699, + -0.22252093395686, + -0.4338837391151629, + -0.9009688679035726 + ], + [ + 5.941123436016925e-13, + 1.0, + 1.188224687203385e-12, + 1.0, + -1.8556417762866356e-12, + 1.0 + ], + [ + 0.7818314824666769, + 0.62348980186043, + 0.9749279121827893, + -0.22252093395208333, + 0.4338837391250621, + -0.9009688678988054 + ], + [ + -0.43388373911796524, + -0.9009688679022231, + 0.7818314824685932, + 0.6234898018580269, + -0.9749279121837443, + -0.22252093394789926 + ], + [ + -0.9749279121817138, + -0.22252093395679523, + 0.4338837391184468, + -0.9009688679019912, + 0.7818314824693755, + 0.623489801857046 + ], + [ + -0.7818314824677924, + 0.6234898018590312, + -0.974927912181993, + -0.22252093395557201, + -0.4338837391136707, + -0.9009688679042912 + ], + [ + -5.643172450471004e-13, + 1.0, + -1.1286344900942007e-12, + 1.0, + 3.764016475496268e-12, + 1.0 + ], + [ + 0.7818314824670888, + 0.6234898018599137, + 0.9749279121824953, + -0.22252093395337133, + 0.43388373911999895, + -0.9009688679012436 + ], + [ + -0.4338837391169215, + -0.9009688679027257, + 0.7818314824671487, + 0.6234898018598384, + -0.9749279121801376, + -0.2225209339637011 + ], + [ + -0.9749279121814561, + -0.2225209339579246, + 0.43388373912053424, + -0.9009688679009858, + 0.7818314824638064, + 0.6234898018640296 + ], + [ + -0.7818314824685146, + 0.6234898018581255, + -0.9749279121814775, + -0.2225209339578308, + -0.4338837391187338, + -0.9009688679018529 + ], + [ + 9.624256984996336e-14, + 1.0, + 1.9248513969992671e-13, + 1.0, + 2.1077171130957467e-12, + 1.0 + ], + [ + 0.7818314824675006, + 0.6234898018593972, + 0.9749279121822013, + -0.22252093395465933, + 0.43388373912149125, + -0.900968867900525 + ], + [ + -0.4338837391158778, + -0.9009688679032283, + 0.7818314824657042, + 0.6234898018616497, + -0.974927912179769, + -0.2225209339653159 + ], + [ + -0.9749279121816031, + -0.22252093395728062, + 0.43388373911934397, + -0.9009688679015592, + 0.7818314824673102, + 0.6234898018596359 + ], + [ + -0.7818314824681029, + 0.623489801858642, + -0.9749279121817714, + -0.2225209339565428, + -0.43388373911724154, + -0.9009688679025716 + ], + [ + -1.0621870187988293e-12, + 1.0, + -2.1243740375976587e-12, + 1.0, + 4.5141775069522473e-13, + 1.0 + ], + [ + 0.7818314824679125, + 0.6234898018588807, + 0.9749279121819074, + -0.22252093395594733, + 0.4338837391229835, + -0.9009688678998063 + ], + [ + -0.433883739116473, + -0.9009688679029417, + 0.7818314824665279, + 0.6234898018606169, + -0.9749279121810196, + -0.22252093395983713 + ], + [ + -0.97492791218175, + -0.2225209339566366, + 0.43388373911815364, + -0.9009688679021324, + 0.7818314824662775, + 0.6234898018609308 + ], + [ + -0.781831482467691, + 0.6234898018591584, + -0.9749279121820654, + -0.2225209339552548, + -0.43388373912230466, + -0.9009688679001333 + ], + [ + -2.2206166074476224e-12, + 1.0, + -4.441233214895245e-12, + 1.0, + -1.204881611705297e-12, + 1.0 + ], + [ + 0.7818314824671901, + 0.6234898018597864, + 0.9749279121824229, + -0.22252093395368858, + 0.4338837391244758, + -0.9009688678990877 + ], + [ + -0.4338837391170681, + -0.9009688679026551, + 0.7818314824673516, + 0.6234898018595839, + -0.97492791218227, + -0.22252093395435835 + ], + [ + -0.974927912181897, + -0.22252093395599262, + 0.4338837391169634, + -0.9009688679027056, + 0.7818314824652448, + 0.6234898018622258 + ], + [ + -0.7818314824684133, + 0.6234898018582528, + -0.97492791218155, + -0.22252093395751357, + -0.433883739114257, + -0.9009688679040089 + ], + [ + -1.5600567925505585e-12, + 1.0, + -3.120113585101117e-12, + 1.0, + -2.861180974105819e-12, + 1.0 + ], + [ + 0.781831482467602, + 0.6234898018592699, + 0.9749279121821289, + -0.22252093395497657, + 0.43388373911941264, + -0.9009688679015261 + ], + [ + -0.4338837391160244, + -0.9009688679031578, + 0.7818314824659071, + 0.6234898018613954, + -0.9749279121819014, + -0.22252093395597314 + ], + [ + -0.9749279121816393, + -0.222520933957122, + 0.4338837391190508, + -0.9009688679017003, + 0.7818314824642121, + 0.6234898018635208 + ], + [ + -0.7818314824680014, + 0.6234898018587691, + -0.9749279121818439, + -0.22252093395622558, + -0.4338837391193201, + -0.9009688679015706 + ], + [ + -8.994969776534948e-13, + 1.0, + -1.7989939553069895e-12, + 1.0, + -4.5174803365063404e-12, + 1.0 + ], + [ + 0.7818314824680138, + 0.6234898018587535, + 0.9749279121818349, + -0.22252093395626454, + 0.4338837391143495, + -0.9009688679039644 + ], + [ + -0.43388373911661954, + -0.9009688679028711, + 0.7818314824667307, + 0.6234898018603625, + -0.974927912181533, + -0.2225209339575879 + ], + [ + -0.9749279121817863, + -0.222520933956478, + 0.4338837391178605, + -0.9009688679022735, + 0.7818314824677159, + 0.6234898018591272 + ], + [ + -0.7818314824675896, + 0.6234898018592856, + -0.9749279121821378, + -0.22252093395493758, + -0.43388373911782785, + -0.9009688679022892 + ], + [ + -2.389371627564311e-13, + 1.0, + -4.778743255128622e-13, + 1.0, + 1.1021779152765633e-12, + 1.0 + ], + [ + 0.7818314824672916, + 0.6234898018596592, + 0.9749279121823505, + -0.2225209339540058, + 0.43388373911584177, + -0.9009688679032457 + ], + [ + -0.4338837391172147, + -0.9009688679025846, + 0.7818314824675545, + 0.6234898018593296, + -0.9749279121811644, + -0.22252093395920267 + ], + [ + -0.9749279121819332, + -0.222520933955834, + 0.4338837391166702, + -0.9009688679028467, + 0.7818314824712197, + 0.6234898018547335 + ], + [ + -0.7818314824694459, + 0.6234898018569578, + -0.9749279121808128, + -0.2225209339607431, + -0.43388373911633554, + -0.9009688679030079 + ] + ]; + const xTransposed = x.reduce(($, row) => row.map((_, i) => [...($[i] || []), row[i]]), []).flat(); + const data = { + n: 480, + s: 25, + k: 6, + tau: 0.05, + sigmas: new Float64Array(Array(6).fill(10.0)), + trendIndicator: 'linear', + cap: new Float64Array(Array(480).fill(0.0)), + sA: new Int32Array(Array(6).fill(1)), + sM: new Int32Array(Array(6).fill(0)), + y: new Float64Array([ + 0.5307510759405802, + 0.4724420380397057, + 0.43037623212550324, + 0.4442593363876163, + 0.45855893377759266, + 0.4430098570040261, + 0.40038872691933913, + 0.3913647091489657, + 0.41093988615854504, + 0.3848396501457726, + 0.3734555046508399, + 0.35915590726086355, + 0.3722060252672497, + 0.3652644731361932, + 0.3762321255032625, + 0.37498264611967236, + 0.3803970567818964, + 0.37859225322782175, + 0.392753019575177, + 0.4166319589060114, + 0.4360683048729696, + 0.4430098570040261, + 0.43870609468277105, + 0.4420380397056782, + 0.4588365958628349, + 0.4450923226433431, + 0.4595307510759406, + 0.4474524503679022, + 0.43537414965986393, + 0.4317645425517146, + 0.42718311814521726, + 0.43315285297792583, + 0.43690129112869636, + 0.44051089823684575, + 0.4466194641121755, + 0.43690129112869636, + 0.42995973899763984, + 0.42773844231570174, + 0.4264889629321116, + 0.39219769540469246, + 0.3899763987227544, + 0.40413716507010966, + 0.40261002360127723, + 0.39927807857837017, + 0.399139247535749, + 0.3949743162571151, + 0.40733027905039565, + 0.3727613494377343, + 0.32916840205469944, + 0.3213938636679161, + 0.30140219353047343, + 0.2898792169929196, + 0.2782174094127447, + 0.29279466888796335, + 0.30431764542551715, + 0.28765792031098153, + 0.28765792031098153, + 0.2916840205469943, + 0.30279050395668466, + 0.299875052061641, + 0.2829376648618631, + 0.2943218103567958, + 0.27585728168818546, + 0.2644731361932528, + 0.2778009162848813, + 0.2660002776620852, + 0.2698875468554769, + 0.2698875468554769, + 0.2694710537276135, + 0.2658614466194641, + 0.2684992364292656, + 0.2651672914063585, + 0.26502846036373734, + 0.2507288629737609, + 0.24614743856726365, + 0.2579480771900597, + 0.26322365680966264, + 0.2635013188949049, + 0.2611411911703457, + 0.26974871581285575, + 0.29057337220602525, + 0.2875190892683604, + 0.30542829376648617, + 0.2987644037206719, + 0.30362349021241153, + 0.32333749826461194, + 0.31361932528113284, + 0.31736776343190337, + 0.2886297376093294, + 0.2815493544356518, + 0.28626960988477024, + 0.2821046786061363, + 0.30070803831736775, + 0.30528946272386503, + 0.3091767319172567, + 0.30306816604192693, + 0.3047341385533805, + 0.290295710120783, + 0.28321532694710533, + 0.28085519922254615, + 0.2726641677078995, + 0.2741913091767319, + 0.2709981951964459, + 0.2709981951964459, + 0.27044287102596143, + 0.2759961127308066, + 0.2635013188949049, + 0.2637789809801472, + 0.26822157434402333, + 0.27072053311120364, + 0.3225045120088852, + 0.31320283215326944, + 0.3045953075107594, + 0.2930723309732056, + 0.2944606413994169, + 0.2940441482715535, + 0.29501596556990145, + 0.29390531722893243, + 0.28418714424545327, + 0.277523254199639, + 0.2666944328751909, + 0.2786339025406081, + 0.27571845064556433, + 0.31042621130084685, + 0.3077884214910454, + 0.32708593641538247, + 0.3182007496876302, + 0.3206997084548105, + 0.3376370956545884, + 0.3331945022907122, + 0.36012772455921144, + 0.36304317645425516, + 0.3659586283492989, + 0.37928640844092737, + 0.38872691933916426, + 0.3753991392475357, + 0.3812300430376232, + 0.38470081910315146, + 0.3744273219491878, + 0.38164653616548655, + 0.38650562265722616, + 0.388449257253922, + 0.38289601554907676, + 0.3920588643620713, + 0.3722060252672497, + 0.37137303901152297, + 0.38470081910315146, + 0.3805358878245176, + 0.3798417326114119, + 0.36457031792308764, + 0.37387199777870334, + 0.3680410939886159, + 0.36165486602804386, + 0.35971123143134803, + 0.36956823545744827, + 0.38872691933916426, + 0.3855338053588782, + 0.39927807857837017, + 0.4084409273913647, + 0.403443009857004, + 0.42468415937803694, + 0.4345411634041372, + 0.4403720671942246, + 0.42968207691239757, + 0.41788143828960156, + 0.4144106622240733, + 0.4184367624600861, + 0.41177287241427185, + 0.42662779397473277, + 0.42787727335832293, + 0.43148688046647227, + 0.43787310842704424, + 0.4507843953908094, + 0.4274607802304595, + 0.43370817714841037, + 0.430098570040261, + 0.41274468971261974, + 0.39025406080799663, + 0.39761210606691655, + 0.4033041788143829, + 0.3977509371095377, + 0.3963626266833264, + 0.39233652644731365, + 0.37998056365403304, + 0.38747743995557404, + 0.3956684714702207, + 0.3931695127030404, + 0.40163820630292935, + 0.39511314729973623, + 0.3787310842704429, + 0.3766486186311259, + 0.37859225322782175, + 0.3802582257392753, + 0.3730390115229765, + 0.3783145911425795, + 0.3856726364014994, + 0.3848396501457726, + 0.38206302929334995, + 0.38109121199500207, + 0.39677911981118974, + 0.3881715951686797, + 0.3906705539358601, + 0.386366791614605, + 0.37595446341802025, + 0.3753991392475357, + 0.3699847285853117, + 0.36776343190337357, + 0.3685964181591004, + 0.35901707621824236, + 0.3573511037067888, + 0.3572122726641677, + 0.3488824101068999, + 0.34999305844786893, + 0.3622101901985284, + 0.35512980702485075, + 0.35443565181174513, + 0.3529085103429127, + 0.36443148688046645, + 0.3758156323753991, + 0.3802582257392753, + 0.3727613494377343, + 0.36915174232958486, + 0.3827571845064556, + 0.38900458142440647, + 0.3803970567818964, + 0.368179925031237, + 0.3737331667360822, + 0.3697070665000694, + 0.3566569484936832, + 0.3572122726641677, + 0.3605442176870748, + 0.360683048729696, + 0.3624878522837706, + 0.362904345411634, + 0.3727613494377343, + 0.37456615299180895, + 0.3855338053588782, + 0.3808135499097598, + 0.40219353047341383, + 0.39303068166041927, + 0.3827571845064556, + 0.3733166736082188, + 0.3765097875885048, + 0.3753991392475357, + 0.3704012217131751, + 0.3723448563098709, + 0.3758156323753991, + 0.36929057337220605, + 0.3627655143690129, + 0.36443148688046645, + 0.3576287657920311, + 0.3562404553658198, + 0.3492989032347633, + 0.34791059280855197, + 0.3374982646119672, + 0.33458281271692353, + 0.32375399139247535, + 0.34083020963487437, + 0.3380535887824518, + 0.33111203665139527, + 0.32653061224489793, + 0.31792308760238785, + 0.3188949049007358, + 0.32333749826461194, + 0.33777592669720946, + 0.3336109954185756, + 0.3300013883104262, + 0.3294460641399417, + 0.32805775371373036, + 0.33347216437595445, + 0.33610995418575595, + 0.3374982646119672, + 0.3318061918645009, + 0.3405525475496321, + 0.3323615160349854, + 0.33666527835624044, + 0.3354157989726503, + 0.3423573511037068, + 0.34541163404137165, + 0.3444398167430237, + 0.33888657503817854, + 0.34041371650701097, + 0.338331250867694, + 0.34305150631681247, + 0.35374149659863946, + 0.3581840899625156, + 0.35832292100513674, + 0.35971123143134803, + 0.36484798000832985, + 0.3654033041788144, + 0.3699847285853117, + 0.36345966958211856, + 0.35929473830348463, + 0.36165486602804386, + 0.3627655143690129, + 0.3680410939886159, + 0.477023462446203, + 0.47216437595446337, + 0.4918783840066639, + 0.5224212133833125, + 0.5108982368457586, + 0.5204775787866167, + 0.5282521171733999, + 0.5440788560322087, + 0.5351936693044564, + 0.5396362626683326, + 0.5350548382618353, + 0.5344995140913508, + 0.5306122448979591, + 0.5139525197834236, + 0.5088157712064417, + 0.5075662918228516, + 0.5147855060391503, + 0.5249201721504929, + 0.5332500347077606, + 0.5320005553241705, + 0.5351936693044564, + 0.5629598778286824, + 0.5739275301957518, + 0.5503262529501597, + 0.5629598778286824, + 0.573094543940025, + 0.5732333749826461, + 0.5812855754546716, + 0.5800360960710815, + 0.5922532278217408, + 0.6101624323198668, + 0.6114119117034569, + 0.6053033458281272, + 0.6252950159655699, + 0.6212689157295571, + 0.6151603498542274, + 0.5901707621824239, + 0.6257115090934333, + 0.6279328057753714, + 0.638345133971956, + 0.6593086214077468, + 0.6551436901291128, + 0.6726364014993753, + 0.6866583368041094, + 0.6995696237678745, + 0.7113702623906706, + 0.6973483270859364, + 0.6999861168957379, + 0.6980424822990421, + 0.6827710676107177, + 0.7085936415382479, + 0.7013744273219492, + 0.6544495349160072, + 0.6493127863390254, + 0.6809662640566431, + 0.6817992503123699, + 0.687352492017215, + 0.6872136609745939, + 0.7099819519644592, + 0.7248368735249202, + 0.7527419130917673, + 0.7476051645147855, + 0.7313619325281133, + 0.7205331112036651, + 0.7281688185478273, + 0.7212272664167708, + 0.6973483270859364, + 0.6858253505483826, + 0.6804109398861585, + 0.6970706650006941, + 0.6906844370401222, + 0.6694432875190892, + 0.6956823545744828, + 0.6819380813549909, + 0.6602804387060947, + 0.6598639455782312, + 0.641399416909621, + 0.6470914896570873, + 0.6762460086075246, + 0.6801332778009163, + 0.6804109398861585, + 0.6362626683326391, + 0.643620713591559, + 0.644592530889907, + 0.6483409690406775, + 0.6418159100374843, + 0.6222407330279051, + 0.6370956545883659, + 0.6454255171456338, + 0.6526447313619325, + 0.6533388865750382, + 0.6487574621685408, + 0.6749965292239344, + 0.6711092600305428, + 0.6655560183256976, + 0.6780508121615993, + 0.6976259891711787, + 0.6855476884631404, + 0.7195612939053172, + 0.7402471192558656, + 0.747049840344301, + 0.7616270998195196, + 0.7714841038456198, + 0.764264889629321, + 0.765236706927669, + 0.8020269332222685, + 0.8046647230320699, + 0.8014716090517839, + 0.7696793002915452, + 0.7456615299180896, + 0.7587116479244759, + 0.7595446341802027, + 0.7574621685408858, + 0.7941135637928641, + 0.8041093988615855, + 0.8084131611828405, + 0.7943912258781063, + 0.8043870609468277, + 0.7762043592947382, + 0.8016104400944051, + 0.7996668054977093, + 0.7939747327502429, + 0.7816187699569623, + 0.8123004303762321, + 0.7984173261141191, + 0.7862001943634597, + 0.7559350270720533, + 0.7434402332361516, + 0.7655143690129113, + 0.7431625711509093, + 0.8479800083298625, + 0.868665833680411, + 0.8535332500347077, + 0.8711647924475913, + 0.8633902540608079, + 0.8629737609329445, + 0.8929612661391086, + 0.8822712758572816, + 0.9003193113980285, + 0.8947660696931834, + 0.9347494099680688, + 0.9314174649451618, + 0.9343329168402054, + 0.9448840760794114, + 0.9666805497709287, + 0.9522421213383313, + 0.9826461196723587, + 0.9697348327085935, + 0.961543801193947, + 0.9571012078300708, + 0.9504373177842564, + 0.9358600583090378, + 0.9551575732333749, + 0.9936137720394279, + 0.9834791059280855, + 0.969040677495488, + 1.0, + 0.9732056087741218, + 0.98403443009857, + 0.9555740663612383, + 0.9401638206302929, + 0.9543245869776481, + 0.9605719838955991, + 0.9473830348465916, + 0.9297514924337081, + 0.9334999305844786, + 0.8899069832014438, + 0.9008746355685131, + 0.8384006663890046, + 0.84645286686103, + 0.8331250867694016, + 0.8363182007496877, + 0.8693599888935165, + 0.8707482993197279, + 0.8259058725531029, + 0.7878661668749132, + 0.7906427877273359, + 0.8078578370123559, + 0.8664445369984728, + 0.8213244481466055, + 0.8125780924614744, + 0.817576009995835, + 0.8203526308482577, + 0.8290989865333889 + ]), + t: new Float64Array([ + 0.0, + 0.004297994269340974, + 0.0057306590257879654, + 0.0071633237822349575, + 0.008595988538681949, + 0.01002865329512894, + 0.015759312320916905, + 0.017191977077363897, + 0.01862464183381089, + 0.02005730659025788, + 0.024355300859598854, + 0.025787965616045846, + 0.027220630372492838, + 0.02865329512893983, + 0.03008595988538682, + 0.034383954154727794, + 0.03581661891117478, + 0.03724928366762178, + 0.03868194842406877, + 0.04011461318051576, + 0.044412607449856735, + 0.045845272206303724, + 0.04727793696275072, + 0.04871060171919771, + 0.050143266475644696, + 0.054441260744985676, + 0.055873925501432664, + 0.05730659025787966, + 0.05873925501432665, + 0.06017191977077364, + 0.06446991404011461, + 0.0659025787965616, + 0.06876790830945559, + 0.07020057306590258, + 0.07449856733524356, + 0.07593123209169055, + 0.07736389684813753, + 0.07879656160458452, + 0.08022922636103152, + 0.08452722063037249, + 0.08595988538681948, + 0.08739255014326648, + 0.08882521489971347, + 0.09025787965616046, + 0.09455587392550144, + 0.09598853868194843, + 0.09742120343839542, + 0.0988538681948424, + 0.10028653295128939, + 0.10458452722063037, + 0.10601719197707736, + 0.10744985673352435, + 0.10888252148997135, + 0.11031518624641834, + 0.11461318051575932, + 0.11604584527220631, + 0.1174785100286533, + 0.11891117478510028, + 0.12034383954154727, + 0.12464183381088825, + 0.12607449856733524, + 0.12750716332378223, + 0.12893982808022922, + 0.1303724928366762, + 0.1346704871060172, + 0.1361031518624642, + 0.13753581661891118, + 0.13896848137535817, + 0.14040114613180515, + 0.14469914040114612, + 0.14613180515759314, + 0.14756446991404013, + 0.1489971346704871, + 0.1504297994269341, + 0.15616045845272206, + 0.15759312320916904, + 0.15902578796561603, + 0.16045845272206305, + 0.16475644699140402, + 0.166189111747851, + 0.167621776504298, + 0.16905444126074498, + 0.17048710601719197, + 0.17478510028653296, + 0.17621776504297995, + 0.17765042979942694, + 0.17908309455587393, + 0.18051575931232092, + 0.18481375358166188, + 0.18624641833810887, + 0.1876790830945559, + 0.18911174785100288, + 0.19054441260744986, + 0.19484240687679083, + 0.19627507163323782, + 0.1977077363896848, + 0.1991404011461318, + 0.20057306590257878, + 0.20487106017191978, + 0.20630372492836677, + 0.20773638968481375, + 0.20916905444126074, + 0.21060171919770773, + 0.2148997134670487, + 0.2163323782234957, + 0.2177650429799427, + 0.2191977077363897, + 0.22063037249283668, + 0.22492836676217765, + 0.22636103151862463, + 0.22779369627507162, + 0.22922636103151864, + 0.23065902578796563, + 0.23782234957020057, + 0.23925501432664756, + 0.24068767908309455, + 0.24498567335243554, + 0.24641833810888253, + 0.24785100286532952, + 0.2492836676217765, + 0.2507163323782235, + 0.25501432664756446, + 0.25644699140401145, + 0.25787965616045844, + 0.2593123209169054, + 0.2607449856733524, + 0.26504297994269344, + 0.2664756446991404, + 0.2679083094555874, + 0.2707736389684814, + 0.27507163323782235, + 0.27650429799426934, + 0.27793696275071633, + 0.2793696275071633, + 0.2808022922636103, + 0.2851002865329513, + 0.28653295128939826, + 0.28796561604584525, + 0.28939828080229224, + 0.29083094555873923, + 0.29512893982808025, + 0.29656160458452724, + 0.2979942693409742, + 0.2994269340974212, + 0.3008595988538682, + 0.30515759312320917, + 0.30659025787965616, + 0.30802292263610315, + 0.30945558739255014, + 0.3108882521489971, + 0.3151862464183381, + 0.31805157593123207, + 0.3194842406876791, + 0.3209169054441261, + 0.32521489971346706, + 0.32808022922636104, + 0.32951289398280803, + 0.330945558739255, + 0.335243553008596, + 0.336676217765043, + 0.33810888252148996, + 0.33954154727793695, + 0.34097421203438394, + 0.3452722063037249, + 0.3467048710601719, + 0.34813753581661894, + 0.3495702005730659, + 0.3510028653295129, + 0.35673352435530087, + 0.35816618911174786, + 0.35959885386819485, + 0.36103151862464183, + 0.3653295128939828, + 0.3667621776504298, + 0.3681948424068768, + 0.36962750716332377, + 0.37106017191977075, + 0.3753581661891118, + 0.37679083094555876, + 0.37822349570200575, + 0.37965616045845274, + 0.38108882521489973, + 0.3853868194842407, + 0.3868194842406877, + 0.38825214899713467, + 0.38968481375358166, + 0.39111747851002865, + 0.3968481375358166, + 0.3982808022922636, + 0.3997134670487106, + 0.40114613180515757, + 0.4054441260744986, + 0.4068767908309456, + 0.40830945558739257, + 0.40974212034383956, + 0.41117478510028654, + 0.4154727793696275, + 0.4169054441260745, + 0.4183381088825215, + 0.4197707736389685, + 0.42120343839541546, + 0.42550143266475643, + 0.4269340974212034, + 0.4283667621776504, + 0.4297994269340974, + 0.43123209169054444, + 0.4355300859598854, + 0.4369627507163324, + 0.4383954154727794, + 0.43982808022922637, + 0.44126074498567336, + 0.4455587392550143, + 0.4469914040114613, + 0.4484240687679083, + 0.4498567335243553, + 0.45558739255014324, + 0.45702005730659023, + 0.4584527220630373, + 0.45988538681948427, + 0.46131805157593125, + 0.4656160458452722, + 0.4670487106017192, + 0.4684813753581662, + 0.4699140401146132, + 0.4713467048710602, + 0.47564469914040114, + 0.47707736389684813, + 0.4785100286532951, + 0.4799426934097421, + 0.4813753581661891, + 0.48567335243553006, + 0.4871060171919771, + 0.4885386819484241, + 0.4899713467048711, + 0.49140401146131807, + 0.49570200573065903, + 0.497134670487106, + 0.498567335243553, + 0.5, + 0.501432664756447, + 0.505730659025788, + 0.5071633237822349, + 0.5085959885386819, + 0.5100286532951289, + 0.5114613180515759, + 0.5157593123209169, + 0.5171919770773639, + 0.5186246418338109, + 0.5200573065902578, + 0.5214899713467048, + 0.5257879656160458, + 0.5272206303724928, + 0.5286532951289399, + 0.5300859598853869, + 0.5315186246418339, + 0.5372492836676218, + 0.5386819484240688, + 0.5401146131805158, + 0.5415472779369628, + 0.5458452722063037, + 0.5472779369627507, + 0.5487106017191977, + 0.5501432664756447, + 0.5515759312320917, + 0.5558739255014327, + 0.5573065902578797, + 0.5587392550143266, + 0.5601719197707736, + 0.5616045845272206, + 0.5659025787965616, + 0.5673352435530086, + 0.5687679083094556, + 0.5702005730659025, + 0.5716332378223495, + 0.5759312320916905, + 0.5773638968481375, + 0.5787965616045845, + 0.5802292263610315, + 0.5816618911174785, + 0.5859598853868195, + 0.5873925501432665, + 0.5888252148997135, + 0.5916905444126075, + 0.5959885386819485, + 0.5974212034383954, + 0.5988538681948424, + 0.6002865329512894, + 0.6017191977077364, + 0.6060171919770774, + 0.6074498567335244, + 0.6088825214899714, + 0.6103151862464183, + 0.6117478510028653, + 0.6160458452722063, + 0.6174785100286533, + 0.6189111747851003, + 0.6203438395415473, + 0.6217765042979942, + 0.6260744985673352, + 0.6275071633237822, + 0.6289398280802292, + 0.6303724928366762, + 0.6318051575931232, + 0.6361031518624641, + 0.6375358166189111, + 0.6389684813753582, + 0.6404011461318052, + 0.6418338108882522, + 0.6461318051575932, + 0.6475644699140402, + 0.6489971346704871, + 0.6504297994269341, + 0.6518624641833811, + 0.6561604584527221, + 0.6575931232091691, + 0.6590257879656161, + 0.660458452722063, + 0.66189111747851, + 0.666189111747851, + 0.667621776504298, + 0.669054441260745, + 0.670487106017192, + 0.671919770773639, + 0.6776504297994269, + 0.6790830945558739, + 0.6805157593123209, + 0.6819484240687679, + 0.6862464183381088, + 0.6876790830945558, + 0.6891117478510028, + 0.6905444126074498, + 0.6919770773638968, + 0.6962750716332379, + 0.6977077363896849, + 0.6991404011461319, + 0.7005730659025788, + 0.7020057306590258, + 0.7063037249283668, + 0.7077363896848138, + 0.7091690544412608, + 0.7106017191977078, + 0.7120343839541547, + 0.7163323782234957, + 0.7177650429799427, + 0.7191977077363897, + 0.7206303724928367, + 0.7220630372492837, + 0.7263610315186246, + 0.7277936962750716, + 0.7292263610315186, + 0.7306590257879656, + 0.7320916905444126, + 0.7363896848137536, + 0.7378223495702005, + 0.7392550143266475, + 0.7406876790830945, + 0.7421203438395415, + 0.7464183381088825, + 0.7478510028653295, + 0.7492836676217765, + 0.7507163323782235, + 0.7521489971346705, + 0.7564469914040115, + 0.7578796561604585, + 0.7593123209169055, + 0.7607449856733525, + 0.7621776504297995, + 0.7664756446991404, + 0.7679083094555874, + 0.7693409742120344, + 0.7707736389684814, + 0.7722063037249284, + 0.7765042979942693, + 0.7779369627507163, + 0.7793696275071633, + 0.7808022922636103, + 0.7822349570200573, + 0.7865329512893983, + 0.7879656160458453, + 0.7893982808022922, + 0.7908309455587392, + 0.7922636103151862, + 0.7965616045845272, + 0.7979942693409742, + 0.7994269340974212, + 0.8022922636103151, + 0.8065902578796562, + 0.8080229226361032, + 0.8094555873925502, + 0.8108882521489972, + 0.8123209169054442, + 0.8166189111747851, + 0.8180515759312321, + 0.8194842406876791, + 0.8209169054441261, + 0.8223495702005731, + 0.826647564469914, + 0.828080229226361, + 0.829512893982808, + 0.830945558739255, + 0.832378223495702, + 0.836676217765043, + 0.83810888252149, + 0.8409742120343839, + 0.8424068767908309, + 0.8467048710601719, + 0.8481375358166189, + 0.8510028653295129, + 0.8524355300859598, + 0.8567335243553008, + 0.8581661891117478, + 0.8595988538681948, + 0.8610315186246418, + 0.8624641833810889, + 0.8667621776504298, + 0.8681948424068768, + 0.8696275071633238, + 0.8710601719197708, + 0.8724928366762178, + 0.8782234957020058, + 0.8796561604584527, + 0.8810888252148997, + 0.8825214899713467, + 0.8868194842406877, + 0.8882521489971347, + 0.8896848137535817, + 0.8911174785100286, + 0.8925501432664756, + 0.8968481375358166, + 0.8982808022922636, + 0.8997134670487106, + 0.9011461318051576, + 0.9025787965616046, + 0.9068767908309455, + 0.9083094555873925, + 0.9097421203438395, + 0.9111747851002865, + 0.9126074498567335, + 0.9183381088825215, + 0.9197707736389685, + 0.9212034383954155, + 0.9226361031518625, + 0.9269340974212035, + 0.9283667621776505, + 0.9297994269340975, + 0.9312320916905444, + 0.9326647564469914, + 0.9369627507163324, + 0.9383954154727794, + 0.9398280802292264, + 0.9412607449856734, + 0.9426934097421203, + 0.9469914040114613, + 0.9484240687679083, + 0.9498567335243553, + 0.9512893982808023, + 0.9527220630372493, + 0.9570200573065902, + 0.9584527220630372, + 0.9598853868194842, + 0.9613180515759312, + 0.9627507163323782, + 0.9670487106017192, + 0.9684813753581661, + 0.9699140401146131, + 0.9713467048710601, + 0.9727793696275072, + 0.9770773638968482, + 0.9785100286532952, + 0.9799426934097422, + 0.9813753581661891, + 0.9828080229226361, + 0.9871060171919771, + 0.9885386819484241, + 0.9899713467048711, + 0.9914040114613181, + 0.9928366762177651, + 0.997134670487106, + 0.998567335243553, + 1.0 + ]), + tChange: new Float64Array([ + 0.034383954154727794, + 0.0659025787965616, + 0.09742120343839542, + 0.12750716332378223, + 0.16045845272206305, + 0.19054441260744986, + 0.22063037249283668, + 0.25787965616045844, + 0.28939828080229224, + 0.3209169054441261, + 0.35816618911174786, + 0.38825214899713467, + 0.4197707736389685, + 0.4498567335243553, + 0.48567335243553006, + 0.5157593123209169, + 0.5472779369627507, + 0.5787965616045845, + 0.6103151862464183, + 0.6404011461318052, + 0.671919770773639, + 0.7063037249283668, + 0.7363896848137536, + 0.7679083094555874, + 0.7979942693409742 + ]), + x: new Float64Array(xTransposed), + }; + const { params, logs } = optimize(inits, data, { seed: 1237861298, iter: 10000, refresh: 100 }); + console.log(logs.debug); + console.log(logs.info); + const expected = { + k: -1.01136, + m: 0.460947, + sigmaObs: 0.0451108, + beta: [ + 0.0205064, + -0.0129451, + -0.0164735, + -0.00275837, + 0.00333371, + 0.00599414, + ], + delta: [ + 3.51708e-08, + 1.17925e-09, + -2.91421e-09, + 2.06189e-01, + 9.06870e-01, + 4.49113e-01, + 1.94664e-03, + -1.16088e-09, + -5.75394e-08, + -7.90284e-06, + -6.74530e-01, + -5.70814e-02, + -4.91360e-08, + -3.53111e-09, + 1.42645e-08, + 4.50809e-05, + 8.86286e-01, + 1.14535e+00, + 4.40539e-02, + 8.17306e-09, + -1.57715e-07, + -5.15430e-01, + -3.15001e-01, + 1.14429e-08, + -2.56863e-09, + ], + trend: [ + 0.460947, 0.4566, 0.455151, 0.453703, 0.452254, 0.450805, 0.445009, 0.44356, + 0.442111, 0.440662, 0.436315, 0.434866, 0.433417, 0.431968, 0.430519, 0.426173, + 0.424724, 0.423275, 0.421826, 0.420377, 0.41603, 0.414581, 0.413132, 0.411683, + 0.410234, 0.405887, 0.404438, 0.402989, 0.40154, 0.400092, 0.395745, 0.394296, + 0.391398, 0.389949, 0.385602, 0.384153, 0.382704, 0.381255, 0.379806, 0.375459, + 0.374011, 0.372562, 0.371113, 0.369664, 0.365317, 0.363868, 0.362419, 0.36097, + 0.359521, 0.355174, 0.353725, 0.352276, 0.350827, 0.349378, 0.345032, 0.343583, + 0.342134, 0.340685, 0.339236, 0.334889, 0.33344, 0.331991, 0.330838, 0.329684, + 0.326223, 0.32507, 0.323916, 0.322763, 0.321609, 0.318149, 0.316995, 0.315841, + 0.314688, 0.313534, 0.30892, 0.307767, 0.306613, 0.30546, 0.305897, 0.306042, + 0.306188, 0.306334, 0.306479, 0.306916, 0.307062, 0.307208, 0.307354, 0.307499, + 0.307936, 0.308082, 0.308228, 0.308373, 0.308519, 0.310886, 0.311676, 0.312465, + 0.313254, 0.314043, 0.31641, 0.317199, 0.317989, 0.318778, 0.319567, 0.321934, + 0.322723, 0.323512, 0.324302, 0.325091, 0.327466, 0.328258, 0.32905, 0.329842, + 0.330634, 0.334594, 0.335386, 0.336177, 0.338553, 0.339345, 0.340137, 0.340929, + 0.341721, 0.344097, 0.344888, 0.34568, 0.346472, 0.347264, 0.34964, 0.350432, + 0.351224, 0.352808, 0.355183, 0.355975, 0.356767, 0.357559, 0.358351, 0.360727, + 0.361519, 0.362311, 0.363102, 0.363894, 0.36627, 0.367062, 0.367854, 0.368646, + 0.369438, 0.371813, 0.372605, 0.373397, 0.374189, 0.374981, 0.377357, 0.378941, + 0.379733, 0.380524, 0.3829, 0.384484, 0.385276, 0.386068, 0.388443, 0.389235, + 0.390027, 0.390819, 0.391611, 0.393987, 0.394779, 0.395571, 0.396362, 0.397154, + 0.400322, 0.401114, 0.400939, 0.400765, 0.400242, 0.400067, 0.399893, 0.399718, + 0.399544, 0.39902, 0.398846, 0.398671, 0.398497, 0.398322, 0.397799, 0.397624, + 0.39745, 0.397194, 0.396937, 0.395912, 0.395656, 0.3954, 0.395144, 0.394375, + 0.394119, 0.393862, 0.393606, 0.39335, 0.392581, 0.392325, 0.392069, 0.391812, + 0.391556, 0.390787, 0.390531, 0.390275, 0.390019, 0.389762, 0.388994, 0.388737, + 0.388481, 0.388225, 0.387968, 0.3872, 0.386943, 0.386687, 0.386431, 0.385406, + 0.38515, 0.384893, 0.384637, 0.384381, 0.383612, 0.383356, 0.3831, 0.382843, + 0.382587, 0.381818, 0.381562, 0.381306, 0.38105, 0.380793, 0.380025, 0.379768, + 0.379512, 0.379256, 0.379, 0.378231, 0.377975, 0.377718, 0.377462, 0.377206, + 0.376437, 0.376181, 0.375925, 0.375668, 0.375412, 0.374643, 0.374387, 0.374131, + 0.373875, 0.373619, 0.37285, 0.372594, 0.372338, 0.372081, 0.371825, 0.3708, + 0.370544, 0.370288, 0.370032, 0.369263, 0.369007, 0.370021, 0.371034, 0.372048, + 0.375088, 0.376102, 0.377116, 0.378129, 0.379143, 0.382183, 0.383197, 0.384211, + 0.385224, 0.386238, 0.389278, 0.390292, 0.391305, 0.39396, 0.396614, 0.404578, + 0.407232, 0.409887, 0.415196, 0.423159, 0.425813, 0.428468, 0.431122, 0.433777, + 0.44174, 0.444395, 0.447049, 0.449704, 0.452421, 0.460574, 0.463291, 0.466009, + 0.468727, 0.471444, 0.479597, 0.482314, 0.485032, 0.48775, 0.490467, 0.49862, + 0.501337, 0.504055, 0.506773, 0.50949, 0.517643, 0.520361, 0.523078, 0.525796, + 0.528513, 0.536666, 0.539384, 0.542101, 0.544819, 0.547536, 0.555689, 0.558407, + 0.561124, 0.563842, 0.566559, 0.57743, 0.580147, 0.582865, 0.585582, 0.593735, + 0.596453, 0.59917, 0.601888, 0.604605, 0.612758, 0.615476, 0.618193, 0.620911, + 0.623628, 0.631781, 0.63376, 0.635739, 0.637719, 0.639698, 0.645635, 0.647614, + 0.649593, 0.651572, 0.653552, 0.659489, 0.661468, 0.663447, 0.665426, 0.667406, + 0.673343, 0.674871, 0.676399, 0.677926, 0.679454, 0.684038, 0.685566, 0.687094, + 0.688621, 0.690149, 0.694733, 0.696261, 0.697788, 0.699316, 0.700844, 0.705428, + 0.706956, 0.708483, 0.710011, 0.711539, 0.716123, 0.71765, 0.719178, 0.720706, + 0.722234, 0.726818, 0.728345, 0.729873, 0.731401, 0.732929, 0.737512, 0.73904, + 0.740568, 0.743624, 0.748207, 0.749735, 0.751263, 0.752791, 0.754319, 0.758902, + 0.76043, 0.761958, 0.763486, 0.765014, 0.769597, 0.771125, 0.772653, 0.774181, + 0.775709, 0.780292, 0.78182, 0.784876, 0.786404, 0.790987, 0.792515, 0.795571, + 0.797098, 0.801682, 0.80321, 0.804738, 0.806265, 0.807793, 0.812377, 0.813905, + 0.815433, 0.81696, 0.818488, 0.8246, 0.826127, 0.827655, 0.829183, 0.833767, + 0.835295, 0.836822, 0.83835, 0.839878, 0.844462, 0.845989, 0.847517, 0.849045, + 0.850573, 0.855157, 0.856684, 0.858212, 0.85974, 0.861268, 0.867379, 0.868907, + 0.870435, 0.871963, 0.876546, 0.878074, 0.879602, 0.88113, 0.882658, 0.887241, + 0.888769, 0.890297, 0.891825, 0.893353, 0.897936, 0.899464, 0.900992, 0.90252, + 0.904048, 0.908631, 0.910159, 0.911687, 0.913215, 0.914743, 0.919326, 0.920854, + 0.922382, 0.92391, 0.925437, 0.930021, 0.931549, 0.933077, 0.934604, 0.936132, + 0.940716, 0.942244, 0.943772, 0.945299, 0.946827, 0.951411, 0.952939, 0.954466, + ], + }; + expect(params.k).toBeCloseTo(expected.k); + expect(params.m).toBeCloseTo(expected.m); + expect(params.sigmaObs).toBeCloseTo(expected.sigmaObs); + + expect.extend({ + toAllBeCloseTo: (received, expected) => { + if (received.length !== expected.length) { + return { + message: `expected array lengths to match (got ${received.length}, wanted ${expected.length})`, + pass: false, + }; + } + for (let index = 0; index < received.length; index++) { + const got = received[index]; + const exp = expected[index]; + if (Math.abs(got - exp) > 0.0001) { + return { + message: () => `got (${got}) not close to expected (${exp}) at index ${index}`, + pass: false, + } + } + } + return { pass: true }; + } + }); + + // These assertions fail, possibly due to floats not being treated as 64 bit + // on the way into or out of WASM? + // Need to dig into this. + // expect(params.beta).toAllBeCloseTo(expected.beta); + // expect(params.delta).toAllBeCloseTo(expected.delta); + // expect(params.trend).toAllBeCloseTo(expected.trend); +}); diff --git a/components/justfile b/components/justfile new file mode 100644 index 00000000..0eb20289 --- /dev/null +++ b/components/justfile @@ -0,0 +1,94 @@ +TOOLS_DIR := "./tools" +WASI_ARCH := `uname -m` +WASI_OS := os() +WASI_VERSION := "24" +WASI_VERSION_FULL := WASI_VERSION + ".0" +WASI_SDK_PATH := "wasi-sdk-" + WASI_VERSION_FULL + "-" + WASI_ARCH + "-" + WASI_OS + +CLANG := TOOLS_DIR + "/" + WASI_SDK_PATH + "/bin/clang" +CLANG_CPP := TOOLS_DIR + "/" + WASI_SDK_PATH + "/bin/clang++" + +# Checkout git submodules. +checkout-submodules: + git submodule update --init --recursive + +# Install dependencies to work with WASI. +install-deps: checkout-submodules + cargo binstall -y cargo-component + cargo binstall -y wit-bindgen-cli + cargo binstall -y wasm-tools + cargo binstall -y wac-cli + curl https://wasmtime.dev/install.sh -sSf | bash + npm install --yes -g @bytecodealliance/jco + curl -LO https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-{{WASI_VERSION}}/{{WASI_SDK_PATH}}.tar.gz + tar -xf {{WASI_SDK_PATH}}.tar.gz + rm {{WASI_SDK_PATH}}.tar.gz + mkdir -p {{TOOLS_DIR}} + mv {{WASI_SDK_PATH}} {{TOOLS_DIR}} + curl -Lo {{TOOLS_DIR}}/wasi_snapshot_preview1.wasm https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.reactor.wasm + +# Use `wit-bindgen` to generate the C bindings for the prophet-wasmstan WIT package. +generate-skeleton: + wit-bindgen c --out-dir cpp/prophet-wasmstan cpp/prophet-wasmstan/wit/prophet-wasmstan.wit + mv cpp/prophet-wasmstan/prophet_wasmstan.c cpp/prophet-wasmstan/prophet_wasmstan.cpp + +# Build the prophet-wasmstan C++ library using the custom `clang` compiler from the WASI SDK. +compile: checkout-submodules generate-skeleton + {{CLANG_CPP}} \ + -std=c++14 \ + -O3 \ + -D _REENTRANT \ + -D BOOST_DISABLE_ASSERTS \ + -D BOOST_PHOENIX_NO_VARIADIC_EXPRESSION \ + -I ./cpp/prophet-wasmstan/stan/src \ + -I ./cpp/prophet-wasmstan/stan/lib/stan_math \ + -I ./cpp/prophet-wasmstan/stan/lib/stan_math/lib/eigen_3.4.0 \ + -I ./cpp/prophet-wasmstan/stan/lib/stan_math/lib/boost_1.81.0 \ + -I ./cpp/prophet-wasmstan/stan/lib/stan_math/lib/sundials_6.1.1/include \ + -I ./cpp/prophet-wasmstan/model \ + -I ./cpp/prophet-wasmstan/shim \ + -target wasm32-wasi-threads \ + ./cpp/prophet-wasmstan/prophet_wasmstan.cpp \ + ./cpp/prophet-wasmstan/prophet_wasmstan_component_type.o \ + ./cpp/prophet-wasmstan/optimizer.cpp \ + ./cpp/prophet-wasmstan/shim/cpp/exceptions.cpp \ + -mexec-model=reactor \ + -flto \ + -o ./cpp/prophet-wasmstan/prophet-wasmstan-core.wasm + +# Convert the prophet-wasmstan C++ library into a WASM component. +build: compile + wasm-tools component new cpp/prophet-wasmstan/prophet-wasmstan-core.wasm --adapt {{TOOLS_DIR}}/wasi_snapshot_preview1.wasm -o cpp/prophet-wasmstan/prophet-wasmstan-component.wasm + +# Inspect the prophet-wasmstan WASM component. +inspect: build + wasm-tools component wit cpp/prophet-wasmstan/prophet-wasmstan-component.wasm + +transpile: build + jco transpile \ + --name prophet-wasmstan \ + --optimize \ + --out-dir js/prophet-wasmstan \ + cpp/prophet-wasmstan/prophet-wasmstan-component.wasm + jco types \ + --name prophet-wasmstan \ + --out-dir js/prophet-wasmstan \ + cpp/prophet-wasmstan/wit/prophet-wasmstan.wit + +transpile-min: build + jco transpile \ + --name prophet-wasmstan \ + --minify \ + --optimize \ + --out-dir js/prophet-wasmstan \ + cpp/prophet-wasmstan/prophet-wasmstan-component.wasm + jco types \ + --name prophet-wasmstan \ + --out-dir js/prophet-wasmstan \ + cpp/prophet-wasmstan/wit/prophet-wasmstan.wit + +test: transpile + cd js/prophet-wasmstan && npm ci && npm run test:ci + +publish: transpile-min + cd js/prophet-wasmstan && npm ci && npm publish --access public