import numpy as np from converted_code.smartmean import smartmean def smartstd(x, dim=None): """ Python implementation of the MATLAB smartstd function. Calculates the standard deviation while ignoring NaN and Inf values. Uses N (not N-1) for normalization. Parameters: x (ndarray): Input array dim (int, optional): Dimension along which to compute the standard deviation Returns: ndarray: Standard deviation along the specified dimension, ignoring NaN/Inf """ if isinstance(x, list): x = np.array(x) # If dimension is not specified, find the first non-singleton dimension if dim is None: # Find the first dimension with size > 1 if len(x.shape) == 1: dim = 0 else: non_singleton_dims = [i for i, size in enumerate(x.shape) if size > 1] dim = non_singleton_dims[0] if non_singleton_dims else 0 # Compute mean along the specified dimension mean_x = smartmean(x, dim) # Create a tile for broadcasting mean back to original dimensions tile_shape = list(x.shape) tile_shape[dim] = 1 # Reshape mean to be broadcastable broadcast_shape = [1] * len(x.shape) broadcast_shape[dim] = mean_x.shape[0] if dim == 0 else mean_x.shape[1] if dim == 0: mean_reshaped = mean_x.reshape(1, -1) x_centered = x - np.tile(mean_reshaped, (x.shape[0], 1)) elif dim == 1: mean_reshaped = mean_x.reshape(-1, 1) x_centered = x - np.tile(mean_reshaped, (1, x.shape[1])) else: # For higher dimensions - this might need more complex handling raise ValueError("Dimensions higher than 2 not fully supported yet") # Get finite mask mask = np.isfinite(x) # Zero out non-finite values in centered data x_centered = np.where(mask, x_centered, 0) # Square the differences squared_diff = np.square(x_centered) # Compute the mean of squares (using N, not N-1) result = np.sqrt(smartmean(squared_diff, dim)) return result