|
12 | 12 | from qolmat.utils.exceptions import CostFunctionRPCANotMinimized |
13 | 13 |
|
14 | 14 |
|
15 | | -def _check_cost_function_minimized( |
16 | | - observations: NDArray, |
17 | | - low_rank: NDArray, |
18 | | - anomalies: NDArray, |
19 | | - tau: float, |
20 | | - lam: float, |
21 | | - norm: str, |
22 | | -): |
23 | | - """Check that the functional minimized by the RPCA |
24 | | - is smaller at the end than at the beginning |
25 | | -
|
26 | | - Parameters |
27 | | - ---------- |
28 | | - observations : NDArray |
29 | | - observations matrix with first linear interpolation |
30 | | - low_rank : NDArray |
31 | | - low_rank matrix resulting from RPCA |
32 | | - anomalies : NDArray |
33 | | - sparse matrix resulting from RPCA |
34 | | - tau : float |
35 | | - parameter penalizing the nuclear norm of the low rank part |
36 | | - lam : float |
37 | | - parameter penalizing the L1-norm of the anomaly/sparse part |
38 | | - norm : str |
39 | | - norm of the temporal penalisation. Has to be `L1` or `L2` |
40 | | -
|
41 | | - Raises |
42 | | - ------ |
43 | | - CostFunctionRPCANotMinimized |
44 | | - The RPCA does not minimized the cost function: |
45 | | - the starting cost is at least equal to the final one. |
46 | | - """ |
47 | | - value_start = tau * np.linalg.norm(observations, "nuc") |
48 | | - if norm == "L1": |
49 | | - anomalies_norm = np.sum(np.abs(anomalies)) |
50 | | - function_str = "||D-M-A||_2 + tau ||D||_* + lam ||A||_1" |
51 | | - elif norm == "L2": |
52 | | - anomalies_norm = np.sum(anomalies**2) |
53 | | - function_str = "||D-M-A||_2 + tau ||D||_* + lam ||A||_2" |
54 | | - value_end = ( |
55 | | - np.sum((observations - low_rank - anomalies) ** 2) |
56 | | - + tau * np.linalg.norm(low_rank, "nuc") |
57 | | - + lam * anomalies_norm |
58 | | - ) |
59 | | - if value_start + 1e-4 < value_end: |
60 | | - raise CostFunctionRPCANotMinimized(function_str, value_start, value_end) |
61 | | - |
62 | | - |
63 | 15 | class RPCANoisy(RPCA): |
64 | 16 | """ |
65 | 17 | This class implements a noisy version of the so-called 'improved RPCA' |
@@ -423,12 +375,54 @@ def decompose_rpca(self, D: NDArray, Omega: NDArray) -> Tuple[NDArray, NDArray]: |
423 | 375 | elif self.norm == "L2": |
424 | 376 | M, A, U, V = self.decompose_rpca_L2(D, Omega, lam, tau, rank) |
425 | 377 |
|
426 | | - print("D") |
427 | | - print(D) |
428 | | - print("M") |
429 | | - print(M) |
430 | | - print("A") |
431 | | - print(A) |
432 | | - _check_cost_function_minimized(D, M, A, tau, lam, self.norm) |
| 378 | + self._check_cost_function_minimized(D, M, A, tau, lam, self.norm) |
433 | 379 |
|
434 | 380 | return M, A |
| 381 | + |
| 382 | + @staticmethod |
| 383 | + def _check_cost_function_minimized( |
| 384 | + observations: NDArray, |
| 385 | + low_rank: NDArray, |
| 386 | + anomalies: NDArray, |
| 387 | + tau: float, |
| 388 | + lam: float, |
| 389 | + norm: str, |
| 390 | + ): |
| 391 | + """Check that the functional minimized by the RPCA |
| 392 | + is smaller at the end than at the beginning |
| 393 | +
|
| 394 | + Parameters |
| 395 | + ---------- |
| 396 | + observations : NDArray |
| 397 | + observations matrix with first linear interpolation |
| 398 | + low_rank : NDArray |
| 399 | + low_rank matrix resulting from RPCA |
| 400 | + anomalies : NDArray |
| 401 | + sparse matrix resulting from RPCA |
| 402 | + tau : float |
| 403 | + parameter penalizing the nuclear norm of the low rank part |
| 404 | + lam : float |
| 405 | + parameter penalizing the L1-norm of the anomaly/sparse part |
| 406 | + norm : str |
| 407 | + norm of the temporal penalisation. Has to be `L1` or `L2` |
| 408 | +
|
| 409 | + Raises |
| 410 | + ------ |
| 411 | + CostFunctionRPCANotMinimized |
| 412 | + The RPCA does not minimized the cost function: |
| 413 | + the starting cost is at least equal to the final one. |
| 414 | + """ |
| 415 | + value_start = tau * np.linalg.norm(observations, "nuc") |
| 416 | + if norm == "L1": |
| 417 | + anomalies_norm = np.sum(np.abs(anomalies)) |
| 418 | + function_str = "||D-M-A||_2 + tau ||D||_* + lam ||A||_1" |
| 419 | + elif norm == "L2": |
| 420 | + anomalies_norm = np.sum(anomalies**2) |
| 421 | + function_str = "||D-M-A||_2 + tau ||D||_* + lam ||A||_2" |
| 422 | + value_end = ( |
| 423 | + np.sum((observations - low_rank - anomalies) ** 2) |
| 424 | + + tau * np.linalg.norm(low_rank, "nuc") |
| 425 | + + lam * anomalies_norm |
| 426 | + ) |
| 427 | + if value_start + 1e-4 <= value_end: |
| 428 | + raise CostFunctionRPCANotMinimized(function_str, value_start, value_end) |
0 commit comments