PeriodicPaddingStrategy.java
package com.morphiqlabs.wavelet.padding;
import com.morphiqlabs.wavelet.exception.InvalidArgumentException;
/**
* Periodic padding strategy that wraps the signal cyclically.
*
* <p>This strategy treats the signal as one period of a periodic function
* and extends it by repeating. It is ideal for:</p>
* <ul>
* <li>Naturally periodic signals (e.g., seasonal financial data)</li>
* <li>Signals extracted from cyclic phenomena</li>
* <li>Maintaining continuity at boundaries</li>
* </ul>
*
* <p>Example: {@code [1, 2, 3, 4]} padded to length 8 becomes {@code [1, 2, 3, 4, 1, 2, 3, 4]}</p>
*/
public record PeriodicPaddingStrategy() implements PaddingStrategy {
@Override
public double[] pad(double[] signal, int targetLength) {
if (signal == null) {
throw new InvalidArgumentException("Signal cannot be null");
}
if (signal.length == 0) {
throw new InvalidArgumentException("Signal cannot be empty");
}
if (targetLength < signal.length) {
throw new InvalidArgumentException(
"Target length " + targetLength + " must be >= signal length " + signal.length);
}
if (targetLength == signal.length) {
return signal.clone();
}
double[] padded = new double[targetLength];
// Efficiently copy full periods
int fullCopies = targetLength / signal.length;
for (int i = 0; i < fullCopies; i++) {
System.arraycopy(signal, 0, padded, i * signal.length, signal.length);
}
// Copy remaining partial period
int remaining = targetLength % signal.length;
if (remaining > 0) {
System.arraycopy(signal, 0, padded, fullCopies * signal.length, remaining);
}
return padded;
}
@Override
public String name() {
return "periodic";
}
@Override
public String description() {
return "Periodic padding - wraps signal cyclically";
}
}