From 7dc6ed4bd8cc308fd9ba280e7c441eb6caa12d24 Mon Sep 17 00:00:00 2001 From: Fengler Date: Tue, 7 Jan 2025 15:02:00 +0100 Subject: [PATCH] wip --- docs/basic_tutorial/basic_tutorial.ipynb | 54 +- notebooks/basic_tutorial copy.ipynb | 1080 +++++++-------------- notebooks/basic_tutorial_12122024.ipynb | 464 +++++++++ notebooks/basic_tutorial_old.ipynb | 1113 ++++++++++++++++++++++ pyproject.toml | 2 +- ssms/__init__.py | 2 +- ssms/basic_simulators/drift_functions.py | 54 +- ssms/basic_simulators/simulator.py | 16 + ssms/basic_simulators/theta_processor.py | 8 +- ssms/config/config.py | 152 ++- ssms/dataset_generators/lan_mlp.py | 20 +- ssms/support_utils/kde_class.py | 25 +- 12 files changed, 2204 insertions(+), 786 deletions(-) create mode 100755 notebooks/basic_tutorial_12122024.ipynb create mode 100755 notebooks/basic_tutorial_old.ipynb diff --git a/docs/basic_tutorial/basic_tutorial.ipynb b/docs/basic_tutorial/basic_tutorial.ipynb index 25dd5a4..bba1f97 100755 --- a/docs/basic_tutorial/basic_tutorial.ipynb +++ b/docs/basic_tutorial/basic_tutorial.ipynb @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -89,7 +89,7 @@ " 'ddm_truncnormt']" ] }, - "execution_count": 11, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -101,19 +101,28 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'ssms' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[1], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Take an example config for a given model\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[43mssms\u001b[49m\u001b[38;5;241m.\u001b[39mconfig\u001b[38;5;241m.\u001b[39mmodel_config[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mddm\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", - "\u001b[0;31mNameError\u001b[0m: name 'ssms' is not defined" - ] + "data": { + "text/plain": [ + "{'name': 'ddm',\n", + " 'params': ['v', 'a', 'z', 't'],\n", + " 'param_bounds': [[-3.0, 0.3, 0.1, 0.0], [3.0, 2.5, 0.9, 2.0]],\n", + " 'boundary_name': 'constant',\n", + " 'boundary': float | numpy.ndarray>,\n", + " 'boundary_params': [],\n", + " 'n_params': 4,\n", + " 'default_params': [0.0, 1.0, 0.5, 0.001],\n", + " 'nchoices': 2,\n", + " 'n_particles': 1,\n", + " 'simulator': }" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -140,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -184,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -211,10 +220,11 @@ " 'n_subruns': 10,\n", " 'bin_pointwise': False,\n", " 'separate_response_channels': False,\n", - " 'smooth_unif': True}" + " 'smooth_unif': True,\n", + " 'kde_displace_t': False}" ] }, - "execution_count": 14, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -233,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -258,14 +268,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary_name': 'angle', 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n" + "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary_name': 'angle', 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n" ] } ], @@ -283,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -303,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 11, "metadata": { "tags": [] }, diff --git a/notebooks/basic_tutorial copy.ipynb b/notebooks/basic_tutorial copy.ipynb index 59c491f..be5824e 100755 --- a/notebooks/basic_tutorial copy.ipynb +++ b/notebooks/basic_tutorial copy.ipynb @@ -30,7 +30,7 @@ "\n", "You can do so by typing,\n", "\n", - "`pip install git+https://github.com/AlexanderFengler/ssm_simulators`\n", + "`pip install ssm-simulators`\n", "\n", "in your terminal.\n", "\n", @@ -56,33 +56,6 @@ "import ssms" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3 2 1\n" - ] - } - ], - "source": [ - "def myfun(a, b, c):\n", - "\tprint(a, b, c)\n", - "\n", - "myfun(**{'c': 1, 'b': 2, 'a': 3})" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -90,7 +63,7 @@ "#### Using the Simulators\n", "\n", "Let's start with using the basic simulators. \n", - "You access the main simulators through the `ssms.basic_simulators.simulator` function.\n", + "You access the main simulators through the `ssms.basic_simulators.simulator.simulator()` function.\n", "\n", "To get an idea about the models included in `ssms`, use the `config` module.\n", "The central dictionary with metadata about included models sits in `ssms.config.model_config`. " @@ -113,90 +86,7 @@ " 'full_ddm',\n", " 'full_ddm_rv',\n", " 'ddm_st',\n", - " 'ddm_truncnormt',\n", - " 'ddm_rayleight',\n", - " 'ddm_sdv',\n", - " 'gamma_drift',\n", - " 'shrink_spot',\n", - " 'shrink_spot_extended',\n", - " 'gamma_drift_angle',\n", - " 'ds_conflict_drift',\n", - " 'ds_conflict_drift_angle',\n", - " 'ornstein',\n", - " 'ornstein_angle',\n", - " 'lba2',\n", - " 'lba3',\n", - " 'lba_3_v1',\n", - " 'lba_angle_3_v1',\n", - " 'rlwm_lba_race_v1',\n", - " 'race_2',\n", - " 'race_no_bias_2',\n", - " 'race_no_z_2',\n", - " 'race_no_bias_angle_2',\n", - " 'race_no_z_angle_2',\n", - " 'race_3',\n", - " 'race_no_bias_3',\n", - " 'race_no_z_3',\n", - " 'race_no_bias_angle_3',\n", - " 'race_no_z_angle_3',\n", - " 'race_4',\n", - " 'race_no_bias_4',\n", - " 'race_no_z_4',\n", - " 'race_no_bias_angle_4',\n", - " 'race_no_z_angle_4',\n", - " 'lca_3',\n", - " 'lca_no_bias_3',\n", - " 'lca_no_z_3',\n", - " 'lca_no_bias_angle_3',\n", - " 'lca_no_z_angle_3',\n", - " 'lca_4',\n", - " 'lca_no_bias_4',\n", - " 'lca_no_z_4',\n", - " 'lca_no_bias_angle_4',\n", - " 'lca_no_z_angle_4',\n", - " 'ddm_par2',\n", - " 'ddm_par2_no_bias',\n", - " 'ddm_par2_conflict_gamma_no_bias',\n", - " 'ddm_par2_angle_no_bias',\n", - " 'ddm_par2_weibull_no_bias',\n", - " 'ddm_seq2',\n", - " 'ddm_seq2_no_bias',\n", - " 'ddm_seq2_conflict_gamma_no_bias',\n", - " 'ddm_seq2_angle_no_bias',\n", - " 'ddm_seq2_weibull_no_bias',\n", - " 'ddm_mic2_adj',\n", - " 'ddm_mic2_adj_no_bias',\n", - " 'ddm_mic2_adj_conflict_gamma_no_bias',\n", - " 'ddm_mic2_adj_angle_no_bias',\n", - " 'ddm_mic2_adj_weibull_no_bias',\n", - " 'ddm_mic2_ornstein',\n", - " 'ddm_mic2_ornstein_no_bias',\n", - " 'ddm_mic2_ornstein_conflict_gamma_no_bias',\n", - " 'ddm_mic2_ornstein_angle_no_bias',\n", - " 'ddm_mic2_ornstein_weibull_no_bias',\n", - " 'ddm_mic2_multinoise_no_bias',\n", - " 'ddm_mic2_multinoise_conflict_gamma_no_bias',\n", - " 'ddm_mic2_multinoise_angle_no_bias',\n", - " 'ddm_mic2_multinoise_weibull_no_bias',\n", - " 'ddm_mic2_leak',\n", - " 'ddm_mic2_leak_no_bias',\n", - " 'ddm_mic2_leak_conflict_gamma_no_bias',\n", - " 'ddm_mic2_leak_angle_no_bias',\n", - " 'ddm_mic2_leak_weibull_no_bias',\n", - " 'tradeoff_no_bias',\n", - " 'tradeoff_angle_no_bias',\n", - " 'tradeoff_weibull_no_bias',\n", - " 'tradeoff_conflict_gamma_no_bias',\n", - " 'weibull_cdf',\n", - " 'full_ddm2',\n", - " 'ddm_mic2_ornstein_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_ornstein_angle_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_ornstein_weibull_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_ornstein_conflict_gamma_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_leak_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_leak_angle_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_leak_weibull_no_bias_no_lowdim_noise',\n", - " 'ddm_mic2_leak_conflict_gamma_no_bias_no_lowdim_noise']" + " 'ddm_truncnormt']" ] }, "execution_count": 2, @@ -206,34 +96,13 @@ ], "source": [ "# Check included models\n", - "list(ssms.config.model_config.keys())" + "list(ssms.config.model_config.keys())[:10]" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "'ddm_deadline'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mssms\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_config\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mddm_deadline\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n", - "\u001b[0;31mKeyError\u001b[0m: 'ddm_deadline'" - ] - } - ], - "source": [ - "ssms.config.model_config[\"ddm_deadline\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, "outputs": [ { "data": { @@ -248,10 +117,10 @@ " 'default_params': [0.0, 1.0, 0.5, 0.001],\n", " 'nchoices': 2,\n", " 'n_particles': 1,\n", - " 'simulator': }" + " 'simulator': }" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -261,41 +130,6 @@ "ssms.config.model_config[\"ddm\"]" ] }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from ssms.basic_simulators.simulator import simulator\n", - "\n", - "sim_out = simulator(\n", - "\tmodel=\"lba2\", theta={'A': 0.3, 'b': 0.5, 'v0': 0.5, 'v1': 0.5},\n", - "\t\t\t\t\t\t n_samples=10\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", - " 1., 1., 1.])" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.tile(np.ones(2), (10))" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -315,130 +149,343 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "from ssms.basic_simulators.simulator import simulator\n", - "\n", - "p_choice_vec = []\n", - "dline_tmp_vec = []\n", - "for dline_tmp in np.linspace(0.2, 5, 50):\n", - " sim_out = simulator(\n", - " model=\"ddm_deadline\", theta=[1.0, 1.0, 0.5, 0.1, dline_tmp], n_samples=10000\n", - " )\n", - " p_choice_vec.append(np.sum(sim_out[\"choices\"] == 1.0) / sim_out[\"choices\"].shape[0])\n", - " dline_tmp_vec.append(dline_tmp)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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M1VaWtru9atXr1ZRUZHz2L17t8xms2699VbnNb/61a/029/+VitWrNCWLVsUFBSkzMxM1dfXd/6TuZF9RdWS6A4CAKCzXA4sS5cu1X333ae5c+dq1KhRWrFihQIDA/Xqq6+2e33//v0VExPjPNatW6fAwEBnYHE4HFq2bJkWLlyom266SampqfrjH/+owsJCvffeexf14dzFgdYWlphQgysBAKB3cimwNDY2KicnRxkZGd8+wMtLGRkZ2rRpU4ee8corr+i2225TUFCQJOno0aMqLi5u88ywsDClp6ef85kNDQ2yWCxtDne2v7ilhWVkLC0sAAB0hkuBpby8XDabTdHR0W3OR0dHq7i4+IL3b926Vbt379a9997rPNd6nyvPXLJkicLCwpxHYmKiKx+jR1XVNqmoqqVrKzmawAIAQGf06CyhV155RWPGjNHEiRMv6jkLFixQVVWV88jPz++iCrte64DbhH4BCmGFWwAAOsWlwBIRESGz2aySkpI250tKShQTE3Pee61Wq9566y3dc889bc633ufKM/38/BQaGtrmcFet3UGMXwEAoPNcCiy+vr4aP368srOznefsdruys7M1adKk8977zjvvqKGhQXfeeWeb80OGDFFMTEybZ1osFm3ZsuWCz+wNnFOamSEEAECnebt6Q1ZWlubMmaMJEyZo4sSJWrZsmaxWq+bOnStJmj17tuLj47VkyZI2973yyiu6+eabNWBA252KTSaTHnnkET3zzDMaPny4hgwZoieeeEJxcXG6+eabO//J3ETrlOYRDLgFAKDTXA4sM2fOVFlZmRYtWqTi4mKlpaVp7dq1zkGzeXl58vJq23Bz4MABbdy4UR9//HG7z3zsscdktVp1//33q7KyUlOmTNHatWvl7+/fiY/kPux2hw6W0CUEAMDFMjkcDofRRVwsi8WisLAwVVVVudV4luMVVl39/Hr5entp71OZ8jazEwIAAK1ceX/zBu1Grd1BydHBhBUAAC4Cb9FudIAZQgAAdAkCSzdihhAAAF2DwNKNWIMFAICuQWDpJnWNNh2rsEpiSjMAABeLwNJNDpZUy+GQIoJ9FRHsZ3Q5AAD0agSWbvLt+BW6gwAAuFgElm7y7fgVuoMAALhYBJZusv/0GiwpBBYAAC4agaUbOBwOZ5fQyFi6hAAAuFgElm5QVt2gU7VN8jJJw6KCjS4H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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from matplotlib import pyplot as plt\n", - "\n", - "plt.plot(dline_tmp_vec, p_choice_vec)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "(array([ 2., 0., 2., 2., 4., 4., 2., 5., 7.,\n", - " 5., 15., 15., 26., 50., 52., 62., 111., 116.,\n", - " 195., 221., 234., 45., 0., 0., 0., 0., 0.,\n", - " 263., 1796., 1810., 1326., 930., 759., 517., 400., 266.,\n", - " 205., 154., 104., 74., 60., 40., 24., 29., 17.,\n", - " 15., 15., 8., 3., 7.]),\n", - " array([-4.67442942, -4.4839405 , -4.29345158, -4.10296266, -3.91247374,\n", - " -3.72198482, -3.5314959 , -3.34100698, -3.15051805, -2.96002913,\n", - " -2.76954021, -2.57905129, -2.38856237, -2.19807345, -2.00758453,\n", - " -1.81709561, -1.62660669, -1.43611777, -1.24562885, -1.05513993,\n", - " -0.86465101, -0.67416209, -0.48367317, -0.29318425, -0.10269533,\n", - " 0.08779359, 0.27828251, 0.46877143, 0.65926035, 0.84974927,\n", - " 1.04023819, 1.23072711, 1.42121603, 1.61170495, 1.80219387,\n", - " 1.99268279, 2.18317171, 2.37366063, 2.56414955, 2.75463847,\n", - " 2.94512739, 3.13561631, 3.32610523, 3.51659415, 3.70708307,\n", - " 3.89757199, 4.08806091, 4.27854983, 4.46903875, 4.65952767,\n", - " 4.85001659]),\n", - " )" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n", + "sim param dict before {'max_t': 20.0, 'n_samples': 2000, 'n_trials': 1000, 'delta_t': 0.001, 'random_state': None, 'return_option': 'full', 'smooth_unif': False}\n", + "sim param dict after {'n_samples': 1, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': 100, 'n_trials': 1}\n" + ] } ], "source": [ - "from matplotlib import pyplot as plt\n", - "\n", - "plt.hist(\n", - " sim_out[\"rts\"][sim_out[\"rts\"] != -999] * sim_out[\"choices\"][sim_out[\"rts\"] != -999],\n", - " bins=50,\n", - ")" + "from ssms.basic_simulators.simulator import simulator\n", + "out_list = []\n", + "for i in range(100):\n", + " sim_out = simulator(\n", + " model=\"ddm\", theta={\"v\": 0, \"a\": 1, \"z\": 0.5, \"t\": 0.5}, n_samples=1, random_state = 100,\n", + " )\n", + " out_list.append(sim_out)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array([[ 1.26040506, 1. ],\n", - " [ 1.56888986, -1. ],\n", - " [ 1.09187531, -1. ],\n", - " ...,\n", - " [ 0.75505078, -1. ],\n", - " [ 0.89852297, 1. ],\n", - " [ 1.17158473, -1. ]])" + "[1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848,\n", + " 1.4548848]" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "np.hstack([sim_out[\"rts\"], sim_out[\"choices\"]])" + "[out_list[i]['rts'][0][0] for i in range(100)]" ] }, { @@ -474,14 +521,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'output_folder': 'data/lan_mlp/',\n", - " 'dgp_list': 'ddm',\n", + " 'model': 'ddm',\n", " 'nbins': 0,\n", " 'n_samples': 100000,\n", " 'n_parameter_sets': 10000,\n", @@ -500,10 +547,12 @@ " 'negative_rt_cutoff': -66.77497,\n", " 'n_subruns': 10,\n", " 'bin_pointwise': False,\n", - " 'separate_response_channels': False}" + " 'separate_response_channels': False,\n", + " 'smooth_unif': True,\n", + " 'kde_displace_t': False}" ] }, - "execution_count": 12, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -522,16 +571,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "from copy import deepcopy\n", "\n", "# Initialize the generator config (for MLP LANs)\n", - "generator_config = deepcopy(ssms.config.data_generator_config[\"snpe\"])\n", + "generator_config = deepcopy(ssms.config.data_generator_config[\"lan\"])\n", + "generator_config[\"model\"] = \"shrink_spot_simple\"\n", "# Specify generative model (one from the list of included models mentioned above)\n", - "generator_config[\"dgp_list\"] = \"angle\"\n", "# Specify number of parameter sets to simulate\n", "generator_config[\"n_parameter_sets\"] = 100\n", "# Specify how many samples a simulation run should entail\n", @@ -547,14 +596,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'hddm_include': ['z', 'theta'], 'nchoices': 2}\n" + "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary_name': 'angle', 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n" ] } ], @@ -572,27 +621,27 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "n_cpus used: 6\n", - "checking: data/snpe_training/\n" + "n_cpus used: 12\n", + "checking: data/lan_mlp/\n" ] } ], "source": [ - "my_dataset_generator = ssms.dataset_generators.data_generator_snpe(\n", + "my_dataset_generator = ssms.dataset_generators.lan_mlp.data_generator(\n", " generator_config=generator_config, model_config=model_config\n", ")" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 46, "metadata": { "tags": [] }, @@ -610,458 +659,12 @@ "simulation round: 7 of 10\n", "simulation round: 8 of 10\n", "simulation round: 9 of 10\n", - "simulation round: 10 of 10\n", - "Writing to file: data/snpe_training/training_data__n_1000/angle/training_data_angle_4c70e020dace11ec9074acde48001122.pickle\n" + "simulation round: 10 of 10\n" ] } ], "source": [ - "training_data = my_dataset_generator.generate_data_training_uniform(save=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "new_features = {\n", - " i: {\n", - " \"data\": training_data[0][i][\"features\"],\n", - " \"labels\": training_data[0][i][\"labels\"],\n", - " }\n", - " for i in range(len(training_data[0]))\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "training_data.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "trainin" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'features: ': array([[ 4.10223436, 1. ],\n", - " [ 2.655339 , 1. ],\n", - " [ 3.40328479, 1. ],\n", - " ...,\n", - " [ 2.71133494, 1. ],\n", - " [ 0.60232329, -1. ],\n", - " [ 1.18331599, -1. ]]),\n", - " 'labels': array([ 1.2677877 , 2.0692544 , 0.17184597, 0.36032298, -0.06370651],\n", - " dtype=float32),\n", - " 'meta': {'v': array([1.2677877], dtype=float32),\n", - " 'a': array([2.0692544], dtype=float32),\n", - " 'z': array([0.17184597], dtype=float32),\n", - " 't': array([0.36032298], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([-0.06370651], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ -1.3580683],\n", - " [ -1.3061538],\n", - " [ -1.3130792],\n", - " ...,\n", - " [-999. ],\n", - " [-999. ],\n", - " [-999. ]], dtype=float32),\n", - " 'boundary': array([2.0692544, 2.0693183, 2.069382 , ..., 3.3449836, 3.3450472,\n", - " 3.345111 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[1.02261758, 1. ],\n", - " [1.04661727, 1. ],\n", - " [1.06361699, 1. ],\n", - " ...,\n", - " [0.93361747, 1. ],\n", - " [1.46661186, 1. ],\n", - " [1.03261745, 1. ]]),\n", - " 'labels': array([2.604681 , 1.3304262, 0.5099575, 0.7646173, 0.8860518],\n", - " dtype=float32),\n", - " 'meta': {'v': array([2.604681], dtype=float32),\n", - " 'a': array([1.3304262], dtype=float32),\n", - " 'z': array([0.5099575], dtype=float32),\n", - " 't': array([0.7646173], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.8860518], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 2.6495418e-02],\n", - " [ 7.9746895e-02],\n", - " [ 7.4158326e-02],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 1.3304262, 1.3292016, 1.3279768, ..., -23.160759 ,\n", - " -23.161983 , -23.163208 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[ 0.96705407, 1. ],\n", - " [ 0.935054 , 1. ],\n", - " [ 0.87205386, -1. ],\n", - " ...,\n", - " [ 0.90805393, 1. ],\n", - " [ 0.96405405, 1. ],\n", - " [ 1.02105391, 1. ]]),\n", - " 'labels': array([1.2017035 , 0.97606236, 0.39102793, 0.7560538 , 1.2579942 ],\n", - " dtype=float32),\n", - " 'meta': {'v': array([1.2017035], dtype=float32),\n", - " 'a': array([0.97606236], dtype=float32),\n", - " 'z': array([0.39102793], dtype=float32),\n", - " 't': array([0.7560538], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([1.2579942], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[-2.1272707e-01],\n", - " [-1.6087857e-01],\n", - " [-1.6787012e-01],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 0.97606236, 0.9729704 , 0.96987844, ..., -60.856857 ,\n", - " -60.859947 , -60.863037 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[ 1.00975132, -1. ],\n", - " [ 1.27174985, -1. ],\n", - " [ 1.12875164, -1. ],\n", - " ...,\n", - " [ 0.99275136, -1. ],\n", - " [ 1.25475013, -1. ],\n", - " [ 1.45274758, -1. ]]),\n", - " 'labels': array([-1.6534374 , 1.5941297 , 0.12224997, 0.8867513 , 0.23367152],\n", - " dtype=float32),\n", - " 'meta': {'v': array([-1.6534374], dtype=float32),\n", - " 'a': array([1.5941297], dtype=float32),\n", - " 'z': array([0.12224997], dtype=float32),\n", - " 't': array([0.8867513], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.23367152], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ -1.2043651],\n", - " [ -1.1553718],\n", - " [ -1.1652185],\n", - " ...,\n", - " [-999. ],\n", - " [-999. ],\n", - " [-999. ]], dtype=float32),\n", - " 'boundary': array([ 1.5941297, 1.5938916, 1.5936537, ..., -3.1657853, -3.1660233,\n", - " -3.1662607], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[ 1.26257348, -1. ],\n", - " [ 0.6515795 , 1. ],\n", - " [ 0.95757735, -1. ],\n", - " ...,\n", - " [ 0.97157717, -1. ],\n", - " [ 0.83357894, 1. ],\n", - " [ 0.77157974, -1. ]]),\n", - " 'labels': array([-1.4438915 , 0.9805305 , 0.69183505, 0.5205794 , 0.6480955 ],\n", - " dtype=float32),\n", - " 'meta': {'v': array([-1.4438915], dtype=float32),\n", - " 'a': array([0.9805305], dtype=float32),\n", - " 'z': array([0.69183505], dtype=float32),\n", - " 't': array([0.5205794], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.6480955], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 3.7620023e-01],\n", - " [ 4.2540312e-01],\n", - " [ 4.1576597e-01],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 0.9805305 , 0.9797733 , 0.97901607, ..., -14.162027 ,\n", - " -14.162784 , -14.163541 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[0.91735744, 1. ],\n", - " [1.20835662, 1. ],\n", - " [0.92935741, 1. ],\n", - " ...,\n", - " [0.90235746, 1. ],\n", - " [0.89735746, 1. ],\n", - " [1.31435525, 1. ]]),\n", - " 'labels': array([1.9964801, 1.4816018, 0.8841693, 0.8633575, 1.0173286],\n", - " dtype=float32),\n", - " 'meta': {'v': array([1.9964801], dtype=float32),\n", - " 'a': array([1.4816018], dtype=float32),\n", - " 'z': array([0.8841693], dtype=float32),\n", - " 't': array([0.8633575], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([1.0173286], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 1.1383718],\n", - " [ 1.0790156],\n", - " [ 1.0546436],\n", - " ...,\n", - " [-999. ],\n", - " [-999. ],\n", - " [-999. ]], dtype=float32),\n", - " 'boundary': array([ 1.4816018, 1.4799834, 1.478365 , ..., -30.883564 ,\n", - " -30.885181 , -30.886799 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[ 2.23801517, -1. ],\n", - " [ 1.17800593, 1. ],\n", - " [ 3.20701861, -1. ],\n", - " ...,\n", - " [ 1.28100467, 1. ],\n", - " [ 2.52602863, -1. ],\n", - " [ 3.33400941, -1. ]]),\n", - " 'labels': array([-1.3583255 , 1.9194802 , 0.76933956, 0.85600656, 0.14019692],\n", - " dtype=float32),\n", - " 'meta': {'v': array([-1.3583255], dtype=float32),\n", - " 'a': array([1.9194802], dtype=float32),\n", - " 'z': array([0.76933956], dtype=float32),\n", - " 't': array([0.85600656], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.14019692], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 1.0339839e+00],\n", - " [ 1.0211202e+00],\n", - " [ 9.7800064e-01],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 1.9194802 , 1.9193391 , 1.9191979 , ..., -0.9026922 ,\n", - " -0.90283334, -0.90297425], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[1.76377082, 1. ],\n", - " [1.77377069, 1. ],\n", - " [1.61377048, 1. ],\n", - " ...,\n", - " [1.95776832, 1. ],\n", - " [1.74777079, 1. ],\n", - " [1.8307699 , 1. ]]),\n", - " 'labels': array([1.3629639, 1.579064 , 0.8027136, 1.5157704, 1.1332113],\n", - " dtype=float32),\n", - " 'meta': {'v': array([1.3629639], dtype=float32),\n", - " 'a': array([1.579064], dtype=float32),\n", - " 'z': array([0.8027136], dtype=float32),\n", - " 't': array([1.5157704], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([1.1332113], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 9.5600820e-01],\n", - " [ 9.7418803e-01],\n", - " [ 9.7369546e-01],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 1.579064 , 1.5769265, 1.574789 , ..., -41.166893 ,\n", - " -41.16903 , -41.171165 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[ 1.31482685, -1. ],\n", - " [ 1.34382689, -1. ],\n", - " [ 1.57382441, -1. ],\n", - " ...,\n", - " [ 1.71682262, -1. ],\n", - " [ 1.47482562, -1. ],\n", - " [ 1.4528259 , -1. ]]),\n", - " 'labels': array([-1.5496522 , 2.5096037 , 0.22222184, 1.1238266 , 0.43571863],\n", - " dtype=float32),\n", - " 'meta': {'v': array([-1.5496522], dtype=float32),\n", - " 'a': array([2.5096037], dtype=float32),\n", - " 'z': array([0.22222184], dtype=float32),\n", - " 't': array([1.1238266], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.43571863], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ -1.3942262],\n", - " [ -1.390434 ],\n", - " [ -1.4434246],\n", - " ...,\n", - " [-999. ],\n", - " [-999. ],\n", - " [-999. ]], dtype=float32),\n", - " 'boundary': array([ 2.5096037, 2.509138 , 2.5086727, ..., -6.80068 , -6.8011456,\n", - " -6.801611 ], dtype=float32),\n", - " 'model': 'angle'}},\n", - " {'features: ': array([[1.96486604, 1. ],\n", - " [1.91186666, 1. ],\n", - " [1.88486707, 1. ],\n", - " ...,\n", - " [1.74086714, 1. ],\n", - " [1.64786708, 1. ],\n", - " [1.78686726, 1. ]]),\n", - " 'labels': array([-0.1372501 , 0.71668977, 0.7275491 , 1.608867 , 0.44358554],\n", - " dtype=float32),\n", - " 'meta': {'v': array([-0.1372501], dtype=float32),\n", - " 'a': array([0.71668977], dtype=float32),\n", - " 'z': array([0.7275491], dtype=float32),\n", - " 't': array([1.608867], dtype=float32),\n", - " 's': 1.0,\n", - " 'theta': array([0.44358554], dtype=float32),\n", - " 'delta_t': 0.0010000000474974513,\n", - " 'max_t': 20.0,\n", - " 'n_samples': 1000,\n", - " 'simulator': 'ddm_flexbound',\n", - " 'boundary_fun_type': 'angle',\n", - " 'possible_choices': [-1, 1],\n", - " 'trajectory': array([[ 3.2616419e-01],\n", - " [ 3.5521433e-01],\n", - " [ 3.6585027e-01],\n", - " ...,\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02],\n", - " [-9.9900000e+02]], dtype=float32),\n", - " 'boundary': array([ 0.71668977, 0.7162146 , 0.7157394 , ..., -8.785724 ,\n", - " -8.786199 , -8.786674 ], dtype=float32),\n", - " 'model': 'angle'}}]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "training_data[0]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "max_n_trials = 3000\n", - "mydict = {\n", - " 0: {\"features\": np.zeros((max_n_trials, 2)), \"labels\": np.ones(4)},\n", - " 1: {\"features\": np.zeros((max_n_trials, 2)), \"labels\": np.ones(4)},\n", - "}\n", - "\n", - "\n", - "n_trials = int(np.random.uniform(low=500, high=3000))\n", - "n_batch = 2\n", - "\n", - "# Inside the dataloader\n", - "my_batch = np.zeros((n_batch, n_trials, 2))\n", - "\n", - "for i in range(n_batch):\n", - " my_batch[i, :, :] = mydict[i][\"features\"][\n", - " np.random.choice(max_n_trials, n_trials, replace=False), :\n", - " ]" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 1488, 2)" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "my_batch.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([4, 5])" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.random.choice(10, 2, replace=False)" + "training_data = my_dataset_generator.generate_data_training_uniform(save=False)" ] }, { @@ -1089,10 +692,13 @@ } ], "metadata": { + "interpreter": { + "hash": "c2404e761a8d4e2a34f63613cf4c9a9997cd3109cabb959a7904b2035989131a" + }, "kernelspec": { "display_name": "ssms_dev", "language": "python", - "name": "python3" + "name": "ssms_dev" }, "language_info": { "codemirror_mode": { diff --git a/notebooks/basic_tutorial_12122024.ipynb b/notebooks/basic_tutorial_12122024.ipynb new file mode 100755 index 0000000..928cc28 --- /dev/null +++ b/notebooks/basic_tutorial_12122024.ipynb @@ -0,0 +1,464 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quick Start" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `ssms` package serves two purposes. \n", + "\n", + "1. Easy access to *fast simulators of sequential sampling models*\n", + " \n", + "2. Support infrastructure to construct training data for various approaches to likelihood / posterior amortization\n", + "\n", + "We provide two minimal examples here to illustrate how to use each of the two capabilities.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Install \n", + "\n", + "Let's start with *installing* the `ssms` package.\n", + "\n", + "You can do so by typing,\n", + "\n", + "`pip install ssm-simulators`\n", + "\n", + "in your terminal.\n", + "\n", + "Below you find a basic tutorial on how to use the package." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Tutorial" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import necessary packages\n", + "import numpy as np\n", + "import pandas as pd\n", + "import ssms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Using the Simulators\n", + "\n", + "Let's start with using the basic simulators. \n", + "You access the main simulators through the `ssms.basic_simulators.simulator.simulator()` function.\n", + "\n", + "To get an idea about the models included in `ssms`, use the `config` module.\n", + "The central dictionary with metadata about included models sits in `ssms.config.model_config`. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['ddm',\n", + " 'ddm_legacy',\n", + " 'angle',\n", + " 'weibull',\n", + " 'levy',\n", + " 'levy_angle',\n", + " 'full_ddm',\n", + " 'full_ddm_rv',\n", + " 'ddm_st',\n", + " 'ddm_truncnormt']" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check included models\n", + "list(ssms.config.model_config.keys())[:10]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'ddm',\n", + " 'params': ['v', 'a', 'z', 't'],\n", + " 'param_bounds': [[-3.0, 0.3, 0.1, 0.0], [3.0, 2.5, 0.9, 2.0]],\n", + " 'boundary_name': 'constant',\n", + " 'boundary': float | numpy.ndarray>,\n", + " 'boundary_params': [],\n", + " 'n_params': 4,\n", + " 'default_params': [0.0, 1.0, 0.5, 0.001],\n", + " 'nchoices': 2,\n", + " 'n_particles': 1,\n", + " 'simulator': }" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Take an example config for a given model\n", + "ssms.config.model_config[\"ddm\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note:**\n", + "The usual structure of these models includes,\n", + "\n", + "- Parameter names (`'params'`)\n", + "- Bounds on the parameters (`'param_bounds'`)\n", + "- A function that defines a boundary for the respective model (`'boundary'`)\n", + "- The number of parameters (`'n_params'`)\n", + "- Defaults for the parameters (`'default_params'`)\n", + "- The number of choices the process can produce (`'nchoices'`)\n", + "\n", + "The `'hddm_include'` key concerns information useful for integration with the [hddm](https://github.com/hddm-devs/hddm) python package, which facilitates hierarchical bayesian inference for sequential sampling models. It is not important for the present tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'a': array([0.7], dtype=float32), 'z': array([0.5], dtype=float32), 't': array([0.5], dtype=float32), 'ptarget': array([-5.], dtype=float32), 'pouter': array([5.], dtype=float32), 'r': array([0.01], dtype=float32), 'sda': array([1.], dtype=float32), 'deadline': array([999.], dtype=float32), 's': array([1.], dtype=float32), 'v': array([0.], dtype=float32)}\n", + "{'boundary_params': {}, 'boundary_fun': , 'boundary_multiplicative': True}\n", + "{'drift_fun': , 'drift_params': {'ptarget': array([-5.], dtype=float32), 'pouter': array([5.], dtype=float32), 'r': array([0.01], dtype=float32), 'sda': array([1.], dtype=float32)}}\n", + "{'n_samples': 10000, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': None, 'n_trials': 1}\n", + "{'name': 'shrink_spot_simple_extended', 'params': ['a', 'z', 't', 'ptarget', 'pouter', 'r', 'sda'], 'param_bounds': [[0.3, 0.1, 0.001, 2.0, -5.5, 0.01, 1], [3.0, 0.9, 2.0, 5.5, 5.5, 1.0, 3]], 'boundary_name': 'constant', 'boundary': , 'drift_name': 'attend_drift_simple', 'drift_fun': , 'n_params': 7, 'default_params': [0.7, 0.5, 0.25, 2.0, -2.0, 0.01, 1], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n", + "{'a': array([0.7], dtype=float32), 'z': array([0.5], dtype=float32), 't': array([0.5], dtype=float32), 'ptarget': array([5.], dtype=float32), 'pouter': array([-5.], dtype=float32), 'r': array([0.01], dtype=float32), 'sda': array([1.], dtype=float32), 'deadline': array([999.], dtype=float32), 's': array([1.], dtype=float32), 'v': array([0.], dtype=float32)}\n", + "{'boundary_params': {}, 'boundary_fun': , 'boundary_multiplicative': True}\n", + "{'drift_fun': , 'drift_params': {'ptarget': array([5.], dtype=float32), 'pouter': array([-5.], dtype=float32), 'r': array([0.01], dtype=float32), 'sda': array([1.], dtype=float32)}}\n", + "{'n_samples': 10000, 'delta_t': 0.001, 'max_t': 20, 'smooth_unif': True, 'return_option': 'full', 'random_state': None, 'n_trials': 1}\n", + "{'name': 'shrink_spot_simple_extended', 'params': ['a', 'z', 't', 'ptarget', 'pouter', 'r', 'sda'], 'param_bounds': [[0.3, 0.1, 0.001, 2.0, -5.5, 0.01, 1], [3.0, 0.9, 2.0, 5.5, 5.5, 1.0, 3]], 'boundary_name': 'constant', 'boundary': , 'drift_name': 'attend_drift_simple', 'drift_fun': , 'n_params': 7, 'default_params': [0.7, 0.5, 0.25, 2.0, -2.0, 0.01, 1], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n" + ] + } + ], + "source": [ + "from ssms.basic_simulators.simulator import simulator\n", + "\n", + "sim_out = simulator(\n", + " model=\"shrink_spot_simple_extended\",\n", + " theta={\n", + " \"a\": 0.7,\n", + " \"z\": 0.5,\n", + " \"t\": 0.5,\n", + " \"ptarget\": -5,\n", + " \"pouter\": 5,\n", + " \"r\": 0.01,\n", + " \"sda\": 1,\n", + " },\n", + " n_samples=10000,\n", + ")\n", + "\n", + "sim_out2 = simulator(\n", + " model=\"shrink_spot_simple_extended\",\n", + " theta={\n", + " \"a\": 0.7,\n", + " \"z\": 0.5,\n", + " \"t\": 0.5,\n", + " \"ptarget\": 5,\n", + " \"pouter\": -5,\n", + " \"r\": 0.01,\n", + " \"sda\": 1,\n", + " },\n", + " n_samples=10000,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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SktL0+HDh/Xuu+8qIyND99xzj6KjoyVJP/zhD+Xn56d58+bp+PHj2rFjh9avX6+srCy3HTgAADCuTt9G/ac//Um33nqr83VzqJgzZ45yc3O1aNEi1dTU6KGHHlJlZaW+/e1va+/evQoICHB+5qWXXlJGRoZuv/12+fj4aObMmfrFL37hXB8SEqK3335b6enpGjt2rMLDw5Wdnc0t1AAAQFIXAkxSUpIcDker600mk1auXKmVK1e2WhMaGqpt27a1uZ8xY8boD3/4Q2fbAwAA14BecxcSAAC4dhBgAACA4RBgAACA4XR6DAwAwBhOVlS3ub5/Xz8NtAZ2UzeAexFgAKCX6d/XT4G+ZmXuKG6zLtDXrP2P3EKIgSERYACglxloDdT+R27R+Zq6VmtOVlQrc0exztfUEWBgSAQYAOiFBloDCSbo1RjECwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADIcAAwAADKePtxsAcJUqS6WL59qv++Kvnu8FALoJAQYwsspSaeN4qf5ix+p9g6SgMM/2BADdgAADGNnFc03hZcYWKfym9uuDwiRrjOf7AgAPI8AAvUH4TVJ0gre7AIBuwyBeAABgOAQYAABgOAQYAABgOAQYAABgOAziBQBv6+hcPtxFBjgRYADAmzozl49vkJR+mBADyAOXkJYvXy6TyeSyDBs2zLn+8uXLSk9PV1hYmPr166eZM2eqvLzcZRunTp3StGnTFBQUpIiICD366KO6cuWKu1sFAO/76lw+DxW0vszY0lTXkTM1wDXAI2dgRo4cqf379/9rJ33+tZuHH35Yu3fv1m9/+1uFhIQoIyNDM2bM0LvvvitJamho0LRp0xQVFaX33ntPZWVlmj17tnx9ffXEE094ol0A8D7m8gE6xSMBpk+fPoqKivra+1VVVXr++ee1bds23XbbbZKkF198UcOHD9f777+viRMn6u2339ZHH32k/fv3KzIyUgkJCVq1apUWL16s5cuXy8/PzxMtA8A16WRFdbs1/fv6aaA1sBu6ATrOIwHmb3/7m6KjoxUQEKDExEStXr1agwcPVlFRkerr65WcnOysHTZsmAYPHqzCwkJNnDhRhYWFGj16tCIjI501qampWrBggY4fP65vfvObLe6ztrZWtbW1ztd2u90ThwYAvUL/vn4K9DUrc0dxu7WBvmbtf+QWQgx6FLcHmAkTJig3N1dDhw5VWVmZVqxYoe985zv68MMPZbPZ5OfnJ6vV6vKZyMhI2Ww2SZLNZnMJL83rm9e1ZvXq1VqxYoV7DwYAeqmB1kDtf+QWna+pa7PuZEW1MncU63xNHQEGPYrbA8zUqVOdfx4zZowmTJig2NhYvfLKKwoM9Nz/+ZcsWaKsrCzna7vdrpgYRuoDQGsGWgMJJTAsj99GbbVaddNNN+nkyZP67ne/q7q6OlVWVrqchSkvL3eOmYmKitLhw4ddttF8l1JL42qa+fv7y9/f3/0HAMDF6cpL7f6rnTETADzN4wGmurpan376qWbNmqWxY8fK19dX+fn5mjlzpiTpxIkTOnXqlBITEyVJiYmJ+p//+R9VVFQoIiJCkpSXlyeLxaIRI0Z4ul0AbThdeUnJawt0qb6hzTrGTADwNLcHmJ/85Ce68847FRsbqzNnzmjZsmUym8269957FRISonnz5ikrK0uhoaGyWCxauHChEhMTNXHiRElSSkqKRowYoVmzZmnNmjWy2WxaunSp0tPTOcMCeNn5mjpdqm9Qzt0JGhLRr8Wa5jETR0q+1PlWappxpgZAV7k9wHz++ee69957de7cOV133XX69re/rffff1/XXXedJGndunXy8fHRzJkzVVtbq9TUVD3zzDPOz5vNZu3atUsLFixQYmKi+vbtqzlz5mjlypXubhVAFw2J6KdRA0NaXMfdLQC6g9sDzPbt29tcHxAQoI0bN2rjxo2t1sTGxmrPnj3ubg1AN+DuFgDdgWchAXA77m4B4GlufxYSAACApxFgAACA4RBgAACA4RBgAACA4RBgAACA4RBgAACA4RBgAACA4RBgAACA4RBgAACA4TATL9BTVZZKF8+1XfPFX7unF3RNZakCvviHRppKFPBFiGRq4eGWfIdAlxBggJ6oslTaOF6qv9h+rW+QFBTm+Z7QOf/8DofUX9Ruf0k726jlOwQ6jQAD9EQXzzWFlxlbpPCb2q4NCpOsMd3TFzrun99h6a3rNX9vtdbfk6Ah17VwBkbiOwS6gAAD9GThN0nRCd7uAleh1jpExx1Vuhw+WooO8XY7QK/BIF4AAGA4BBgAAGA4XEICACPp6F1LjKtBL0eAAQAjCAprulvptbSO1fsGSemH3RZiTlZUt7m+f18/DbQGumVfQEcQYADACKwxTYGkvbmBpKazNK+lNdVeZYDp39dPgb5mZe4obrMu0Nes/Y/cQohBtyHAAIBRWGO6/bLQQGug9j9yi87X1LVac7KiWpk7inW+po4Ag25DgAEAtGmgNZBggh6HAANAknS68lKb/8qW2h8HAQDdhQADQKcrLyl5bYEu1Te0Wxvoa1b/vn7d0BUAtI4AA0Dna+p0qb5BOXcnaEhEK9Pd/xN3mwDoCQgwAJyGRPTTqIFMdw+g52MmXgAAYDgEGAAAYDgEGAAAYDiMgQEAuEVHbrNnEDjchQADALgqHX3cgMQjB+A+BBigu1WWtv88m44+cbiD2pukjgnqcDU68rgBiUcOwL0IMEB3qiyVNo6X6i+2X+sb1PQE4qvU0UnqmKCuF+pIEA4Kc8vzlXjcALobAQboThfPNYWXGVuk8JvarnXTL5aOTlLH2IReJCisKQC/ltZ+rW9Q01Ouu/khkcDVIsAA3hB+kxSd0K27ZJK6a4g1pimUdORS5WtpTXUEGBgMAQYAeiNrDKEEvRrzwAAAAMMhwAAAAMPhEhLgLl64PRpwi268WwlwFwIM4A5euD0auGpeuluJGXvhDgQYwB28cHs0cNW6+W4lZuyFOxFgAHfq5tuj25thV2KWXbSjG+9WYsZeuBMBBjCojs6wKzHLLnoOZuyFuxBgAIPq6Ay7EuMJ4CYM9kUPQoAB2tKRO4ukbn/4ovSvS0PMsAuP49EE6IEIMEBrOnNnkdTtD1+UuDSEbuKlRxO0N36LM4vXNgIM0JrO3FkkdfjUeXtnV05WVHNpCD1PNw727ejdStypdG3r0QFm48aNevLJJ2Wz2RQfH68NGzZo/Pjx3m4LvUFnJp1z451FHT27Euhr1ri4UP7DDGO6yrEyHblbqflOpSMlX+o8Qf+a1GMDzI4dO5SVlaXNmzdrwoQJysnJUWpqqk6cOKGIiAhvtwcj8+Kkcx0deMt/cGFIbhwr097dSp2dU2bzrLEKa+NyKz9zxtNjA8zPf/5zpaWl6f7775ckbd68Wbt379YLL7ygxx57zMvdocfq6JmVf14aqgiIlf1SfaulDQGhqq+xSDVVbmmPgbfo1To7VuZUYccGybdwtqajc8qcq6nT/F8Xac4Lh9us60jI6QwCkef1yABTV1enoqIiLVmyxPmej4+PkpOTVVhY2OJnamtrVVtb63xdVdX0C8dut7u/wQvlUnW5+7drQF9erNP5i60HgO7U5/J5xfz+/8mn4XK7tY3mABVVDdSC33yuy/WNbVSWSTruth4lKcDXR30aLstuN7l1u0ZTfcGuxtqLOvb3MlVfaPo59T9XrhtqHfq8uFC1Jcb+GfOv+rsG1Tr0SekXaqytV/UF+7XxnfuESP3aCedX/KSGAOnlBzu2zT6B0oxnv3Y2NPifS1sGS9p1l1+b/1CxX67X2n3H9T+bP+hYPx0Q0MdHj6QOlSXAt0ufbwi6TlcCr3NbP55wXT9/XWcJcPt2m39vOxyOtgsdPdDp06cdkhzvvfeey/uPPvqoY/z48S1+ZtmyZQ5JLCwsLCwsLL1gKS0tbTMr9MgzMF2xZMkSZWVlOV83Njbqyy+/VFhYmEwmY/yrx263KyYmRqWlpbJYLN5uB+3g+zIevjNj4fsyHnd8Zw6HQxcuXFB0dHSbdT0ywISHh8tsNqu83PUUcnl5uaKiolr8jL+/v/z9/V3es1qtnmrRoywWCz+sBsL3ZTx8Z8bC92U8V/udhYSEtFvj0+Wte5Cfn5/Gjh2r/Px853uNjY3Kz89XYmKiFzsDAAA9QY88AyNJWVlZmjNnjm6++WaNHz9eOTk5qqmpcd6VBAAArl09NsDcfffdOnv2rLKzs2Wz2ZSQkKC9e/cqMjLS2615jL+/v5YtW/a1S2Homfi+jIfvzFj4voynO78zk8PR3n1KAAAAPUuPHAMDAADQFgIMAAAwHAIMAAAwHAIMAAAwHAJMD1dbW6uEhASZTCYVFxd7ux204rPPPtO8efMUFxenwMBA3XDDDVq2bJnq6tp+0By6z8aNG3X99dcrICBAEyZM0OHDbT/cD96zevVqjRs3TsHBwYqIiND06dN14sQJb7eFDvrZz34mk8mkzMxMj+6HANPDLVq0qN3plOF9n3zyiRobG/XLX/5Sx48f17p167R582b99Kc/9XZrkLRjxw5lZWVp2bJl+vOf/6z4+HilpqaqoqLC262hBQUFBUpPT9f777+vvLw81dfXKyUlRTU1Nd5uDe04cuSIfvnLX2rMmDEe3xe3Ufdgb731lrKysvR///d/GjlypI4ePaqEhARvt4UOevLJJ7Vp0yb9/e9/93Yr17wJEyZo3LhxevrppyU1zewdExOjhQsX6rHHHvNyd2jP2bNnFRERoYKCAk2ePNnb7aAV1dXV+ta3vqVnnnlGjz/+uBISEpSTk+Ox/XEGpocqLy9XWlqafv3rXysoKMjb7aALqqqqFBoa6u02rnl1dXUqKipScnKy8z0fHx8lJyersLDQi52ho6qqqiSJn6ceLj09XdOmTXP5WfOkHjsT77XM4XBo7ty5mj9/vm6++WZ99tln3m4JnXTy5Elt2LBBTz31lLdbueZ98cUXamho+Nos3pGRkfrkk0+81BU6qrGxUZmZmZo0aZJGjRrl7XbQiu3bt+vPf/6zjhw50m375AxMN3rsscdkMpnaXD755BNt2LBBFy5c0JIlS7zd8jWvo9/ZV50+fVpTpkzR97//faWlpXmpc6B3SE9P14cffqjt27d7uxW0orS0VP/93/+tl156SQEBAd22X8bAdKOzZ8/q3LlzbdZ84xvf0A9+8AO9+eabMplMzvcbGhpkNpt13333aevWrZ5uFf/U0e/Mz89PknTmzBklJSVp4sSJys3NlY8P/0bwtrq6OgUFBenVV1/V9OnTne/PmTNHlZWVeuONN7zXHNqUkZGhN954QwcPHlRcXJy320ErXn/9dd11110ym83O9xoaGmQymeTj46Pa2lqXde5CgOmBTp06Jbvd7nx95swZpaam6tVXX9WECRM0aNAgL3aH1pw+fVq33nqrxo4dq9/85jce+YFF10yYMEHjx4/Xhg0bJDVdlhg8eLAyMjIYxNsDORwOLVy4UDt37tSBAwd04403ersltOHChQv6xz/+4fLe/fffr2HDhmnx4sUeu/THGJgeaPDgwS6v+/XrJ0m64YYbCC891OnTp5WUlKTY2Fg99dRTOnv2rHNdVFSUFzuDJGVlZWnOnDm6+eabNX78eOXk5Kimpkb333+/t1tDC9LT07Vt2za98cYbCg4Ols1mkySFhIQoMDDQy93h3wUHB38tpPTt21dhYWEeHbdEgAHcIC8vTydPntTJkye/FjI5yel9d999t86ePavs7GzZbDYlJCRo7969XxvYi55h06ZNkqSkpCSX91988UXNnTu3+xtCj8QlJAAAYDiMMAQAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIZDgAEAAIbz/wE/YiocvRZaEgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import pyplot as plt\n", + "plt.hist(sim_out[\"rts\"] * sim_out['choices'], histtype = 'step', bins = 40, label='sim_out')\n", + "plt.hist(sim_out2[\"rts\"] * sim_out2['choices'], histtype = 'step', bins = 40, label='sim_out2')\n", + "plt.legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The output of the simulator is a `dictionary` with three elements.\n", + "\n", + "1. `rts` (array)\n", + "2. `choices` (array)\n", + "3. `metadata` (dictionary)\n", + "\n", + "The `metadata` includes the named parameters, simulator settings, and more." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Using the Training Data Generators\n", + "\n", + "The training data generators sit on top of the simulator function to turn raw simulations into usable training data for training machine learning algorithms aimed at posterior or likelihood armortization.\n", + "\n", + "We will use the `data_generator` class from `ssms.dataset_generators`. Initializing the `data_generator` boils down to supplying two configuration dictionaries.\n", + "\n", + "1. The `generator_config`, concerns choices as to what kind of training data one wants to generate.\n", + "2. The `model_config` concerns choices with respect to the underlying generative *sequential sampling model*. \n", + "\n", + "We will consider a basic example here, concerning data generation to prepare for training [LANs](https://elifesciences.org/articles/65074).\n", + "\n", + "Let's start by peeking at an example `generator_config`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'output_folder': 'data/lan_mlp/',\n", + " 'model': 'ddm',\n", + " 'nbins': 0,\n", + " 'n_samples': 100000,\n", + " 'n_parameter_sets': 10000,\n", + " 'n_parameter_sets_rejected': 100,\n", + " 'n_training_samples_by_parameter_set': 1000,\n", + " 'max_t': 20.0,\n", + " 'delta_t': 0.001,\n", + " 'pickleprotocol': 4,\n", + " 'n_cpus': 'all',\n", + " 'kde_data_mixture_probabilities': [0.8, 0.1, 0.1],\n", + " 'simulation_filters': {'mode': 20,\n", + " 'choice_cnt': 0,\n", + " 'mean_rt': 17,\n", + " 'std': 0,\n", + " 'mode_cnt_rel': 0.95},\n", + " 'negative_rt_cutoff': -66.77497,\n", + " 'n_subruns': 10,\n", + " 'bin_pointwise': False,\n", + " 'separate_response_channels': False,\n", + " 'smooth_unif': True}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ssms.config.data_generator_config[\"lan\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You usually have to make just few changes to this basic configuration dictionary.\n", + "An example below." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from copy import deepcopy\n", + "\n", + "# Initialize the generator config (for MLP LANs)\n", + "generator_config = deepcopy(ssms.config.data_generator_config[\"lan\"])\n", + "# Specify generative model (one from the list of included models mentioned above)\n", + "generator_config[\"dgp_list\"] = \"angle\"\n", + "# Specify number of parameter sets to simulate\n", + "generator_config[\"n_parameter_sets\"] = 100\n", + "# Specify how many samples a simulation run should entail\n", + "generator_config[\"n_samples\"] = 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define our corresponding `model_config`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary_name': 'angle', 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'nchoices': 2, 'n_particles': 1, 'simulator': }\n" + ] + } + ], + "source": [ + "model_config = ssms.config.model_config[\"angle\"]\n", + "print(model_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are now ready to initialize a `data_generator`, after which we can generate training data using the `generate_data_training_uniform` function, which will use the hypercube defined by our parameter bounds from the `model_config` to uniformly generate parameter sets and corresponding simulated datasets." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "n_cpus used: 12\n", + "checking: data/lan_mlp/\n" + ] + } + ], + "source": [ + "my_dataset_generator = ssms.dataset_generators.lan_mlp.data_generator(\n", + " generator_config=generator_config, model_config=model_config\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "simulation round: 1 of 10\n", + "simulation round: 2 of 10\n", + "simulation round: 3 of 10\n", + "simulation round: 4 of 10\n", + "simulation round: 5 of 10\n", + "simulation round: 6 of 10\n", + "simulation round: 7 of 10\n", + "simulation round: 8 of 10\n", + "simulation round: 9 of 10\n", + "simulation round: 10 of 10\n" + ] + } + ], + "source": [ + "training_data = my_dataset_generator.generate_data_training_uniform(save=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`training_data` is a dictionary containing four keys:\n", + "\n", + "1. `data` the features for [LANs](https://elifesciences.org/articles/65074), containing vectors of *model parameters*, as well as *rts* and *choices*.\n", + "2. `labels` which contain approximate likelihood values\n", + "3. `generator_config`, as defined above\n", + "4. `model_config`, as defined above" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can now use this training data for your purposes. If you want to train [LANs](https://elifesciences.org/articles/65074) yourself, you might find the [LANfactory](https://github.com/AlexanderFengler/LANfactory) package helpful.\n", + "\n", + "You may also simply find the basic simulators provided with the **ssms** package useful, without any desire to use the outputs into training data for amortization purposes.\n", + "\n", + "##### END" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "c2404e761a8d4e2a34f63613cf4c9a9997cd3109cabb959a7904b2035989131a" + }, + "kernelspec": { + "display_name": "ssms_dev", + "language": "python", + "name": "ssms_dev" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + }, + "orig_nbformat": 2 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/basic_tutorial_old.ipynb b/notebooks/basic_tutorial_old.ipynb new file mode 100755 index 0000000..59c491f --- /dev/null +++ b/notebooks/basic_tutorial_old.ipynb @@ -0,0 +1,1113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Quick Start" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `ssms` package serves two purposes. \n", + "\n", + "1. Easy access to *fast simulators of sequential sampling models*\n", + " \n", + "2. Support infrastructure to construct training data for various approaches to likelihood / posterior amortization\n", + "\n", + "We provide two minimal examples here to illustrate how to use each of the two capabilities.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Install \n", + "\n", + "Let's start with *installing* the `ssms` package.\n", + "\n", + "You can do so by typing,\n", + "\n", + "`pip install git+https://github.com/AlexanderFengler/ssm_simulators`\n", + "\n", + "in your terminal.\n", + "\n", + "Below you find a basic tutorial on how to use the package." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Tutorial" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Import necessary packages\n", + "import numpy as np\n", + "import pandas as pd\n", + "import ssms" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3 2 1\n" + ] + } + ], + "source": [ + "def myfun(a, b, c):\n", + "\tprint(a, b, c)\n", + "\n", + "myfun(**{'c': 1, 'b': 2, 'a': 3})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Using the Simulators\n", + "\n", + "Let's start with using the basic simulators. \n", + "You access the main simulators through the `ssms.basic_simulators.simulator` function.\n", + "\n", + "To get an idea about the models included in `ssms`, use the `config` module.\n", + "The central dictionary with metadata about included models sits in `ssms.config.model_config`. " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['ddm',\n", + " 'ddm_legacy',\n", + " 'angle',\n", + " 'weibull',\n", + " 'levy',\n", + " 'levy_angle',\n", + " 'full_ddm',\n", + " 'full_ddm_rv',\n", + " 'ddm_st',\n", + " 'ddm_truncnormt',\n", + " 'ddm_rayleight',\n", + " 'ddm_sdv',\n", + " 'gamma_drift',\n", + " 'shrink_spot',\n", + " 'shrink_spot_extended',\n", + " 'gamma_drift_angle',\n", + " 'ds_conflict_drift',\n", + " 'ds_conflict_drift_angle',\n", + " 'ornstein',\n", + " 'ornstein_angle',\n", + " 'lba2',\n", + " 'lba3',\n", + " 'lba_3_v1',\n", + " 'lba_angle_3_v1',\n", + " 'rlwm_lba_race_v1',\n", + " 'race_2',\n", + " 'race_no_bias_2',\n", + " 'race_no_z_2',\n", + " 'race_no_bias_angle_2',\n", + " 'race_no_z_angle_2',\n", + " 'race_3',\n", + " 'race_no_bias_3',\n", + " 'race_no_z_3',\n", + " 'race_no_bias_angle_3',\n", + " 'race_no_z_angle_3',\n", + " 'race_4',\n", + " 'race_no_bias_4',\n", + " 'race_no_z_4',\n", + " 'race_no_bias_angle_4',\n", + " 'race_no_z_angle_4',\n", + " 'lca_3',\n", + " 'lca_no_bias_3',\n", + " 'lca_no_z_3',\n", + " 'lca_no_bias_angle_3',\n", + " 'lca_no_z_angle_3',\n", + " 'lca_4',\n", + " 'lca_no_bias_4',\n", + " 'lca_no_z_4',\n", + " 'lca_no_bias_angle_4',\n", + " 'lca_no_z_angle_4',\n", + " 'ddm_par2',\n", + " 'ddm_par2_no_bias',\n", + " 'ddm_par2_conflict_gamma_no_bias',\n", + " 'ddm_par2_angle_no_bias',\n", + " 'ddm_par2_weibull_no_bias',\n", + " 'ddm_seq2',\n", + " 'ddm_seq2_no_bias',\n", + " 'ddm_seq2_conflict_gamma_no_bias',\n", + " 'ddm_seq2_angle_no_bias',\n", + " 'ddm_seq2_weibull_no_bias',\n", + " 'ddm_mic2_adj',\n", + " 'ddm_mic2_adj_no_bias',\n", + " 'ddm_mic2_adj_conflict_gamma_no_bias',\n", + " 'ddm_mic2_adj_angle_no_bias',\n", + " 'ddm_mic2_adj_weibull_no_bias',\n", + " 'ddm_mic2_ornstein',\n", + " 'ddm_mic2_ornstein_no_bias',\n", + " 'ddm_mic2_ornstein_conflict_gamma_no_bias',\n", + " 'ddm_mic2_ornstein_angle_no_bias',\n", + " 'ddm_mic2_ornstein_weibull_no_bias',\n", + " 'ddm_mic2_multinoise_no_bias',\n", + " 'ddm_mic2_multinoise_conflict_gamma_no_bias',\n", + " 'ddm_mic2_multinoise_angle_no_bias',\n", + " 'ddm_mic2_multinoise_weibull_no_bias',\n", + " 'ddm_mic2_leak',\n", + " 'ddm_mic2_leak_no_bias',\n", + " 'ddm_mic2_leak_conflict_gamma_no_bias',\n", + " 'ddm_mic2_leak_angle_no_bias',\n", + " 'ddm_mic2_leak_weibull_no_bias',\n", + " 'tradeoff_no_bias',\n", + " 'tradeoff_angle_no_bias',\n", + " 'tradeoff_weibull_no_bias',\n", + " 'tradeoff_conflict_gamma_no_bias',\n", + " 'weibull_cdf',\n", + " 'full_ddm2',\n", + " 'ddm_mic2_ornstein_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_ornstein_angle_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_ornstein_weibull_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_ornstein_conflict_gamma_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_leak_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_leak_angle_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_leak_weibull_no_bias_no_lowdim_noise',\n", + " 'ddm_mic2_leak_conflict_gamma_no_bias_no_lowdim_noise']" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check included models\n", + "list(ssms.config.model_config.keys())" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'ddm_deadline'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[3], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mssms\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel_config\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mddm_deadline\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n", + "\u001b[0;31mKeyError\u001b[0m: 'ddm_deadline'" + ] + } + ], + "source": [ + "ssms.config.model_config[\"ddm_deadline\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'ddm',\n", + " 'params': ['v', 'a', 'z', 't'],\n", + " 'param_bounds': [[-3.0, 0.3, 0.1, 0.0], [3.0, 2.5, 0.9, 2.0]],\n", + " 'boundary_name': 'constant',\n", + " 'boundary': float | numpy.ndarray>,\n", + " 'boundary_params': [],\n", + " 'n_params': 4,\n", + " 'default_params': [0.0, 1.0, 0.5, 0.001],\n", + " 'nchoices': 2,\n", + " 'n_particles': 1,\n", + " 'simulator': }" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Take an example config for a given model\n", + "ssms.config.model_config[\"ddm\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from ssms.basic_simulators.simulator import simulator\n", + "\n", + "sim_out = simulator(\n", + "\tmodel=\"lba2\", theta={'A': 0.3, 'b': 0.5, 'v0': 0.5, 'v1': 0.5},\n", + "\t\t\t\t\t\t n_samples=10\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n", + " 1., 1., 1.])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.tile(np.ones(2), (10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note:**\n", + "The usual structure of these models includes,\n", + "\n", + "- Parameter names (`'params'`)\n", + "- Bounds on the parameters (`'param_bounds'`)\n", + "- A function that defines a boundary for the respective model (`'boundary'`)\n", + "- The number of parameters (`'n_params'`)\n", + "- Defaults for the parameters (`'default_params'`)\n", + "- The number of choices the process can produce (`'nchoices'`)\n", + "\n", + "The `'hddm_include'` key concerns information useful for integration with the [hddm](https://github.com/hddm-devs/hddm) python package, which facilitates hierarchical bayesian inference for sequential sampling models. It is not important for the present tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "from ssms.basic_simulators.simulator import simulator\n", + "\n", + "p_choice_vec = []\n", + "dline_tmp_vec = []\n", + "for dline_tmp in np.linspace(0.2, 5, 50):\n", + " sim_out = simulator(\n", + " model=\"ddm_deadline\", theta=[1.0, 1.0, 0.5, 0.1, dline_tmp], n_samples=10000\n", + " )\n", + " p_choice_vec.append(np.sum(sim_out[\"choices\"] == 1.0) / sim_out[\"choices\"].shape[0])\n", + " dline_tmp_vec.append(dline_tmp)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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M1VaWtru9atXr1ZRUZHz2L17t8xms2699VbnNb/61a/029/+VitWrNCWLVsUFBSkzMxM1dfXd/6TuZF9RdWS6A4CAKCzXA4sS5cu1X333ae5c+dq1KhRWrFihQIDA/Xqq6+2e33//v0VExPjPNatW6fAwEBnYHE4HFq2bJkWLlyom266SampqfrjH/+owsJCvffeexf14dzFgdYWlphQgysBAKB3cimwNDY2KicnRxkZGd8+wMtLGRkZ2rRpU4ee8corr+i2225TUFCQJOno0aMqLi5u88ywsDClp6ef85kNDQ2yWCxtDne2v7ilhWVkLC0sAAB0hkuBpby8XDabTdHR0W3OR0dHq7i4+IL3b926Vbt379a9997rPNd6nyvPXLJkicLCwpxHYmKiKx+jR1XVNqmoqqVrKzmawAIAQGf06CyhV155RWPGjNHEiRMv6jkLFixQVVWV88jPz++iCrte64DbhH4BCmGFWwAAOsWlwBIRESGz2aySkpI250tKShQTE3Pee61Wq9566y3dc889bc633ufKM/38/BQaGtrmcFet3UGMXwEAoPNcCiy+vr4aP368srOznefsdruys7M1adKk8977zjvvqKGhQXfeeWeb80OGDFFMTEybZ1osFm3ZsuWCz+wNnFOamSEEAECnebt6Q1ZWlubMmaMJEyZo4sSJWrZsmaxWq+bOnStJmj17tuLj47VkyZI2973yyiu6+eabNWBA252KTSaTHnnkET3zzDMaPny4hgwZoieeeEJxcXG6+eabO//J3ETrlOYRDLgFAKDTXA4sM2fOVFlZmRYtWqTi4mKlpaVp7dq1zkGzeXl58vJq23Bz4MABbdy4UR9//HG7z3zsscdktVp1//33q7KyUlOmTNHatWvl7+/fiY/kPux2hw6W0CUEAMDFMjkcDofRRVwsi8WisLAwVVVVudV4luMVVl39/Hr5entp71OZ8jazEwIAAK1ceX/zBu1Grd1BydHBhBUAAC4Cb9FudIAZQgAAdAkCSzdihhAAAF2DwNKNWIMFAICuQWDpJnWNNh2rsEpiSjMAABeLwNJNDpZUy+GQIoJ9FRHsZ3Q5AAD0agSWbvLt+BW6gwAAuFgElm7y7fgVuoMAALhYBJZusv/0GiwpBBYAAC4agaUbOBwOZ5fQyFi6hAAAuFgElm5QVt2gU7VN8jJJw6KCjS4H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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import pyplot as plt\n", + "\n", + "plt.plot(dline_tmp_vec, p_choice_vec)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 2., 0., 2., 2., 4., 4., 2., 5., 7.,\n", + " 5., 15., 15., 26., 50., 52., 62., 111., 116.,\n", + " 195., 221., 234., 45., 0., 0., 0., 0., 0.,\n", + " 263., 1796., 1810., 1326., 930., 759., 517., 400., 266.,\n", + " 205., 154., 104., 74., 60., 40., 24., 29., 17.,\n", + " 15., 15., 8., 3., 7.]),\n", + " array([-4.67442942, -4.4839405 , -4.29345158, -4.10296266, -3.91247374,\n", + " -3.72198482, -3.5314959 , -3.34100698, -3.15051805, -2.96002913,\n", + " -2.76954021, -2.57905129, -2.38856237, -2.19807345, -2.00758453,\n", + " -1.81709561, -1.62660669, -1.43611777, -1.24562885, -1.05513993,\n", + " -0.86465101, -0.67416209, -0.48367317, -0.29318425, -0.10269533,\n", + " 0.08779359, 0.27828251, 0.46877143, 0.65926035, 0.84974927,\n", + " 1.04023819, 1.23072711, 1.42121603, 1.61170495, 1.80219387,\n", + " 1.99268279, 2.18317171, 2.37366063, 2.56414955, 2.75463847,\n", + " 2.94512739, 3.13561631, 3.32610523, 3.51659415, 3.70708307,\n", + " 3.89757199, 4.08806091, 4.27854983, 4.46903875, 4.65952767,\n", + " 4.85001659]),\n", + " )" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import pyplot as plt\n", + "\n", + "plt.hist(\n", + " sim_out[\"rts\"][sim_out[\"rts\"] != -999] * sim_out[\"choices\"][sim_out[\"rts\"] != -999],\n", + " bins=50,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1.26040506, 1. ],\n", + " [ 1.56888986, -1. ],\n", + " [ 1.09187531, -1. ],\n", + " ...,\n", + " [ 0.75505078, -1. ],\n", + " [ 0.89852297, 1. ],\n", + " [ 1.17158473, -1. ]])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.hstack([sim_out[\"rts\"], sim_out[\"choices\"]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The output of the simulator is a `dictionary` with three elements.\n", + "\n", + "1. `rts` (array)\n", + "2. `choices` (array)\n", + "3. `metadata` (dictionary)\n", + "\n", + "The `metadata` includes the named parameters, simulator settings, and more." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Using the Training Data Generators\n", + "\n", + "The training data generators sit on top of the simulator function to turn raw simulations into usable training data for training machine learning algorithms aimed at posterior or likelihood armortization.\n", + "\n", + "We will use the `data_generator` class from `ssms.dataset_generators`. Initializing the `data_generator` boils down to supplying two configuration dictionaries.\n", + "\n", + "1. The `generator_config`, concerns choices as to what kind of training data one wants to generate.\n", + "2. The `model_config` concerns choices with respect to the underlying generative *sequential sampling model*. \n", + "\n", + "We will consider a basic example here, concerning data generation to prepare for training [LANs](https://elifesciences.org/articles/65074).\n", + "\n", + "Let's start by peeking at an example `generator_config`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'output_folder': 'data/lan_mlp/',\n", + " 'dgp_list': 'ddm',\n", + " 'nbins': 0,\n", + " 'n_samples': 100000,\n", + " 'n_parameter_sets': 10000,\n", + " 'n_parameter_sets_rejected': 100,\n", + " 'n_training_samples_by_parameter_set': 1000,\n", + " 'max_t': 20.0,\n", + " 'delta_t': 0.001,\n", + " 'pickleprotocol': 4,\n", + " 'n_cpus': 'all',\n", + " 'kde_data_mixture_probabilities': [0.8, 0.1, 0.1],\n", + " 'simulation_filters': {'mode': 20,\n", + " 'choice_cnt': 0,\n", + " 'mean_rt': 17,\n", + " 'std': 0,\n", + " 'mode_cnt_rel': 0.95},\n", + " 'negative_rt_cutoff': -66.77497,\n", + " 'n_subruns': 10,\n", + " 'bin_pointwise': False,\n", + " 'separate_response_channels': False}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ssms.config.data_generator_config[\"lan\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You usually have to make just few changes to this basic configuration dictionary.\n", + "An example below." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "from copy import deepcopy\n", + "\n", + "# Initialize the generator config (for MLP LANs)\n", + "generator_config = deepcopy(ssms.config.data_generator_config[\"snpe\"])\n", + "# Specify generative model (one from the list of included models mentioned above)\n", + "generator_config[\"dgp_list\"] = \"angle\"\n", + "# Specify number of parameter sets to simulate\n", + "generator_config[\"n_parameter_sets\"] = 100\n", + "# Specify how many samples a simulation run should entail\n", + "generator_config[\"n_samples\"] = 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define our corresponding `model_config`." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'angle', 'params': ['v', 'a', 'z', 't', 'theta'], 'param_bounds': [[-3.0, 0.3, 0.1, 0.001, -0.1], [3.0, 3.0, 0.9, 2.0, 1.3]], 'boundary': , 'n_params': 5, 'default_params': [0.0, 1.0, 0.5, 0.001, 0.0], 'hddm_include': ['z', 'theta'], 'nchoices': 2}\n" + ] + } + ], + "source": [ + "model_config = ssms.config.model_config[\"angle\"]\n", + "print(model_config)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are now ready to initialize a `data_generator`, after which we can generate training data using the `generate_data_training_uniform` function, which will use the hypercube defined by our parameter bounds from the `model_config` to uniformly generate parameter sets and corresponding simulated datasets." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "n_cpus used: 6\n", + "checking: data/snpe_training/\n" + ] + } + ], + "source": [ + "my_dataset_generator = ssms.dataset_generators.data_generator_snpe(\n", + " generator_config=generator_config, model_config=model_config\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "simulation round: 1 of 10\n", + "simulation round: 2 of 10\n", + "simulation round: 3 of 10\n", + "simulation round: 4 of 10\n", + "simulation round: 5 of 10\n", + "simulation round: 6 of 10\n", + "simulation round: 7 of 10\n", + "simulation round: 8 of 10\n", + "simulation round: 9 of 10\n", + "simulation round: 10 of 10\n", + "Writing to file: data/snpe_training/training_data__n_1000/angle/training_data_angle_4c70e020dace11ec9074acde48001122.pickle\n" + ] + } + ], + "source": [ + "training_data = my_dataset_generator.generate_data_training_uniform(save=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "new_features = {\n", + " i: {\n", + " \"data\": training_data[0][i][\"features\"],\n", + " \"labels\": training_data[0][i][\"labels\"],\n", + " }\n", + " for i in range(len(training_data[0]))\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "training_data.keys()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trainin" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'features: ': array([[ 4.10223436, 1. ],\n", + " [ 2.655339 , 1. ],\n", + " [ 3.40328479, 1. ],\n", + " ...,\n", + " [ 2.71133494, 1. ],\n", + " [ 0.60232329, -1. ],\n", + " [ 1.18331599, -1. ]]),\n", + " 'labels': array([ 1.2677877 , 2.0692544 , 0.17184597, 0.36032298, -0.06370651],\n", + " dtype=float32),\n", + " 'meta': {'v': array([1.2677877], dtype=float32),\n", + " 'a': array([2.0692544], dtype=float32),\n", + " 'z': array([0.17184597], dtype=float32),\n", + " 't': array([0.36032298], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([-0.06370651], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ -1.3580683],\n", + " [ -1.3061538],\n", + " [ -1.3130792],\n", + " ...,\n", + " [-999. ],\n", + " [-999. ],\n", + " [-999. ]], dtype=float32),\n", + " 'boundary': array([2.0692544, 2.0693183, 2.069382 , ..., 3.3449836, 3.3450472,\n", + " 3.345111 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[1.02261758, 1. ],\n", + " [1.04661727, 1. ],\n", + " [1.06361699, 1. ],\n", + " ...,\n", + " [0.93361747, 1. ],\n", + " [1.46661186, 1. ],\n", + " [1.03261745, 1. ]]),\n", + " 'labels': array([2.604681 , 1.3304262, 0.5099575, 0.7646173, 0.8860518],\n", + " dtype=float32),\n", + " 'meta': {'v': array([2.604681], dtype=float32),\n", + " 'a': array([1.3304262], dtype=float32),\n", + " 'z': array([0.5099575], dtype=float32),\n", + " 't': array([0.7646173], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.8860518], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 2.6495418e-02],\n", + " [ 7.9746895e-02],\n", + " [ 7.4158326e-02],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 1.3304262, 1.3292016, 1.3279768, ..., -23.160759 ,\n", + " -23.161983 , -23.163208 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[ 0.96705407, 1. ],\n", + " [ 0.935054 , 1. ],\n", + " [ 0.87205386, -1. ],\n", + " ...,\n", + " [ 0.90805393, 1. ],\n", + " [ 0.96405405, 1. ],\n", + " [ 1.02105391, 1. ]]),\n", + " 'labels': array([1.2017035 , 0.97606236, 0.39102793, 0.7560538 , 1.2579942 ],\n", + " dtype=float32),\n", + " 'meta': {'v': array([1.2017035], dtype=float32),\n", + " 'a': array([0.97606236], dtype=float32),\n", + " 'z': array([0.39102793], dtype=float32),\n", + " 't': array([0.7560538], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([1.2579942], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[-2.1272707e-01],\n", + " [-1.6087857e-01],\n", + " [-1.6787012e-01],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 0.97606236, 0.9729704 , 0.96987844, ..., -60.856857 ,\n", + " -60.859947 , -60.863037 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[ 1.00975132, -1. ],\n", + " [ 1.27174985, -1. ],\n", + " [ 1.12875164, -1. ],\n", + " ...,\n", + " [ 0.99275136, -1. ],\n", + " [ 1.25475013, -1. ],\n", + " [ 1.45274758, -1. ]]),\n", + " 'labels': array([-1.6534374 , 1.5941297 , 0.12224997, 0.8867513 , 0.23367152],\n", + " dtype=float32),\n", + " 'meta': {'v': array([-1.6534374], dtype=float32),\n", + " 'a': array([1.5941297], dtype=float32),\n", + " 'z': array([0.12224997], dtype=float32),\n", + " 't': array([0.8867513], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.23367152], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ -1.2043651],\n", + " [ -1.1553718],\n", + " [ -1.1652185],\n", + " ...,\n", + " [-999. ],\n", + " [-999. ],\n", + " [-999. ]], dtype=float32),\n", + " 'boundary': array([ 1.5941297, 1.5938916, 1.5936537, ..., -3.1657853, -3.1660233,\n", + " -3.1662607], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[ 1.26257348, -1. ],\n", + " [ 0.6515795 , 1. ],\n", + " [ 0.95757735, -1. ],\n", + " ...,\n", + " [ 0.97157717, -1. ],\n", + " [ 0.83357894, 1. ],\n", + " [ 0.77157974, -1. ]]),\n", + " 'labels': array([-1.4438915 , 0.9805305 , 0.69183505, 0.5205794 , 0.6480955 ],\n", + " dtype=float32),\n", + " 'meta': {'v': array([-1.4438915], dtype=float32),\n", + " 'a': array([0.9805305], dtype=float32),\n", + " 'z': array([0.69183505], dtype=float32),\n", + " 't': array([0.5205794], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.6480955], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 3.7620023e-01],\n", + " [ 4.2540312e-01],\n", + " [ 4.1576597e-01],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 0.9805305 , 0.9797733 , 0.97901607, ..., -14.162027 ,\n", + " -14.162784 , -14.163541 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[0.91735744, 1. ],\n", + " [1.20835662, 1. ],\n", + " [0.92935741, 1. ],\n", + " ...,\n", + " [0.90235746, 1. ],\n", + " [0.89735746, 1. ],\n", + " [1.31435525, 1. ]]),\n", + " 'labels': array([1.9964801, 1.4816018, 0.8841693, 0.8633575, 1.0173286],\n", + " dtype=float32),\n", + " 'meta': {'v': array([1.9964801], dtype=float32),\n", + " 'a': array([1.4816018], dtype=float32),\n", + " 'z': array([0.8841693], dtype=float32),\n", + " 't': array([0.8633575], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([1.0173286], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 1.1383718],\n", + " [ 1.0790156],\n", + " [ 1.0546436],\n", + " ...,\n", + " [-999. ],\n", + " [-999. ],\n", + " [-999. ]], dtype=float32),\n", + " 'boundary': array([ 1.4816018, 1.4799834, 1.478365 , ..., -30.883564 ,\n", + " -30.885181 , -30.886799 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[ 2.23801517, -1. ],\n", + " [ 1.17800593, 1. ],\n", + " [ 3.20701861, -1. ],\n", + " ...,\n", + " [ 1.28100467, 1. ],\n", + " [ 2.52602863, -1. ],\n", + " [ 3.33400941, -1. ]]),\n", + " 'labels': array([-1.3583255 , 1.9194802 , 0.76933956, 0.85600656, 0.14019692],\n", + " dtype=float32),\n", + " 'meta': {'v': array([-1.3583255], dtype=float32),\n", + " 'a': array([1.9194802], dtype=float32),\n", + " 'z': array([0.76933956], dtype=float32),\n", + " 't': array([0.85600656], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.14019692], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 1.0339839e+00],\n", + " [ 1.0211202e+00],\n", + " [ 9.7800064e-01],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 1.9194802 , 1.9193391 , 1.9191979 , ..., -0.9026922 ,\n", + " -0.90283334, -0.90297425], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[1.76377082, 1. ],\n", + " [1.77377069, 1. ],\n", + " [1.61377048, 1. ],\n", + " ...,\n", + " [1.95776832, 1. ],\n", + " [1.74777079, 1. ],\n", + " [1.8307699 , 1. ]]),\n", + " 'labels': array([1.3629639, 1.579064 , 0.8027136, 1.5157704, 1.1332113],\n", + " dtype=float32),\n", + " 'meta': {'v': array([1.3629639], dtype=float32),\n", + " 'a': array([1.579064], dtype=float32),\n", + " 'z': array([0.8027136], dtype=float32),\n", + " 't': array([1.5157704], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([1.1332113], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 9.5600820e-01],\n", + " [ 9.7418803e-01],\n", + " [ 9.7369546e-01],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 1.579064 , 1.5769265, 1.574789 , ..., -41.166893 ,\n", + " -41.16903 , -41.171165 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[ 1.31482685, -1. ],\n", + " [ 1.34382689, -1. ],\n", + " [ 1.57382441, -1. ],\n", + " ...,\n", + " [ 1.71682262, -1. ],\n", + " [ 1.47482562, -1. ],\n", + " [ 1.4528259 , -1. ]]),\n", + " 'labels': array([-1.5496522 , 2.5096037 , 0.22222184, 1.1238266 , 0.43571863],\n", + " dtype=float32),\n", + " 'meta': {'v': array([-1.5496522], dtype=float32),\n", + " 'a': array([2.5096037], dtype=float32),\n", + " 'z': array([0.22222184], dtype=float32),\n", + " 't': array([1.1238266], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.43571863], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ -1.3942262],\n", + " [ -1.390434 ],\n", + " [ -1.4434246],\n", + " ...,\n", + " [-999. ],\n", + " [-999. ],\n", + " [-999. ]], dtype=float32),\n", + " 'boundary': array([ 2.5096037, 2.509138 , 2.5086727, ..., -6.80068 , -6.8011456,\n", + " -6.801611 ], dtype=float32),\n", + " 'model': 'angle'}},\n", + " {'features: ': array([[1.96486604, 1. ],\n", + " [1.91186666, 1. ],\n", + " [1.88486707, 1. ],\n", + " ...,\n", + " [1.74086714, 1. ],\n", + " [1.64786708, 1. ],\n", + " [1.78686726, 1. ]]),\n", + " 'labels': array([-0.1372501 , 0.71668977, 0.7275491 , 1.608867 , 0.44358554],\n", + " dtype=float32),\n", + " 'meta': {'v': array([-0.1372501], dtype=float32),\n", + " 'a': array([0.71668977], dtype=float32),\n", + " 'z': array([0.7275491], dtype=float32),\n", + " 't': array([1.608867], dtype=float32),\n", + " 's': 1.0,\n", + " 'theta': array([0.44358554], dtype=float32),\n", + " 'delta_t': 0.0010000000474974513,\n", + " 'max_t': 20.0,\n", + " 'n_samples': 1000,\n", + " 'simulator': 'ddm_flexbound',\n", + " 'boundary_fun_type': 'angle',\n", + " 'possible_choices': [-1, 1],\n", + " 'trajectory': array([[ 3.2616419e-01],\n", + " [ 3.5521433e-01],\n", + " [ 3.6585027e-01],\n", + " ...,\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02],\n", + " [-9.9900000e+02]], dtype=float32),\n", + " 'boundary': array([ 0.71668977, 0.7162146 , 0.7157394 , ..., -8.785724 ,\n", + " -8.786199 , -8.786674 ], dtype=float32),\n", + " 'model': 'angle'}}]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "training_data[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "max_n_trials = 3000\n", + "mydict = {\n", + " 0: {\"features\": np.zeros((max_n_trials, 2)), \"labels\": np.ones(4)},\n", + " 1: {\"features\": np.zeros((max_n_trials, 2)), \"labels\": np.ones(4)},\n", + "}\n", + "\n", + "\n", + "n_trials = int(np.random.uniform(low=500, high=3000))\n", + "n_batch = 2\n", + "\n", + "# Inside the dataloader\n", + "my_batch = np.zeros((n_batch, n_trials, 2))\n", + "\n", + "for i in range(n_batch):\n", + " my_batch[i, :, :] = mydict[i][\"features\"][\n", + " np.random.choice(max_n_trials, n_trials, replace=False), :\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2, 1488, 2)" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_batch.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([4, 5])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.random.choice(10, 2, replace=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`training_data` is a dictionary containing four keys:\n", + "\n", + "1. `data` the features for [LANs](https://elifesciences.org/articles/65074), containing vectors of *model parameters*, as well as *rts* and *choices*.\n", + "2. `labels` which contain approximate likelihood values\n", + "3. `generator_config`, as defined above\n", + "4. `model_config`, as defined above" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can now use this training data for your purposes. If you want to train [LANs](https://elifesciences.org/articles/65074) yourself, you might find the [LANfactory](https://github.com/AlexanderFengler/LANfactory) package helpful.\n", + "\n", + "You may also simply find the basic simulators provided with the **ssms** package useful, without any desire to use the outputs into training data for amortization purposes.\n", + "\n", + "##### END" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ssms_dev", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + }, + "orig_nbformat": 2 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pyproject.toml b/pyproject.toml index c1c8b72..d27f5db 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires = ["setuptools", "wheel", "Cython>=0.29.23", "numpy >= 1.20"] [project] name= "ssm-simulators" -version= "0.7.8" +version= "0.8.3" authors= [{name = "Alexander Fenger", email = "alexander_fengler@brown.edu"}] description= "SSMS is a package collecting simulators and training data generators for a bunch of generative models of interest in the cognitive science / neuroscience and approximate bayesian computation communities" readme = "README.md" diff --git a/ssms/__init__.py b/ssms/__init__.py index 8d15da6..c21f425 100755 --- a/ssms/__init__.py +++ b/ssms/__init__.py @@ -4,6 +4,6 @@ from . import config from . import support_utils -__version__ = "0.7.8" # importlib.metadata.version(__package__ or __name__) +__version__ = "0.8.3" # importlib.metadata.version(__package__ or __name__) __all__ = ["basic_simulators", "dataset_generators", "config", "support_utils"] diff --git a/ssms/basic_simulators/drift_functions.py b/ssms/basic_simulators/drift_functions.py index 1cc49eb..a90ffc0 100755 --- a/ssms/basic_simulators/drift_functions.py +++ b/ssms/basic_simulators/drift_functions.py @@ -146,9 +146,9 @@ def ds_conflict_drift( def attend_drift( t: np.ndarray = np.arange(0, 20, 0.1), - p_target: float = -0.3, - p_outer: float = -0.3, - p_inner: float = 0.3, + ptarget: float = -0.3, + pouter: float = -0.3, + pinner: float = 0.3, r: float = 0.5, sda: float = 2, ) -> np.ndarray: @@ -160,11 +160,11 @@ def attend_drift( t: np.ndarray Timepoints at which to evaluate the drift. Usually np.arange() of some sort. - p_outer: float + pouter: float perceptual input for outer flankers - p_inner: float + pinner: float perceptual input for inner flankers - p_target: float + ptarget: float perceptual input for target flanker r: float rate parameter for sda decrease @@ -184,7 +184,47 @@ def attend_drift( -0.5, loc=0, scale=new_sda ) - v_t = 2 * p_outer * a_outer + 2 * p_inner * a_inner + p_target * a_target + v_t = (2 * pouter * a_outer) + (2 * pinner * a_inner) + (ptarget * a_target) + + return v_t + + +def attend_drift_simple( + t: np.ndarray = np.arange(0, 20, 0.1), + ptarget: float = -0.3, + pouter: float = -0.3, + r: float = 0.5, + sda: float = 2, +) -> np.ndarray: + """Drift function for shrinking spotlight model, which involves a time varying + function dependent on a linearly decreasing standard deviation of attention. + + Arguments + -------- + t: np.ndarray + Timepoints at which to evaluate the drift. + Usually np.arange() of some sort. + pouter: float + perceptual input for outer flankers + ptarget: float + perceptual input for target flanker + r: float + rate parameter for sda decrease + sda: float + width of attentional spotlight + Return + ------ + np.ndarray + Drift evaluated at timepoints t + """ + + new_sda = np.maximum(sda - r * t, 0.001) + a_outer = 1.0 - norm.cdf( + 0.5, loc=0, scale=new_sda + ) # equivalent to norm.sf(0.5, loc=0, scale=new_sda) + a_target = norm.cdf(0.5, loc=0, scale=new_sda) - 0.5 + + v_t = (2 * pouter * a_outer) + (2 * ptarget * a_target) return v_t diff --git a/ssms/basic_simulators/simulator.py b/ssms/basic_simulators/simulator.py index d16806a..7a0249d 100755 --- a/ssms/basic_simulators/simulator.py +++ b/ssms/basic_simulators/simulator.py @@ -3,6 +3,8 @@ import pandas as pd from copy import deepcopy import warnings +from numpy.random import default_rng +from threading import Lock """ This module defines the basic simulator function which is the main @@ -24,6 +26,17 @@ "smooth_unif": False, } +_global_rng = default_rng() +_rng_lock = Lock() + + +def _get_unique_seed() -> int: + """ + Generate a unique seed for the random number generator. + """ + with _rng_lock: + return _global_rng.integers(0, 2**32 - 1) + def _make_valid_dict(dict_in: dict) -> dict: """Turn all values in dictionary into numpy arrays and make sure, @@ -641,6 +654,9 @@ def simulator( if deadline: model_config_local["params"] += ["deadline"] + if random_state is None: + random_state = _get_unique_seed() + theta = _preprocess_theta_generic(theta) n_trials, theta = _preprocess_theta_deadline(theta, deadline, model_config_local) diff --git a/ssms/basic_simulators/theta_processor.py b/ssms/basic_simulators/theta_processor.py index 82b0125..937ce6b 100644 --- a/ssms/basic_simulators/theta_processor.py +++ b/ssms/basic_simulators/theta_processor.py @@ -120,7 +120,13 @@ def process_theta( theta["sv"] ) - if model in ["shrink_spot", "shrink_spot_extended"]: + if model in [ + "shrink_spot", + "shrink_spot_simple", + "shrink_spot_extended", + "shrink_spot_extended_angle", + "shrink_spot_simple_extended", + ]: theta["v"] = np.tile(np.array([0], dtype=np.float32), n_trials) # Multi-particle models diff --git a/ssms/config/config.py b/ssms/config/config.py index e9dc14b..3963de5 100755 --- a/ssms/config/config.py +++ b/ssms/config/config.py @@ -84,7 +84,11 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: }, "attend_drift": { "fun": df.attend_drift, - "params": ["p_target", "p_outer", "p_inner", "r", "sda"], + "params": ["ptarget", "pouter", "pinner", "r", "sda"], + }, + "attend_drift_simple": { + "fun": df.attend_drift_simple, + "params": ["ptarget", "pouter", "r", "sda"], }, } @@ -100,6 +104,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 4, "default_params": [0.0, 1.0, 0.5, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flexbound, }, @@ -112,6 +117,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 4, "default_params": [0.0, 1.0, 0.5, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm, }, @@ -124,6 +130,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 1e-3, 0.0], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flexbound, }, @@ -139,6 +146,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 1.0, 0.5, 1e-3, 3.0, 3.0], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flexbound, }, @@ -151,6 +159,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 1.5, 0.1], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.levy_flexbound, }, @@ -166,6 +175,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 1.0, 0.5, 1.5, 0.1, 0.01], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.levy_flexbound, }, @@ -181,6 +191,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 1.0, 0.5, 0.25, 1e-3, 1e-3, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm, }, @@ -201,6 +212,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 1.0, 0.5, 0.25, 1e-3, 1e-3, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm_rv, "simulator_fixed_params": {}, @@ -230,6 +242,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 0.25, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm_rv, "simulator_fixed_params": { @@ -254,6 +267,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 0.25, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm_rv, "simulator_fixed_params": { @@ -283,6 +297,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 0.25, 0.2], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm_rv, "simulator_fixed_params": { @@ -307,6 +322,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 1e-3, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.full_ddm_rv, "simulator_fixed_params": { @@ -335,6 +351,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 1.0, 0.5, 0.25, 5.0, 0.5, 1.0], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -344,9 +361,9 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "a", "z", "t", - "p.target", - "p.outer", - "p.inner", + "ptarget", + "pouter", + "pinner", "r", "sda", ], @@ -361,6 +378,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.7, 0.5, 0.25, 2.0, -2.0, -2.0, 0.01, 1], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -370,9 +388,9 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "a", "z", "t", - "p.target", - "p.outer", - "p.inner", + "ptarget", + "pouter", + "pinner", "r", "sda", ], @@ -387,6 +405,59 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.7, 0.5, 0.25, 2.0, -2.0, -2.0, 0.01, 1], "nchoices": 2, + "choices": [-1, 1], + "n_particles": 1, + "simulator": cssm.ddm_flex, + }, + "shrink_spot_simple": { + "name": "shrink_spot_simple", + "params": [ + "a", + "z", + "t", + "ptarget", + "pouter", + "r", + "sda", + ], + "param_bounds": [ + [0.3, 0.1, 1e-3, 2.0, -5.5, 0.01, 1], + [3.0, 0.9, 2.0, 5.5, 5.5, 0.05, 3], + ], + "boundary_name": "constant", + "boundary": bf.constant, + "drift_name": "attend_drift_simple", + "drift_fun": df.attend_drift_simple, + "n_params": 7, + "default_params": [0.7, 0.5, 0.25, 2.0, -2.0, 0.01, 1], + "nchoices": 2, + "choices": [-1, 1], + "n_particles": 1, + "simulator": cssm.ddm_flex, + }, + "shrink_spot_simple_extended": { + "name": "shrink_spot_simple_extended", + "params": [ + "a", + "z", + "t", + "ptarget", + "pouter", + "r", + "sda", + ], + "param_bounds": [ + [0.3, 0.1, 1e-3, 2.0, -5.5, 0.01, 1], + [3.0, 0.9, 2.0, 5.5, 5.5, 1.0, 3], + ], + "boundary_name": "constant", + "boundary": bf.constant, + "drift_name": "attend_drift_simple", + "drift_fun": df.attend_drift_simple, + "n_params": 7, + "default_params": [0.7, 0.5, 0.25, 2.0, -2.0, 0.01, 1], + "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -404,6 +475,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 1.0, 0.5, 0.25, 0.0, 5.0, 0.5, 1.0], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -432,6 +504,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [2.0, 0.5, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 0.5, -0.5], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -461,6 +534,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [2.0, 0.5, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 0.5, -0.5, 0.0], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ddm_flex, }, @@ -473,6 +547,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 1.0, 0.5, 0.0, 1e-3], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ornstein_uhlenbeck, }, @@ -488,6 +563,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 1.0, 0.5, 0.0, 1e-3, 0.1], "nchoices": 2, + "choices": [-1, 1], "n_particles": 1, "simulator": cssm.ornstein_uhlenbeck, }, @@ -500,6 +576,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 4, "default_params": [0.3, 0.5, 0.5, 0.5], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.lba_vanilla, }, @@ -512,6 +589,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.3, 0.5, 0.25, 0.5, 0.25], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lba_vanilla, }, @@ -524,6 +602,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.5, 0.3, 0.2, 0.5, 0.2], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lba_vanilla, }, @@ -536,6 +615,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.5, 0.3, 0.2, 0.5, 0.2, 0.0], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lba_angle, }, @@ -560,6 +640,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.5, 0.3, 0.2, 0.5, 0.3, 0.2, 0.5, 0.2], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.rlwm_lba_race, }, @@ -575,6 +656,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 2.0, 0.5, 0.5, 1e-3], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.race_model, }, @@ -590,6 +672,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 0.0, 2.0, 0.5, 1e-3], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.race_model, }, @@ -605,6 +688,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 4, "default_params": [0.0, 0.0, 2.0, 1e-3], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.race_model, }, @@ -620,6 +704,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 2.0, 0.5, 1e-3, 0.0], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.race_model, }, @@ -635,6 +720,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 0.0, 2.0, 1e-3, 0.0], "nchoices": 2, + "choices": [0, 1], "n_particles": 2, "simulator": cssm.race_model, }, @@ -650,6 +736,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 2.0, 0.5, 0.5, 0.5, 1e-3], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.race_model, }, @@ -666,6 +753,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_particles": 3, "default_params": [0.0, 0.0, 0.0, 2.0, 0.5, 1e-3], "nchoices": 3, + "choices": [0, 1, 2], "simulator": cssm.race_model, }, "race_no_z_3": { @@ -680,6 +768,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 0.0, 0.0, 2.0, 1e-3], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.race_model, }, @@ -695,6 +784,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 2.0, 0.5, 1e-3, 0.0], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.race_model, }, @@ -710,6 +800,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 2.0, 1e-3, 0.0], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.race_model, }, @@ -725,6 +816,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 0.5, 0.5, 0.5, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.race_model, }, @@ -740,6 +832,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.race_model, }, @@ -755,6 +848,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.race_model, }, @@ -770,6 +864,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 1e-3, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.race_model, }, @@ -785,6 +880,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 1e-3, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.race_model, }, @@ -815,6 +911,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 2.0, 0.5, 0.0, 0.0, 1e-3], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lca, }, @@ -830,6 +927,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1e-3], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lca, }, @@ -845,6 +943,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 2.0, 0.5, 0.0, 0.0, 1e-3, 0.0], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lca, }, @@ -860,6 +959,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1e-3, 0.0], "nchoices": 3, + "choices": [0, 1, 2], "n_particles": 3, "simulator": cssm.lca, }, @@ -888,6 +988,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 12, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.lca, }, @@ -903,6 +1004,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 0.0, 0.0, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.lca, }, @@ -918,6 +1020,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1e-3], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.lca, }, @@ -933,6 +1036,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.5, 0.0, 0.0, 1e-3, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.lca, }, @@ -948,6 +1052,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1e-3, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 4, "simulator": cssm.lca, }, @@ -963,6 +1068,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_par2, }, @@ -975,6 +1081,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_par2, }, @@ -1000,6 +1107,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 0.5, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_par2, }, @@ -1016,6 +1124,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_par2, }, @@ -1032,6 +1141,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 3.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_par2, }, @@ -1047,6 +1157,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_seq2, }, @@ -1059,6 +1170,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 5, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_seq2, }, @@ -1099,6 +1211,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 0.5, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_seq2, }, @@ -1115,6 +1228,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_seq2, }, @@ -1131,6 +1245,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 1.0, 2.5, 3.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_seq2, }, @@ -1146,6 +1261,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 0.5, 0.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1161,6 +1277,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1187,6 +1304,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1203,6 +1321,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1219,6 +1338,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 2.5, 3.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1234,6 +1354,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 0.5, 1.5, 0.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1249,6 +1370,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1276,6 +1398,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 11, "default_params": [0.0, 0.0, 0.0, 0.5, 1.5, 1.0, 1.0, 1.0, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1292,6 +1415,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.5, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1308,6 +1432,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.5, 1.0, 2.5, 3.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1324,6 +1449,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_multinoise, }, @@ -1350,6 +1476,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_multinoise, }, @@ -1366,6 +1493,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_multinoise, }, @@ -1382,6 +1510,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 2.5, 3.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_multinoise, }, @@ -1398,6 +1527,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 9, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 0.5, 0.5, 0.5, 0.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1413,6 +1543,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1439,6 +1570,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1455,6 +1587,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1471,6 +1604,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 8, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 2.5, 3.5], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_mic2_ornstein, }, @@ -1487,6 +1621,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 6, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_tradeoff, }, @@ -1503,6 +1638,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 7, "default_params": [0.0, 0.0, 0.0, 1.0, 0.5, 1.0, 0.0], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_tradeoff, }, @@ -1546,6 +1682,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "n_params": 10, "default_params": [0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 2, 2], "nchoices": 4, + "choices": [0, 1, 2, 3], "n_particles": 1, "simulator": cssm.ddm_flexbound_tradeoff, }, @@ -1660,6 +1797,7 @@ def boundary_config_to_function_params(boundary_config: dict) -> dict: "bin_pointwise": False, "separate_response_channels": False, "smooth_unif": True, + "kde_displace_t": False, }, # AF-TODO: Add opn, gonogo "ratio_estimator": { diff --git a/ssms/dataset_generators/lan_mlp.py b/ssms/dataset_generators/lan_mlp.py index 7f8afea..c5cd42c 100755 --- a/ssms/dataset_generators/lan_mlp.py +++ b/ssms/dataset_generators/lan_mlp.py @@ -1,6 +1,7 @@ from ssms.basic_simulators.simulator import simulator # , bin_simulator_output from ssms.support_utils import kde_class import numpy as np +import warnings from copy import deepcopy import pickle import uuid @@ -113,6 +114,18 @@ def __init__( self.model_config["name"] += "_deadline" self.model_config["n_params"] += 1 + if "kde_displace_t" not in self.generator_config: + self.generator_config["kde_displace_t"] = False + + if ( + self.generator_config["kde_displace_t"] is True + and self.model_config["name"].split("_deadline")[0] in KDE_NO_DISPLACE_T + ): + warnings.warn( + f"kde_displace_t is True, but model is in {KDE_NO_DISPLACE_T}. Overriding setting to False" + ) + self.generator_config["kde_displace_t"] = False + # Define constrained parameter space as dictionary # and add to internal model config # AF-COMMENT: This will eventually be replaced so that @@ -287,12 +300,7 @@ def _make_kde_data( tmp_kde = kde_class.LogKDE( simulations, - displace_t=( - True - if self.model_config["name"].split("_deadline")[0] - not in KDE_NO_DISPLACE_T - else False - ), + displace_t=self.generator_config["kde_displace_t"], ) # Get kde part diff --git a/ssms/support_utils/kde_class.py b/ssms/support_utils/kde_class.py index 626c9a7..8a39d95 100755 --- a/ssms/support_utils/kde_class.py +++ b/ssms/support_utils/kde_class.py @@ -46,11 +46,28 @@ class LogKDE: # Initialize the class def __init__( self, - simulator_data, # as returned by simulator function - bandwidth_type="silverman", - auto_bandwidth=True, - displace_t=True, + simulator_data: dict, # as returned by simulator function + bandwidth_type: str = "silverman", + auto_bandwidth: bool = True, + displace_t: bool = False, ): + """Initialize LogKDE class. + + Arguments: + ---------- + simulator_data: Dictionary containing simulation data with keys 'rts', 'choices', and 'metadata'. + Follows the format returned by simulator functions in this package. + bandwidth_type: Type of bandwidth to use for KDE. Currently only 'silverman' is supported. + Defaults to 'silverman'. + auto_bandwidth: Whether to automatically compute bandwidths based on the data. + If False, bandwidths must be set manually. Defaults to True. + displace_t: Whether to shift RTs by the t parameter from metadata. + Only works if all trials have the same t value. Defaults to False. + + Raises: + ------- + AssertionError: If displace_t is True but metadata contains multiple t values. + """ self.simulator_info = simulator_data["metadata"] if displace_t: