|
1 | 1 | /* |
2 | | - * Copyright 2019, 2024 Stefan Zobel |
| 2 | + * Copyright 2019, 2025 Stefan Zobel |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
@@ -3735,6 +3735,92 @@ public static MatrixF colsAverage(MatrixF A) { |
3735 | 3735 | return sumColumns(A).scaleInplace(1.0f / A.numColumns()); |
3736 | 3736 | } |
3737 | 3737 |
|
| 3738 | + /** |
| 3739 | + * Constructs a {@code (r * (delays - 1) x (c - delays))} time-delay |
| 3740 | + * embedding matrix (a.k.a Hankel matrix) from a {@code (r x c)} time series |
| 3741 | + * matrix. |
| 3742 | + * |
| 3743 | + * @param data |
| 3744 | + * a {@code (r x c)} time series matrix where {@code r} is the |
| 3745 | + * dimension of a single observation and {@code c} is the time |
| 3746 | + * dimension of the observations (equispaced, with the first |
| 3747 | + * observation in column {@code 0} and the last one in column |
| 3748 | + * {@code c - 1} |
| 3749 | + * @param delays |
| 3750 | + * the positive number of time-shifts to apply |
| 3751 | + * @return a Hankel matrix produced by stacking time-shifted snapshots of |
| 3752 | + * {@code data} |
| 3753 | + * @throws IllegalArgumentException |
| 3754 | + * if delays < 0 or delays >= data.numColumns() |
| 3755 | + * @since 1.4.7 |
| 3756 | + */ |
| 3757 | + public static MatrixD timeDelayEmbeddingD(MatrixD data, int delays) { |
| 3758 | + if (delays < 0 || delays >= data.numColumns()) { |
| 3759 | + throw new IllegalArgumentException("delays: " + delays); |
| 3760 | + } |
| 3761 | + if (delays == 0) { |
| 3762 | + return data.copy(); |
| 3763 | + } |
| 3764 | + // setup Hankel matrix |
| 3765 | + MatrixD H = createD(data.numRows() * (delays + 1), data.numColumns() - delays); |
| 3766 | + for (int col = 0; col < data.numColumns() - delays; ++col) { |
| 3767 | + int row_ = 0; |
| 3768 | + int col_ = col; |
| 3769 | + for (int row = 0; row < data.numRows() * (delays + 1); ++row) { |
| 3770 | + H.setUnsafe(row, col, data.getUnsafe(row_, col_)); |
| 3771 | + ++row_; |
| 3772 | + if (row_ == data.numRows()) { |
| 3773 | + row_ = 0; |
| 3774 | + ++col_; |
| 3775 | + } |
| 3776 | + } |
| 3777 | + } |
| 3778 | + return H; |
| 3779 | + } |
| 3780 | + |
| 3781 | + /** |
| 3782 | + * Constructs a {@code (r * (delays - 1) x (c - delays))} time-delay |
| 3783 | + * embedding matrix (a.k.a Hankel matrix) from a {@code (r x c)} time series |
| 3784 | + * matrix. |
| 3785 | + * |
| 3786 | + * @param data |
| 3787 | + * a {@code (r x c)} time series matrix where {@code r} is the |
| 3788 | + * dimension of a single observation and {@code c} is the time |
| 3789 | + * dimension of the observations (equispaced, with the first |
| 3790 | + * observation in column {@code 0} and the last one in column |
| 3791 | + * {@code c - 1} |
| 3792 | + * @param delays |
| 3793 | + * the positive number of time-shifts to apply |
| 3794 | + * @return a Hankel matrix produced by stacking time-shifted snapshots of |
| 3795 | + * {@code data} |
| 3796 | + * @throws IllegalArgumentException |
| 3797 | + * if delays < 0 or delays >= data.numColumns() |
| 3798 | + * @since 1.4.7 |
| 3799 | + */ |
| 3800 | + public static MatrixF timeDelayEmbeddingF(MatrixF data, int delays) { |
| 3801 | + if (delays < 0 || delays >= data.numColumns()) { |
| 3802 | + throw new IllegalArgumentException("delays: " + delays); |
| 3803 | + } |
| 3804 | + if (delays == 0) { |
| 3805 | + return data.copy(); |
| 3806 | + } |
| 3807 | + // setup Hankel matrix |
| 3808 | + MatrixF H = createF(data.numRows() * (delays + 1), data.numColumns() - delays); |
| 3809 | + for (int col = 0; col < data.numColumns() - delays; ++col) { |
| 3810 | + int row_ = 0; |
| 3811 | + int col_ = col; |
| 3812 | + for (int row = 0; row < data.numRows() * (delays + 1); ++row) { |
| 3813 | + H.setUnsafe(row, col, data.getUnsafe(row_, col_)); |
| 3814 | + ++row_; |
| 3815 | + if (row_ == data.numRows()) { |
| 3816 | + row_ = 0; |
| 3817 | + ++col_; |
| 3818 | + } |
| 3819 | + } |
| 3820 | + } |
| 3821 | + return H; |
| 3822 | + } |
| 3823 | + |
3738 | 3824 | private static boolean checkApproxEqualArgs(MatrixDimensions A, MatrixDimensions B, double relTol, double absTol) { |
3739 | 3825 | if (relTol < 0.0 || Double.isNaN(relTol) || Double.isInfinite(relTol)) { |
3740 | 3826 | throw new IllegalArgumentException("illegal relTol : " + relTol); |
|
0 commit comments