# Rank-based change (CostRank)#

Bases: BaseCost

Rank-based cost function.

Source code in ruptures/costs/costrank.py
 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 class CostRank(BaseCost): r"""Rank-based cost function.""" model = "rank" def __init__(self): """Initialize the object.""" self.inv_cov = None self.ranks = None self.min_size = 2 def fit(self, signal) -> "CostRank": """Set parameters of the instance. Args: signal (array): signal. Shape (n_samples,) or (n_samples, n_features) Returns: self """ if signal.ndim == 1: signal = signal.reshape(-1, 1) obs, vars = signal.shape # Convert signal data into ranks in the range [1, n] ranks = rankdata(signal, axis=0) # Center the ranks into the range [-(n+1)/2, (n+1)/2] centered_ranks = ranks - ((obs + 1) / 2) # Sigma is the covariance of these ranks. # If it's a scalar, reshape it into a 1x1 matrix cov = np.cov(centered_ranks, rowvar=False, bias=True).reshape(vars, vars) # Use the pseudoinverse to handle linear dependencies # see Lung-Yut-Fong, A., Lévy-Leduc, C., & Cappé, O. (2015) try: self.inv_cov = pinv(cov) except LinAlgError as e: raise LinAlgError( "The covariance matrix of the rank signal is not invertible and the " "pseudo-inverse computation did not converge." ) from e self.ranks = centered_ranks self.signal = signal return self def error(self, start, end): """Return the approximation cost on the segment [start:end]. Args: start (int): start of the segment end (int): end of the segment Returns: float: segment cost Raises: NotEnoughPoints: when the segment is too short (less than min_size samples). """ if end - start < self.min_size: raise NotEnoughPoints mean = np.reshape(np.mean(self.ranks[start:end], axis=0), (-1, 1)) return -(end - start) * mean.T @ self.inv_cov @ mean 

## __init__()#

Initialize the object.

Source code in ruptures/costs/costrank.py
 15 16 17 18 19 def __init__(self): """Initialize the object.""" self.inv_cov = None self.ranks = None self.min_size = 2 

## error(start, end)#

Return the approximation cost on the segment [start:end].

Parameters:

Name Type Description Default
start int

start of the segment

required
end int

end of the segment

required

Returns:

Name Type Description
float

segment cost

Raises:

Type Description
NotEnoughPoints

when the segment is too short (less than min_size samples).

Source code in ruptures/costs/costrank.py
 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 def error(self, start, end): """Return the approximation cost on the segment [start:end]. Args: start (int): start of the segment end (int): end of the segment Returns: float: segment cost Raises: NotEnoughPoints: when the segment is too short (less than min_size samples). """ if end - start < self.min_size: raise NotEnoughPoints mean = np.reshape(np.mean(self.ranks[start:end], axis=0), (-1, 1)) return -(end - start) * mean.T @ self.inv_cov @ mean 

## fit(signal)#

Set parameters of the instance.

Parameters:

Name Type Description Default
signal array

signal. Shape (n_samples,) or (n_samples, n_features)

required

Returns:

Type Description
CostRank

self

Source code in ruptures/costs/costrank.py
 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 def fit(self, signal) -> "CostRank": """Set parameters of the instance. Args: signal (array): signal. Shape (n_samples,) or (n_samples, n_features) Returns: self """ if signal.ndim == 1: signal = signal.reshape(-1, 1) obs, vars = signal.shape # Convert signal data into ranks in the range [1, n] ranks = rankdata(signal, axis=0) # Center the ranks into the range [-(n+1)/2, (n+1)/2] centered_ranks = ranks - ((obs + 1) / 2) # Sigma is the covariance of these ranks. # If it's a scalar, reshape it into a 1x1 matrix cov = np.cov(centered_ranks, rowvar=False, bias=True).reshape(vars, vars) # Use the pseudoinverse to handle linear dependencies # see Lung-Yut-Fong, A., Lévy-Leduc, C., & Cappé, O. (2015) try: self.inv_cov = pinv(cov) except LinAlgError as e: raise LinAlgError( "The covariance matrix of the rank signal is not invertible and the " "pseudo-inverse computation did not converge." ) from e self.ranks = centered_ranks self.signal = signal return self