diff --git a/idaes/core/surrogate/pysmo/kriging.py b/idaes/core/surrogate/pysmo/kriging.py index e93888362f..1c20241ff9 100644 --- a/idaes/core/surrogate/pysmo/kriging.py +++ b/idaes/core/surrogate/pysmo/kriging.py @@ -537,9 +537,10 @@ def error_calculation(theta, p, mean, cov_inv, y_mu, x, y_data): for i in range(0, x.shape[0]): cmt = (np.matmul(((np.abs(x[i, :] - x)) ** p), theta)).transpose() cov_matrix_tests = np.exp(-1 * cmt) - y_prediction[i, 0] = mean + np.matmul( + y_pred_val = mean + np.matmul( np.matmul(cov_matrix_tests.transpose(), cov_inv), y_mu ) + y_prediction[i, 0] = y_pred_val.item() ss_error = (1 / y_data.shape[0]) * (np.sum((y_data - y_prediction) ** 2)) rmse_error = np.sqrt(ss_error) return ss_error, rmse_error, y_prediction @@ -589,10 +590,11 @@ def predict_output(self, x_pred): ) ).transpose() cov_matrix_tests = np.exp(-1 * cmt) - y_pred[i, 0] = self.optimal_mean + np.matmul( + y_pred_val = self.optimal_mean + np.matmul( np.matmul(cov_matrix_tests.transpose(), self.covariance_matrix_inverse), self.optimal_y_mu, ) + y_pred[i, 0] = y_pred_val.item() return y_pred def training(self): diff --git a/idaes/core/surrogate/pysmo/polynomial_regression.py b/idaes/core/surrogate/pysmo/polynomial_regression.py index 011ea3ff12..135fb6abff 100644 --- a/idaes/core/surrogate/pysmo/polynomial_regression.py +++ b/idaes/core/surrogate/pysmo/polynomial_regression.py @@ -15,7 +15,6 @@ # pylint: disable=missing-function-docstring import os.path -import warnings import pickle # Imports from third parties @@ -42,7 +41,9 @@ # Imports from IDAES namespace from idaes.core.surrogate.pysmo.utils import NumpyEvaluator +import idaes.logger as idaeslog +_log = idaeslog.getLogger(__name__) __author__ = "Oluwamayowa Amusat" @@ -346,7 +347,7 @@ def __init__( print("The number of cross-validation cases (3) is used.") number_of_crossvalidations = 3 elif number_of_crossvalidations > 10: - warnings.warn( + _log.warning( "The number of cross-validations entered is large. The simulation may take a while to run" ) self.number_of_crossvalidations = number_of_crossvalidations @@ -356,7 +357,7 @@ def __init__( # pylint: disable-next=broad-exception-raised raise Exception("Maximum polynomial order must be an integer") elif maximum_polynomial_order > 10: - warnings.warn( + _log.warning( "The maximum allowed polynomial order is 10. Value has been adjusted to 10." ) maximum_polynomial_order = 10 @@ -1000,7 +1001,7 @@ def results_generation(self, beta, order): print("\n------------------------------------------------------------") print("The final coefficients of the regression terms are: \n") print("k |", beta[0, 0]) - results_df = pd.concat([results_df, pd.Series({"k": beta[0, 0]})], axis=0) + results_df = pd.Series({"k": beta[0, 0]}) if self.multinomials == 1: for i in range(1, order + 1): for j in range(1, self.number_of_x_vars + 1): @@ -1449,9 +1450,7 @@ def polynomial_regression_fitting(self, additional_regression_features=None): if r_square_opt > 0.95: self.fit_status = "ok" else: - warnings.warn( - "Polynomial regression generates poor fit for the dataset" - ) + _log.warning("Polynomial regression generates poor fit for the dataset") self.fit_status = "poor" self.pickle_save({"model": self}) @@ -1551,9 +1550,7 @@ def polynomial_regression_fitting(self, additional_regression_features=None): if r_square > 0.95: self.fit_status = "ok" else: - warnings.warn( - "Polynomial regression generates poor fit for the dataset" - ) + _log.warning("Polynomial regression generates poor fit for the dataset") self.fit_status = "poor" self.pickle_save({"model": self}) diff --git a/idaes/core/surrogate/pysmo/radial_basis_function.py b/idaes/core/surrogate/pysmo/radial_basis_function.py index f803727a08..4f628c56b2 100644 --- a/idaes/core/surrogate/pysmo/radial_basis_function.py +++ b/idaes/core/surrogate/pysmo/radial_basis_function.py @@ -18,7 +18,6 @@ # Imports from the python standard library import os.path -import warnings import pickle # Imports from third parties @@ -43,6 +42,9 @@ # Imports from IDAES namespace from idaes.core.surrogate.pysmo.sampling import FeatureScaling as fs +import idaes.logger as idaeslog + +_log = idaeslog.getLogger(__name__) __author__ = "Oluwamayowa Amusat" @@ -1105,7 +1107,7 @@ def training(self): if x_condition_number < (1 / np.finfo(float).eps): self.solution_status = "ok" else: - warnings.warn( + _log.warning( "The parameter matrix A in A.x=B is ill-conditioned (condition number > 1e10). The solution returned may be inaccurate or unstable - inspect rmse error. Regularization (if not already done) may improve solution" ) self.solution_status = "unstable solution" diff --git a/idaes/core/surrogate/pysmo/sampling.py b/idaes/core/surrogate/pysmo/sampling.py index bc72cc76e5..0a6d8d59d7 100644 --- a/idaes/core/surrogate/pysmo/sampling.py +++ b/idaes/core/surrogate/pysmo/sampling.py @@ -15,11 +15,13 @@ # pylint: disable=missing-class-docstring # pylint: disable=missing-function-docstring -import warnings import itertools import numpy as np import pandas as pd +import idaes.logger as idaeslog + +_log = idaeslog.getLogger(__name__) __author__ = "Oluwamayowa Amusat" @@ -180,7 +182,7 @@ def sample_point_selection(self, full_data, sample_points, sampling_type): unique_sample_points = np.unique(points_closest_unscaled, axis=0) if unique_sample_points.shape[0] < points_closest_unscaled.shape[0]: - warnings.warn( + _log.warning( "The returned number of samples is less than the requested number due to repetitions during nearest neighbour selection." ) print( @@ -388,7 +390,7 @@ def selection_columns_preprocessing(self, data_input, xlabels, ylabels): warn_str = "The following columns were dropped: " + str( dropped_cols ) - warnings.warn(warn_str) + _log.warning(warn_str) self.x_data = data_input.filter(xlabels).values self.data_headers = set_of_labels self.data_headers_xvars = xlabels @@ -448,7 +450,7 @@ def selection_columns_preprocessing(self, data_input, xlabels, ylabels): warn_str = "The following columns were dropped: " + str( dropped_cols ) - warnings.warn(warn_str) + _log.warning(warn_str) self.x_data = data_input[:, xlabels] self.data_headers = set_of_labels self.data_headers_xvars = xlabels @@ -1417,7 +1419,7 @@ def __init__( elif tolerance > 0.1: raise ValueError("Tolerance must be less than 0.1 to achieve good results") elif tolerance < 1e-9: - warnings.warn( + _log.warning( "Tolerance too tight. CVT algorithm may take long time to converge." ) elif (tolerance < 0.1) and (tolerance > 1e-9): @@ -1784,7 +1786,7 @@ def generate_from_dist(self, dist_name): ) > 0 ): - warnings.warn( + _log.warning( "Points adjusted to remain within specified Gaussian bounds. This may affect the underlying distribution." ) out_locations = [ @@ -1796,7 +1798,7 @@ def generate_from_dist(self, dist_name): rep_value = var_values[k] while (rep_value < 0) or (rep_value > 1): rep_value = dist(loc=0.5, scale=1 / 6, size=1) - var_values[k] = rep_value + var_values[k] = rep_value[0] assert ( sum([1 for i in range(0, var_values.shape[0]) if var_values[i] > 1]) + sum( diff --git a/idaes/core/surrogate/pysmo/tests/test_kriging.py b/idaes/core/surrogate/pysmo/tests/test_kriging.py index 818c4ea21f..c688383683 100644 --- a/idaes/core/surrogate/pysmo/tests/test_kriging.py +++ b/idaes/core/surrogate/pysmo/tests/test_kriging.py @@ -97,6 +97,9 @@ def test__init__07(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:invalid value encountered in log:RuntimeWarning" + ) def test__init__08(self, array_type): input_array = array_type(self.test_data) file_name = "test_filename.pickle" @@ -107,6 +110,9 @@ def test__init__08(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:invalid value encountered in log:RuntimeWarning" + ) def test__init__09(self, array_type): input_array = array_type(self.test_data) file_name1 = "test_filename1.pickle" @@ -343,9 +349,10 @@ def test_error_calculation(self, array_type): ) ).transpose() cov_matrix_tests = np.exp(-1 * cmt) - y_prediction_exp[i, 0] = mean + np.matmul( + y_prediction_val = mean + np.matmul( np.matmul(cov_matrix_tests.transpose(), cov_inv), y_mu ) + y_prediction_exp[i, 0] = y_prediction_val.item() ss_error, rmse_error, y_prediction = KrigingClass.error_calculation( theta, @@ -402,6 +409,9 @@ def test_r2_calculation(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:invalid value encountered in log:RuntimeWarning" + ) def test_predict_output_01(self, array_type): input_array = array_type(self.training_data) np.random.seed(0) @@ -412,6 +422,9 @@ def test_predict_output_01(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:invalid value encountered in log:RuntimeWarning" + ) def test_predict_output(self, array_type): input_array = array_type(self.training_data) np.random.seed(0) diff --git a/idaes/core/surrogate/pysmo/tests/test_polynomial_regression.py b/idaes/core/surrogate/pysmo/tests/test_polynomial_regression.py index 264a84fc0f..b5300c0ee3 100644 --- a/idaes/core/surrogate/pysmo/tests/test_polynomial_regression.py +++ b/idaes/core/surrogate/pysmo/tests/test_polynomial_regression.py @@ -20,6 +20,7 @@ import numpy as np import pandas as pd import pytest +import idaes.logger as idaeslog class TestFeatureScaling: @@ -300,19 +301,23 @@ def test__init__08(self, array_type1, array_type2): @pytest.mark.unit @pytest.mark.parametrize("array_type1", [np.array, pd.DataFrame]) @pytest.mark.parametrize("array_type2", [np.array, pd.DataFrame]) - def test__init__09(self, array_type1, array_type2): + def test__init__09(self, array_type1, array_type2, caplog): + caplog.set_level(idaeslog.WARNING) + warning_msg = "The number of cross-validations entered is large. The simulation may take a while to run" original_data_input = array_type1(self.test_data) regression_data_input = array_type2(self.sample_points) - with pytest.warns(Warning): - PolyClass = PolynomialRegression( - original_data_input, - regression_data_input, - maximum_polynomial_order=5, - number_of_crossvalidations=11, - ) - assert ( - PolyClass.number_of_crossvalidations == 11 - ) # Default number of cross-validations + PolyClass = PolynomialRegression( + original_data_input, + regression_data_input, + maximum_polynomial_order=5, + number_of_crossvalidations=11, + ) + assert warning_msg in caplog.text + for record in caplog.records: + assert record.levelno == idaeslog.WARNING + assert ( + PolyClass.number_of_crossvalidations == 11 + ) # Default number of cross-validations @pytest.mark.unit @pytest.mark.parametrize("array_type1", [np.array, pd.DataFrame]) @@ -328,14 +333,23 @@ def test__init__10(self, array_type1, array_type2): @pytest.mark.unit @pytest.mark.parametrize("array_type1", [np.array, pd.DataFrame]) @pytest.mark.parametrize("array_type2", [np.array, pd.DataFrame]) - def test__init__11(self, array_type1, array_type2): + def test__init__11(self, array_type1, array_type2, caplog): + caplog.set_level(idaeslog.WARNING) + warning_msg = ( + "The maximum allowed polynomial order is 10. Value has been adjusted to 10." + ) original_data_input = array_type1(self.test_data_large) regression_data_input = array_type2(self.sample_points_large) - with pytest.warns(Warning): - PolyClass = PolynomialRegression( - original_data_input, regression_data_input, maximum_polynomial_order=11 - ) - assert PolyClass.max_polynomial_order == 10 + PolyClass = PolynomialRegression( + original_data_input, regression_data_input, maximum_polynomial_order=11 + ) + warning_msg = ( + "The maximum allowed polynomial order is 10. Value has been adjusted to 10." + ) + assert warning_msg in caplog.text + for record in caplog.records: + assert record.levelno == idaeslog.WARNING + assert PolyClass.max_polynomial_order == 10 @pytest.mark.unit @pytest.mark.parametrize("array_type1", [np.array, pd.DataFrame]) @@ -1645,17 +1659,12 @@ def test_results_generation_01(self, array_type1, array_type2): beta = np.array([[0], [0], [0]]) expected_df = pd.Series() row_list = np.array([["k"], ["(x_1)^1"], ["(x_2)^1"]]) - expected_df = pd.concat( - [ - expected_df, - pd.Series( - { - row_list[0, 0]: beta[0, 0], - row_list[1, 0]: beta[1, 0], - row_list[2, 0]: beta[2, 0], - } - ), - ] + expected_df = pd.Series( + { + row_list[0, 0]: beta[0, 0], + row_list[1, 0]: beta[1, 0], + row_list[2, 0]: beta[2, 0], + } ) output_df = data_feed.results_generation(beta, order) assert output_df.index.to_list() == expected_df.index.to_list() @@ -1687,21 +1696,16 @@ def test_results_generation_02(self, array_type1, array_type2): ["(x_2)^3"], ] ) - expected_df = pd.concat( - [ - expected_df, - pd.Series( - { - row_list[0, 0]: beta[0, 0], - row_list[1, 0]: beta[1, 0], - row_list[2, 0]: beta[2, 0], - row_list[3, 0]: beta[3, 0], - row_list[4, 0]: beta[4, 0], - row_list[5, 0]: beta[5, 0], - row_list[6, 0]: beta[6, 0], - } - ), - ] + expected_df = pd.Series( + { + row_list[0, 0]: beta[0, 0], + row_list[1, 0]: beta[1, 0], + row_list[2, 0]: beta[2, 0], + row_list[3, 0]: beta[3, 0], + row_list[4, 0]: beta[4, 0], + row_list[5, 0]: beta[5, 0], + row_list[6, 0]: beta[6, 0], + } ) output_df = data_feed.results_generation(beta, order) assert output_df.index.to_list() == expected_df.index.to_list() @@ -1725,20 +1729,15 @@ def test_results_generation_03(self, array_type1, array_type2): row_list = np.array( [["k"], ["(x_1)^1"], ["(x_2)^1"], ["(x_1)^2"], ["(x_2)^2"], ["(x_1).(x_2)"]] ) - expected_df = pd.concat( - [ - expected_df, - pd.Series( - { - row_list[0, 0]: beta[0, 0], - row_list[1, 0]: beta[1, 0], - row_list[2, 0]: beta[2, 0], - row_list[3, 0]: beta[3, 0], - row_list[4, 0]: beta[4, 0], - row_list[5, 0]: beta[5, 0], - } - ), - ] + expected_df = pd.Series( + { + row_list[0, 0]: beta[0, 0], + row_list[1, 0]: beta[1, 0], + row_list[2, 0]: beta[2, 0], + row_list[3, 0]: beta[3, 0], + row_list[4, 0]: beta[4, 0], + row_list[5, 0]: beta[5, 0], + } ) output_df = data_feed.results_generation(beta, order) assert output_df.index.to_list() == expected_df.index.to_list() diff --git a/idaes/core/surrogate/pysmo/tests/test_radial_basis_function.py b/idaes/core/surrogate/pysmo/tests/test_radial_basis_function.py index 2b2c9b619b..93a29116ac 100644 --- a/idaes/core/surrogate/pysmo/tests/test_radial_basis_function.py +++ b/idaes/core/surrogate/pysmo/tests/test_radial_basis_function.py @@ -507,6 +507,9 @@ def test_thin_plate_spline_transformation(self): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:(invalid value|divide by zero) encountered in (multiply|log):RuntimeWarning" + ) def test_basis_generation(self, array_type): input_array = array_type(self.training_data) scaled = FeatureScaling.data_scaling_minmax(input_array[0:3]) @@ -2074,6 +2077,9 @@ def test_rbf_predict_output_05(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) + @pytest.mark.filterwarnings( + "ignore:(invalid value|divide by zero) encountered in (multiply|log):RuntimeWarning" + ) def test_rbf_predict_output_06(self, array_type): input_array = array_type(self.training_data) data_feed = RadialBasisFunctions( diff --git a/idaes/core/surrogate/pysmo/tests/test_sampling.py b/idaes/core/surrogate/pysmo/tests/test_sampling.py index 55ee44528e..806c25799f 100644 --- a/idaes/core/surrogate/pysmo/tests/test_sampling.py +++ b/idaes/core/surrogate/pysmo/tests/test_sampling.py @@ -28,6 +28,7 @@ SamplingMethods, FeatureScaling, ) +import idaes.logger as idaeslog class TestFeatureScaling: @@ -2229,18 +2230,21 @@ def test__init__selection_tolerance_too_loose(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) - def test__init__selection_tolerance_too_tight(self, array_type): + def test__init__selection_tolerance_too_tight(self, array_type, caplog): + caplog.set_level(idaeslog.WARNING) + warning_msg = ( + "Tolerance too tight. CVT algorithm may take long time to converge." + ) input_array = array_type(self.input_array) - with pytest.warns( - Warning, - match="Tolerance too tight. CVT algorithm may take long time to converge.", - ): - CVTClass = CVTSampling( - input_array, - number_of_samples=None, - tolerance=1e-10, - sampling_type="selection", - ) + CVTClass = CVTSampling( + input_array, + number_of_samples=None, + tolerance=1e-10, + sampling_type="selection", + ) + assert warning_msg in caplog.text + for record in caplog.records: + assert record.levelno == idaeslog.WARNING @pytest.mark.unit @pytest.mark.parametrize("array_type", [np.array, pd.DataFrame]) @@ -2414,18 +2418,21 @@ def test__init__creation_test_tolerance_too_loose(self, array_type): @pytest.mark.unit @pytest.mark.parametrize("array_type", [list]) - def test__init__creation_tolerance_too_tight(self, array_type): + def test__init__creation_tolerance_too_tight(self, array_type, caplog): + caplog.set_level(idaeslog.WARNING) input_array = array_type(self.input_array_list) - with pytest.warns( - Warning, - match="Tolerance too tight. CVT algorithm may take long time to converge.", - ): - CVTClass = CVTSampling( - input_array, - number_of_samples=None, - tolerance=1e-10, - sampling_type="creation", - ) + warning_msg = ( + "Tolerance too tight. CVT algorithm may take long time to converge." + ) + CVTClass = CVTSampling( + input_array, + number_of_samples=None, + tolerance=1e-10, + sampling_type="creation", + ) + assert warning_msg in caplog.text + for record in caplog.records: + assert record.levelno == idaeslog.WARNING @pytest.mark.unit @pytest.mark.parametrize("array_type", [list]) diff --git a/idaes/core/surrogate/pysmo/tests/test_sampling_modified.py b/idaes/core/surrogate/pysmo/tests/test_sampling_modified.py index b1ee3ef09a..a4e0a92387 100644 --- a/idaes/core/surrogate/pysmo/tests/test_sampling_modified.py +++ b/idaes/core/surrogate/pysmo/tests/test_sampling_modified.py @@ -19,6 +19,7 @@ SamplingMethods, FeatureScaling, ) +import idaes.logger as idaeslog import numpy as np import pandas as pd import pyomo.common.unittest as unittest @@ -2187,13 +2188,19 @@ def test__init__selection_10(self): @pytest.mark.unit def test__init__selection_11(self): input_array = self.test_data_numpy - with pytest.warns(Warning): + warning_msg = ( + "Tolerance too tight. CVT algorithm may take long time to converge." + ) + with self.assertLogs(level="WARNING") as cm: CVTClass = CVTSampling( input_array, number_of_samples=None, tolerance=1e-10, sampling_type="selection", ) + self.assertIn(warning_msg, "\n".join(cm.output)) + for record in cm.records: + self.assertEqual(record.levelno, idaeslog.WARNING) @pytest.mark.unit def test__init__selection_12(self): @@ -2315,14 +2322,20 @@ def test__init__creation_09(self): @pytest.mark.unit def test__init__creation_10(self): + warning_msg = ( + "Tolerance too tight. CVT algorithm may take long time to converge." + ) input_array = self.test_data_list - with pytest.warns(Warning): + with self.assertLogs(level="WARNING") as cm: CVTClass = CVTSampling( input_array, number_of_samples=None, tolerance=1e-10, sampling_type="creation", ) + self.assertIn(warning_msg, "\n".join(cm.output)) + for record in cm.records: + assert record.levelno == idaeslog.WARNING @pytest.mark.unit def test__init__creation_11(self): diff --git a/idaes/core/surrogate/pysmo_surrogate.py b/idaes/core/surrogate/pysmo_surrogate.py index a7e3785caa..aec518fdac 100644 --- a/idaes/core/surrogate/pysmo_surrogate.py +++ b/idaes/core/surrogate/pysmo_surrogate.py @@ -513,7 +513,8 @@ def evaluate_surrogate(self, inputs: pd.DataFrame) -> pd.DataFrame: row_data = inputdata[i, :].reshape(1, len(self._input_labels)) for j, output_label in enumerate(self._output_labels): result = self._trained.get_result(output_label) - outputs[i, j] = result.model.predict_output(row_data) + res_vec = result.model.predict_output(row_data) + outputs[i, j] = res_vec.item() return pd.DataFrame( data=outputs, index=inputs.index, columns=self._output_labels