|
2 | 2 | from typing import Callable, List, Tuple |
3 | 3 |
|
4 | 4 | import numpy as np |
| 5 | +import dask.array as da |
5 | 6 | import pandas as pd |
6 | 7 | from scipy.optimize import fmin, fminbound |
7 | 8 |
|
@@ -278,6 +279,9 @@ def __init__( |
278 | 279 | # Exclude attributes to .save_model() method |
279 | 280 | self._exclude_attributes = [] |
280 | 281 |
|
| 282 | + # Row chunks for parallel computation |
| 283 | + self.row_chunks: int = None |
| 284 | + |
281 | 285 | @property |
282 | 286 | def sigma_min(self) -> float: |
283 | 287 | return self._sigma_min |
@@ -714,24 +718,50 @@ def _rbf_variable_interpolation( |
714 | 718 | The interpolated variable. |
715 | 719 | """ |
716 | 720 |
|
717 | | - r = np.linalg.norm( |
718 | | - normalized_dataset.values[:, np.newaxis, :] |
719 | | - - self.normalized_subset_data.values[np.newaxis, :, :], |
720 | | - axis=2, |
721 | | - ) |
722 | | - kernel_values = self.kernel_func(r, opt_sigma) |
723 | | - linear_part = np.dot( |
724 | | - normalized_dataset.values, |
725 | | - rbf_coeff[ |
726 | | - num_points_subset + 1 : num_points_subset + 1 + num_vars_subset |
727 | | - ].T, |
728 | | - ) |
| 721 | + # Calculate optimal chunk size based on memory |
| 722 | + norm_dataset = normalized_dataset.values |
| 723 | + norm_subset = self.normalized_subset_data.values |
729 | 724 |
|
730 | | - return ( |
731 | | - rbf_coeff[num_points_subset] |
732 | | - + np.dot(kernel_values, rbf_coeff[:num_points_subset]) |
733 | | - + linear_part |
734 | | - ) |
| 725 | + if self.row_chunks is not None: |
| 726 | + chunks = (min(self.row_chunks, norm_dataset.shape[0]), -1) |
| 727 | + self.logger.info(f"Using row chunks of size {chunks[0]}") |
| 728 | + # elif self.num_workers > 1: |
| 729 | + # chunks = (norm_dataset.shape[0] // self.num_workers, -1) |
| 730 | + else: |
| 731 | + chunks = (norm_dataset.shape[0], -1) |
| 732 | + |
| 733 | + # Convert to dask arrays for large operations |
| 734 | + d_dataset = da.from_array(norm_dataset, chunks=chunks) |
| 735 | + d_subset = da.from_array(norm_subset) |
| 736 | + |
| 737 | + # Split computation into chunks |
| 738 | + result = [] |
| 739 | + for i in range(0, len(d_dataset), chunks[0]): |
| 740 | + chunk = d_dataset[i : i + chunks[0]] |
| 741 | + |
| 742 | + # Calculate r for this chunk |
| 743 | + r_chunk = da.linalg.norm(chunk[:, None, :] - d_subset[None, :, :], axis=2) |
| 744 | + |
| 745 | + # Apply kernel and dot product |
| 746 | + kernel_values = self.kernel_func(r_chunk, opt_sigma) |
| 747 | + |
| 748 | + # Compute this chunk's result |
| 749 | + chunk_result = ( |
| 750 | + rbf_coeff[num_points_subset] |
| 751 | + + da.dot(kernel_values, rbf_coeff[:num_points_subset]) |
| 752 | + + da.dot( |
| 753 | + chunk, |
| 754 | + rbf_coeff[ |
| 755 | + num_points_subset + 1 : num_points_subset + 1 + num_vars_subset |
| 756 | + ].T, |
| 757 | + ) |
| 758 | + ) |
| 759 | + |
| 760 | + # Compute and append |
| 761 | + result.append(chunk_result.compute()) |
| 762 | + |
| 763 | + # Combine results |
| 764 | + return np.concatenate(result) |
735 | 765 |
|
736 | 766 | def _rbf_interpolate( |
737 | 767 | self, dataset: pd.DataFrame, num_workers: int = None |
|
0 commit comments