diff --git a/README.rst b/README.rst index f4b2967b8..31a9bdc86 100644 --- a/README.rst +++ b/README.rst @@ -9,7 +9,7 @@ Uncertainty Quantification with python (UQpy) :Authors: Michael D. Shields, Dimitris G. Giovanis, Audrey Olivier, Aakash Bangalore Satish, Mohit Singh Chauhan, Lohit Vandanapu, Ketson RM dos Santos, Katiana Kontolati :Contact: UQpy.info@gmail.com -:Version: 3.0.3 +:Version: 3.0.4 Description @@ -85,7 +85,7 @@ For assistance with the UQpy software package, please raise an issue on the Gith .. image:: https://img.shields.io/pypi/dm/UQpy?style=plastic :alt: PyPI - Downloads .. image:: https://img.shields.io/conda/dn/conda-forge/UQpy?style=plastic :alt: Conda -.. image:: https://img.shields.io/github/downloads/SURGroup/UQpy/v3.0.1/total?style=plastic :alt: GitHub Releases (by Release) +.. image:: https://img.shields.io/github/downloads/SURGroup/UQpy/V3.0.4/total?style=plastic :alt: GitHub Releases (by Release) .. image:: https://img.shields.io/pypi/v/UQpy?style=plastic :alt: PyPI .. image:: https://img.shields.io/conda/v/conda-forge/UQpy?style=plastic :alt: Conda diff --git a/docs/source/runmodel_doc.rst b/docs/source/runmodel_doc.rst index beb121d66..cc8644cb2 100644 --- a/docs/source/runmodel_doc.rst +++ b/docs/source/runmodel_doc.rst @@ -87,7 +87,7 @@ To execute ``RunModel``, the working directory must contain the necessary files .. image:: _static/Runmodel_directory_1.png :width: 300 -To avoid cluttering the working directory with outputs, ``RunModel`` creates a directory for each execution of the model and saves the output generated during the model execution within the corresponding directory. ``RunModel`` generates the directory name for the sample as `run_n_timestamp`, where `n` is the python index of the run and `timestamp` corresponds to the time at the beginning of the first simulation of the parallel job. This is illustrated in the figure below. +To avoid cluttering the working directory with outputs, ``RunModel`` creates a directory for each execution of the model and saves the output generated during the model execution within the corresponding directory. ``RunModel`` generates the directory name for the sample as `run_n`, where `n` is the python index of the run and `timestamp` corresponds to the time at the beginning of the first simulation of the parallel job. This is illustrated in the figure below. .. image:: _static/Runmodel_directory_2.png :width: 300 diff --git a/example/RunModel/Abaqus_Example/abaqus_example.py b/example/RunModel/Abaqus_Example/abaqus_example.py index 55388fde4..388fc38d4 100644 --- a/example/RunModel/Abaqus_Example/abaqus_example.py +++ b/example/RunModel/Abaqus_Example/abaqus_example.py @@ -18,7 +18,7 @@ print('Example: Created the model object.') # Towards defining the sampling scheme -# The fire load density is assumed to be uniformly distributed between 50 MJ/number_of_variables^2 and 450 MJ/number_of_variables^2. +# The fire load density is assumed to be uniformly distributed between 50 MJ/m^2 and 450 MJ/m^2. # The yield strength is assumed to be normally distributed, with the parameters # being: mean = 250 MPa and coefficient of variation of 7%. diff --git a/example/RunModel/Abaqus_Example/extract_abaqus_output.py b/example/RunModel/Abaqus_Example/extract_abaqus_output.py index fadb6a64d..80064a9d9 100644 --- a/example/RunModel/Abaqus_Example/extract_abaqus_output.py +++ b/example/RunModel/Abaqus_Example/extract_abaqus_output.py @@ -24,8 +24,8 @@ def extract_disp_temp_output(index): os.remove(os.path.join(dir_name, item)) # Compute the maximum allowable displacement - length_of_beam = 1 # in number_of_variables - depth_of_beam = 0.035 # in number_of_variables + length_of_beam = 1 # in m + depth_of_beam = 0.035 # in m max_allowable_disp = length_of_beam ** 2 / (400 * depth_of_beam) # Obtain the maximum midpoint displacement diff --git a/example/RunModel/Matlab_Example/matlab_model.py b/example/RunModel/Matlab_Example/matlab_model.py index a30d7a447..ed313ecb6 100644 --- a/example/RunModel/Matlab_Example/matlab_model.py +++ b/example/RunModel/Matlab_Example/matlab_model.py @@ -3,11 +3,11 @@ def matlab(index): - command1 = "cp ./InputFiles/dummy_model_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/dummy_model_" + str(index) + ".m ." command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run dummy_model_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run dummy_model_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm dummy_model_" + str(index) + ".number_of_variables" + command4 = "rm dummy_model_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_det.py b/example/RunModel/Matlab_Example/matlab_model_det.py index ebdb6db3a..486e75831 100644 --- a/example/RunModel/Matlab_Example/matlab_model_det.py +++ b/example/RunModel/Matlab_Example/matlab_model_det.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/prod_determinant_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/prod_determinant_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm prod_determinant_" + str(index) + ".number_of_variables" + command4 = "rm prod_determinant_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_det_index.py b/example/RunModel/Matlab_Example/matlab_model_det_index.py index aaf62882b..63124dc86 100644 --- a/example/RunModel/Matlab_Example/matlab_model_det_index.py +++ b/example/RunModel/Matlab_Example/matlab_model_det_index.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/prod_determinant_index_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/prod_determinant_index_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_index_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_index_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm prod_determinant_index_" + str(index) + ".number_of_variables" + command4 = "rm prod_determinant_index_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_det_partial.py b/example/RunModel/Matlab_Example/matlab_model_det_partial.py index 9d71c46c6..fadee72b1 100644 --- a/example/RunModel/Matlab_Example/matlab_model_det_partial.py +++ b/example/RunModel/Matlab_Example/matlab_model_det_partial.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/prod_determinant_partial_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/prod_determinant_partial_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_partial_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run prod_determinant_partial_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm prod_determinant_partial_" + str(index) + ".number_of_variables" + command4 = "rm prod_determinant_partial_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_sum_scalar.py b/example/RunModel/Matlab_Example/matlab_model_sum_scalar.py index fdca0ff0c..88dd8f31f 100644 --- a/example/RunModel/Matlab_Example/matlab_model_sum_scalar.py +++ b/example/RunModel/Matlab_Example/matlab_model_sum_scalar.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/sum_scalar_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/sum_scalar_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_scalar_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_scalar_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm sum_scalar_" + str(index) + ".number_of_variables" + command4 = "rm sum_scalar_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_sum_vector.py b/example/RunModel/Matlab_Example/matlab_model_sum_vector.py index 354f0c2d1..e2d8b1e65 100644 --- a/example/RunModel/Matlab_Example/matlab_model_sum_vector.py +++ b/example/RunModel/Matlab_Example/matlab_model_sum_vector.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/sum_vector_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/sum_vector_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_vector_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_vector_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm sum_vector_" + str(index) + ".number_of_variables" + command4 = "rm sum_vector_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/RunModel/Matlab_Example/matlab_model_sum_vector_indexed.py b/example/RunModel/Matlab_Example/matlab_model_sum_vector_indexed.py index 7fb5d3bde..a3245e8c2 100644 --- a/example/RunModel/Matlab_Example/matlab_model_sum_vector_indexed.py +++ b/example/RunModel/Matlab_Example/matlab_model_sum_vector_indexed.py @@ -3,12 +3,12 @@ def matlab(index): - command1 = "cp ./InputFiles/sum_vector_indexed_" + str(index) + ".number_of_variables ." + command1 = "cp ./InputFiles/sum_vector_indexed_" + str(index) + ".m ." # The user will need to modify command2 to point to the Matlab application on their system. command2 = "/Applications/MATLAB_R2018a.app/bin/matlab " \ - "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_vector_indexed_" + str(index) + ".number_of_variables; exit'" + "-nosplash -nojvm -nodisplay -nodesktop -r 'run sum_vector_indexed_" + str(index) + ".m; exit'" command3 = "mv ./OutputFiles/oupt.out ./OutputFiles/oupt_" + str(index) + ".out" - command4 = "rm sum_vector_indexed_" + str(index) + ".number_of_variables" + command4 = "rm sum_vector_indexed_" + str(index) + ".m" os.system(command1) os.system(command2) os.system(command3) diff --git a/example/StochasticProcess/BSRM_nd.ipynb b/example/StochasticProcess/BSRM_nd.ipynb index 0a9b02b6e..b1520701d 100644 --- a/example/StochasticProcess/BSRM_nd.ipynb +++ b/example/StochasticProcess/BSRM_nd.ipynb @@ -46,14 +46,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Input parameters\n", "\n", - "n_sim = 10000 # Num of samples\n", - "\n", + "n_sim = 1000 # Num of samples\n", + "dim = 2\n", "n = 1 # Num of dimensions\n", "\n", "T = 20 # Time(1 / T = dw)\n", @@ -118,9 +118,27 @@ "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ValueError", + "evalue": "setting an array element with a sequence.", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mTypeError\u001B[0m Traceback (most recent call last)", + "\u001B[0;31mTypeError\u001B[0m: only size-1 arrays can be converted to Python scalars", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001B[0;31mValueError\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[0;32m----> 1\u001B[0;31m \u001B[0mBSRM_object\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mBSRM\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mn_sim\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mP\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mB_Complex\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0mdt\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdt\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0mdf\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdf\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0mnt\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mnt\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m[\u001B[0m\u001B[0mnf\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mnf\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 2\u001B[0m \u001B[0msamples\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mBSRM_object\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msamples\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Documents/GitHub/UQpy/src/UQpy/StochasticProcess.py\u001B[0m in \u001B[0;36m__init__\u001B[0;34m(self, nsamples, power_spectrum, bispectrum, time_interval, frequency_interval, number_time_intervals, number_frequency_intervals, case, random_state, verbose)\u001B[0m\n\u001B[1;32m 368\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 369\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnsamples\u001B[0m \u001B[0;32mis\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 370\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mrun\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnsamples\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnsamples\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 371\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 372\u001B[0m \u001B[0;32mdef\u001B[0m \u001B[0m_compute_bicoherence_uni\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Documents/GitHub/UQpy/src/UQpy/StochasticProcess.py\u001B[0m in \u001B[0;36mrun\u001B[0;34m(self, nsamples)\u001B[0m\n\u001B[1;32m 486\u001B[0m \u001B[0mprint\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'UQpy: Stochastic Process: Starting simulation of uni-variate Stochastic Processes.'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 487\u001B[0m \u001B[0mprint\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'UQpy: The number of dimensions is :'\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnumber_of_dimensions\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 488\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_compute_bicoherence_uni\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 489\u001B[0m phi = np.random.uniform(\n\u001B[1;32m 490\u001B[0m size=np.append(self.nsamples, np.ones(self.number_of_dimensions, dtype=np.int32)\n", + "\u001B[0;32m~/Documents/GitHub/UQpy/src/UQpy/StochasticProcess.py\u001B[0m in \u001B[0;36m_compute_bicoherence_uni\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 406\u001B[0m self.bc2[(*wi, *wj)] = self.b_ampl[(*wi, *wj)] ** 2 / (\n\u001B[1;32m 407\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mpure_power_sepctrum\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m*\u001B[0m\u001B[0mwi\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m*\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mpure_power_sepctrum\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m*\u001B[0m\u001B[0mwj\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 408\u001B[0;31m self.power_spectrum[(*wk, *[])]) * self.frequency_interval ** self.number_of_dimensions\n\u001B[0m\u001B[1;32m 409\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msum_bc2\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m*\u001B[0m\u001B[0mwk\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msum_bc2\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m*\u001B[0m\u001B[0mwk\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m+\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mbc2\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m*\u001B[0m\u001B[0mwi\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0mwj\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 410\u001B[0m \u001B[0;32melse\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mValueError\u001B[0m: setting an array element with a sequence." + ] + } + ], "source": [ - "BSRM_object = BSRM(n_sim, P, B_Complex, dt, df, nt, nf)\n", + "BSRM_object = BSRM(n_sim, P, B_Complex, [dt, dt], [df, df], [nt, nt], [nf, nf])\n", "samples = BSRM_object.samples" ] }, @@ -128,18 +146,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# fig, ax = plt.subplots()\n", "# plt.title('Realisation of the Spectral Representation Method')\n", @@ -164,19 +171,9 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The mean of the samples is -0.00775777397137 whereas the expected mean is 0.000\n", - "The variance of the samples is 20.4471836015 whereas the expected variance is 20.3989422768\n", - "The skewness of the samples is 0.619363095414 whereas the expected skewness is 0.61501412997\n" - ] - } - ], + "outputs": [], "source": [ "print('The mean of the samples is ', np.mean(samples), 'whereas the expected mean is 0.000')\n", "print('The variance of the samples is ', np.var(samples), 'whereas the expected variance is ', np.sum(P)*df*2)\n", @@ -212,4 +209,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/setup.py b/setup.py index 41a468438..42908d0a7 100755 --- a/setup.py +++ b/setup.py @@ -1,30 +1,30 @@ -#!/usr/bin/env python -import sys -version = sys.argv[1] -del sys.argv[1] -from setuptools import setup, find_packages - -setup( - name='UQpy', - version=version, - url='https://github.com/SURGroup/UQpy', - description="UQpy is a general purpose toolbox for Uncertainty Quantification", - author="Michael D. Shields, Dimitris G. Giovanis, Audrey Olivier, Aakash Bangalore-Satish, Mohit Chauhan, " - "Lohit Vandanapu, Ketson R.M. dos Santos", - author_email="UQpy.info@gmail.com", - license='MIT', - platforms=["OSX", "Windows", "Linux"], - packages=find_packages("src"), - package_dir={"": "src"}, - package_data={"": ["*.pdf"]}, - install_requires=[ - "numpy", "scipy", "matplotlib", "scikit-learn", 'fire' - ], - classifiers=[ - 'Programming Language :: Python :: 3', - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering :: Mathematics', - 'License :: OSI Approved :: MIT License', - 'Natural Language :: English', - ], -) +#!/usr/bin/env python +import sys +version = sys.argv[1] +del sys.argv[1] +from setuptools import setup, find_packages + +setup( + name='UQpy', + version=version, + url='https://github.com/SURGroup/UQpy', + description="UQpy is a general purpose toolbox for Uncertainty Quantification", + author="Michael D. Shields, Dimitris G. Giovanis, Audrey Olivier, Aakash Bangalore-Satish, Mohit Chauhan, " + "Lohit Vandanapu, Ketson R.M. dos Santos", + author_email="UQpy.info@gmail.com", + license='MIT', + platforms=["OSX", "Windows", "Linux"], + packages=find_packages("src"), + package_dir={"": "src"}, + package_data={"": ["*.pdf"]}, + install_requires=[ + "numpy", "scipy", "matplotlib", "scikit-learn", 'fire' + ], + classifiers=[ + 'Programming Language :: Python :: 3', + 'Intended Audience :: Science/Research', + 'Topic :: Scientific/Engineering :: Mathematics', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + ], +) diff --git a/src/UQpy/Distributions.py b/src/UQpy/Distributions.py index cc582090b..e9064b4c5 100644 --- a/src/UQpy/Distributions.py +++ b/src/UQpy/Distributions.py @@ -181,7 +181,7 @@ class Distribution: Generated iid samples, `ndarray` of shape `(npoints, dimension)`. **moments** *(moments2return='mvsk')* - Computes the mean 'number_of_variables', variance/covariance ('v'), skewness ('s') and/or kurtosis ('k') of the distribution. + Computes the mean 'm', variance/covariance ('v'), skewness ('s') and/or kurtosis ('k') of the distribution. For a univariate distribution, mean, variance, skewness and kurtosis are returned. For a multivariate distribution, the mean vector, covariance and vectors of marginal skewness and marginal kurtosis are returned. @@ -816,16 +816,16 @@ class Binomial(DistributionDiscrete1D): """ Binomial distribution having probability mass function: - .. math:: f(x) = {number_of_dimensions \choose x} p^x(1-p)^{number_of_dimensions-x} + .. math:: f(x) = {n \choose x} p^x(1-p)^{n-x} - for :math:`x\inumber_of_dimensions\{0, 1, 2, ..., number_of_dimensions\}`. + for :math:`x\in\{0, 1, 2, ..., n\}`. In this standard form `(loc=0)`. Use `loc` to shift the distribution. Specifically, this is equivalent to computing :math:`f(y)` where :math:`y=x-loc`. **Inputs:** - * **number_of_dimensions** (`int`): + * **n** (`int`): number of trials, integer >= 0 * **p** (`float`): success probability for each trial, real number in [0, 1] @@ -837,7 +837,7 @@ class Binomial(DistributionDiscrete1D): * ``cdf``, ``pmf``, ``log_pmf``, ``icdf``, ``rvs, moments``. """ def __init__(self, n, p, loc=0.): - super().__init__(n=n, p=p, loc=loc, order_params=('number_of_dimensions', 'p', 'loc')) + super().__init__(n=n, p=p, loc=loc, order_params=('n', 'p', 'loc')) self._construct_from_scipy(scipy_name=stats.binom) @@ -947,27 +947,27 @@ def fit(self, x): return {'mean': mle_mu, 'cov': mle_cov} def moments(self, moments2return='mv'): - if moments2return == 'number_of_variables': + if moments2return == 'm': return self.get_params()['mean'] elif moments2return == 'v': return self.get_params()['cov'] elif moments2return == 'mv': return self.get_params()['mean'], self.get_params()['cov'] else: - raise ValueError('UQpy: moments2return must be "number_of_variables", "v" or "mv".') + raise ValueError('UQpy: moments2return must be "m", "v" or "mv".') class Multinomial(DistributionND): """ Multinomial distribution having probability mass function - .. math:: f(x) = \dfrac{number_of_dimensions!}{x_1!\dots x_k!}p_1^{x_1}\dots p_k^{x_k} + .. math:: f(x) = \dfrac{n!}{x_1!\dots x_k!}p_1^{x_1}\dots p_k^{x_k} - for :math:`x=\{x_1,\dots,x_k\}` where each :math:`x_i` is a non-negative integer and :math:`\sum_i x_i = number_of_dimensions`. + for :math:`x=\{x_1,\dots,x_k\}` where each :math:`x_i` is a non-negative integer and :math:`\sum_i x_i = n`. **Inputs:** - * **number_of_dimensions** (`int`): + * **n** (`int`): number of trials * **p** (`array_like`): probability of a trial falling into each category; should sum to 1 @@ -994,24 +994,24 @@ def rvs(self, nsamples=1, random_state=None): size=nsamples, random_state=random_state, **self.params).reshape((nsamples, -1)) def moments(self, moments2return='mv'): - if moments2return == 'number_of_variables': - mean = self.get_params()['number_of_dimensions'] * np.array(self.get_params()['p']) + if moments2return == 'm': + mean = self.get_params()['n'] * np.array(self.get_params()['p']) return mean elif moments2return == 'v': - n, p = self.get_params()['number_of_dimensions'], np.array(self.get_params()['p']) + n, p = self.get_params()['n'], np.array(self.get_params()['p']) d = len(p) cov = - n * np.tile(p[np.newaxis, :], [d, 1]) * np.tile(p[:, np.newaxis], [1, d]) np.fill_diagonal(cov, n * p * (1. - p)) return cov elif moments2return == 'mv': - n, p = self.get_params()['number_of_dimensions'], np.array(self.get_params()['p']) + n, p = self.get_params()['n'], np.array(self.get_params()['p']) d = len(p) cov = - n * np.tile(p[np.newaxis, :], [d, 1]) * np.tile(p[:, np.newaxis], [1, d]) np.fill_diagonal(cov, n * p * (1. - p)) mean = n * p return mean, cov else: - raise ValueError('UQpy: moments2return must be "number_of_variables", "v" or "mv".') + raise ValueError('UQpy: moments2return must be "m", "v" or "mv".') class JointInd(DistributionND): @@ -1514,8 +1514,7 @@ class Frank(Copula): **Input:** - * **theta** (`float`): - Parameter of the copula, real number in correlation_function\{0}. + * **theta** (`float`):R\{0}. This copula possesses the following methods: @@ -1526,7 +1525,7 @@ class Frank(Copula): def __init__(self, theta): # Check the input copula_params if theta is not None and ((not isinstance(theta, (float, int))) or (theta == 0.)): - raise ValueError('Input theta should be a float in correlation_function\{0}.') + raise ValueError('Input theta should be a float in R\{0}.') super().__init__(theta=theta) def evaluate_cdf(self, unif): diff --git a/src/UQpy/RunModel.py b/src/UQpy/RunModel.py index 6ead4d4e6..6f9949284 100755 --- a/src/UQpy/RunModel.py +++ b/src/UQpy/RunModel.py @@ -519,10 +519,9 @@ def _serial_execution(self): print('\nUQpy: Performing serial execution of the third-party model.\n') # Loop over the number of simulations, executing the model once per loop - ts = datetime.datetime.now().strftime("%Y_%m_%d_%I_%M_%f_%p") for i in range(self.nexist, self.nexist + self.nsim): # Create a directory for each model run - work_dir = os.path.join(self.model_dir, "run_" + str(i) + '_' + ts) + work_dir = os.path.join(self.model_dir, "run_" + str(i)) self._copy_files(work_dir=work_dir) # Change current working directory to model run directory @@ -567,21 +566,19 @@ def _parallel_execution(self): # Call the input function print('\nUQpy: Creating inputs for parallel execution of the third-party model.\n') - ts = datetime.datetime.now().strftime("%Y_%m_%d_%I_%M_%f_%p") - # Create all input files for the parallel execution and place them in the proper directories for i in range(self.nexist, self.nexist + self.nsim): # Create a directory for each model run - work_dir = os.path.join(self.model_dir, "run_" + str(i) + '_' + ts) + work_dir = os.path.join(self.model_dir, "run_" + str(i)) self._copy_files(work_dir=work_dir) - self._input_parallel(ts) + self._input_parallel() # Execute the model if self.verbose: print('\nUQpy: Executing the third-party model in parallel.\n') - self._execute_parallel(ts) + self._execute_parallel() # Call the output function if self.verbose: @@ -589,7 +586,7 @@ def _parallel_execution(self): for i in range(self.nexist, self.nexist + self.nsim): # Change current working directory to model run directory - work_dir = os.path.join(self.model_dir, "run_" + str(i) + '_' + ts) + work_dir = os.path.join(self.model_dir, "run_" + str(i)) if self.verbose: print('\nUQpy: Changing to the following directory for output processing:\n' + work_dir) os.chdir(work_dir) @@ -733,19 +730,14 @@ def _output_serial(self, index): else: self.qoi_list[index] = self.model_output - def _input_parallel(self, timestamp): + def _input_parallel(self): """ Create all the input files required - - ** Input: ** - - :param timestamp: Timestamp which is appended to the name of the input file - :type timestamp: str """ # Loop over the number of samples and create input files in a folder in current directory for i in range(self.nsim): new_text = self._find_and_replace_var_names_with_values(index=i + self.nexist) - folder_to_write = 'run_' + str(i+self.nexist) + '_' + timestamp + '/InputFiles' + folder_to_write = 'run_' + str(i+self.nexist) + '/InputFiles' # Write the new text to the input file self._create_input_files(file_name=self.input_template, num=i+self.nexist, text=new_text, new_folder=folder_to_write) @@ -753,7 +745,7 @@ def _input_parallel(self, timestamp): print('\nUQpy: Created input files for run ' + str(i) + ' in the directory: \n' + os.path.join(self.model_dir, folder_to_write)) - def _execute_parallel(self, timestamp): + def _execute_parallel(self): """ Build the command string and execute the model in parallel using subprocess and gnu parallel @@ -778,12 +770,12 @@ def _execute_parallel(self, timestamp): # If running on SLURM cluster if self.cluster: self.srun_string = "srun -N" + str(self.nodes) + " -n1 -c" + str(self.cores_per_task) + " --exclusive " - self.model_command_string = (self.parallel_string + "'(cd run_{1}_" + timestamp + " && " + self.srun_string + self.model_command_string = (self.parallel_string + "'(cd run_{1}" + " && " + self.srun_string + " " + self.python_command + " -u " + str(self.model_script) + " {1})' ::: {" + str(self.nexist) + ".." + str(self.nexist + self.nsim - 1) + "}") else: # If running locally - self.model_command_string = (self.parallel_string + " 'cd run_{1}_" + timestamp + " && " + + self.model_command_string = (self.parallel_string + " 'cd run_{1}" + " && " + self.python_command + " -u " + str(self.model_script) + "' {1} ::: {" + str(self.nexist) + ".." + str(self.nexist + self.nsim - 1) + "}") diff --git a/src/UQpy/StochasticProcess.py b/src/UQpy/StochasticProcess.py index 3e189dd0a..611555cec 100644 --- a/src/UQpy/StochasticProcess.py +++ b/src/UQpy/StochasticProcess.py @@ -15,6 +15,7 @@ import itertools from scipy.linalg import sqrtm +from scipy.stats import norm from UQpy.Distributions import * from UQpy.Utilities import * @@ -373,26 +374,26 @@ def _compute_bicoherence_uni(self): if self.verbose: print('UQpy: Stochastic Process: Computing the partial bicoherence values.') self.bc2 = np.zeros_like(self.b_real) - self.pure_power_sepctrum = np.zeros_like(self.power_spectrum) + self.pure_power_spectrum = np.zeros_like(self.power_spectrum) self.sum_bc2 = np.zeros_like(self.power_spectrum) if self.number_of_dimensions == 1: - self.pure_power_sepctrum[0] = self.power_spectrum[0] - self.pure_power_sepctrum[1] = self.power_spectrum[1] + self.pure_power_spectrum[0] = self.power_spectrum[0] + self.pure_power_spectrum[1] = self.power_spectrum[1] if self.number_of_dimensions == 2: - self.pure_power_sepctrum[0, :] = self.power_spectrum[0, :] - self.pure_power_sepctrum[1, :] = self.power_spectrum[1, :] - self.pure_power_sepctrum[:, 0] = self.power_spectrum[:, 0] - self.pure_power_sepctrum[:, 1] = self.power_spectrum[:, 1] + self.pure_power_spectrum[0, :] = self.power_spectrum[0, :] + self.pure_power_spectrum[1, :] = self.power_spectrum[1, :] + self.pure_power_spectrum[:, 0] = self.power_spectrum[:, 0] + self.pure_power_spectrum[:, 1] = self.power_spectrum[:, 1] if self.number_of_dimensions == 3: - self.pure_power_sepctrum[0, :, :] = self.power_spectrum[0, :, :] - self.pure_power_sepctrum[1, :, :] = self.power_spectrum[1, :, :] - self.pure_power_sepctrum[:, 0, :] = self.power_spectrum[:, 0, :] - self.pure_power_sepctrum[:, 1, :] = self.power_spectrum[:, 1, :] - self.pure_power_sepctrum[:, :, 0] = self.power_spectrum[:, :, 0] - self.pure_power_sepctrum[:, 0, 1] = self.power_spectrum[:, :, 1] + self.pure_power_spectrum[0, :, :] = self.power_spectrum[0, :, :] + self.pure_power_spectrum[1, :, :] = self.power_spectrum[1, :, :] + self.pure_power_spectrum[:, 0, :] = self.power_spectrum[:, 0, :] + self.pure_power_spectrum[:, 1, :] = self.power_spectrum[:, 1, :] + self.pure_power_spectrum[:, :, 0] = self.power_spectrum[:, :, 0] + self.pure_power_spectrum[:, 0, 1] = self.power_spectrum[:, :, 1] self.ranges = [range(self.number_frequency_intervals[i]) for i in range(self.number_of_dimensions)] @@ -401,10 +402,10 @@ def _compute_bicoherence_uni(self): for j in itertools.product(*[range(np.int32(k)) for k in np.ceil((wk + 1) / 2)]): wj = np.array(j) wi = wk - wj - if self.b_ampl[(*wi, *wj)] > 0 and self.pure_power_sepctrum[(*wi, *[])] * \ - self.pure_power_sepctrum[(*wj, *[])] != 0: + if self.b_ampl[(*wi, *wj)] > 0 and self.pure_power_spectrum[(*wi, *[])] * \ + self.pure_power_spectrum[(*wj, *[])] != 0: self.bc2[(*wi, *wj)] = self.b_ampl[(*wi, *wj)] ** 2 / ( - self.pure_power_sepctrum[(*wi, *[])] * self.pure_power_sepctrum[(*wj, *[])] * + self.pure_power_spectrum[(*wi, *[])] * self.pure_power_spectrum[(*wj, *[])] * self.power_spectrum[(*wk, *[])]) * self.frequency_interval ** self.number_of_dimensions self.sum_bc2[(*wk, *[])] = self.sum_bc2[(*wk, *[])] + self.bc2[(*wi, *wj)] else: @@ -417,7 +418,7 @@ def _compute_bicoherence_uni(self): wi = wk - wj self.bc2[(*wi, *wj)] = self.bc2[(*wi, *wj)] / self.sum_bc2[(*wk, *[])] self.sum_bc2[(*wk, *[])] = 1 - self.pure_power_sepctrum[(*wk, *[])] = self.power_spectrum[(*wk, *[])] * (1 - self.sum_bc2[(*wk, *[])]) + self.pure_power_spectrum[(*wk, *[])] = self.power_spectrum[(*wk, *[])] * (1 - self.sum_bc2[(*wk, *[])]) def _simulate_bsrm_uni(self, phi): coeff = np.sqrt((2 ** ( @@ -425,6 +426,7 @@ def _simulate_bsrm_uni(self, phi): self.frequency_interval ** self.number_of_dimensions) phi_e = np.exp(phi * 1.0j) biphase_e = np.exp(self.biphase * 1.0j) + self._compute_bicoherence_uni() b = np.sqrt(1 - self.sum_bc2) * phi_e bc = np.sqrt(self.bc2)