Implement mlx.core.blackman (#3136)
This commit is contained in:
+27
@@ -2346,6 +2346,33 @@ array hamming(int M, StreamOrDevice s /* = {} */) {
|
||||
return subtract(left_coef, multiply(right_coef, cos_vals, s), s);
|
||||
}
|
||||
|
||||
array blackman(int M, StreamOrDevice s /* = {} */) {
|
||||
if (M < 1) {
|
||||
return array({});
|
||||
}
|
||||
if (M == 1) {
|
||||
return ones({1}, float32, s);
|
||||
}
|
||||
|
||||
auto n = arange(0, M, float32, s);
|
||||
|
||||
float arg_val = (2.0 * M_PI) / (M - 1);
|
||||
auto x = multiply(array(arg_val, float32), n, s);
|
||||
|
||||
auto cos_x = cos(x, s);
|
||||
|
||||
auto alpha = array(0.34f, float32);
|
||||
auto beta = array(0.5f, float32);
|
||||
auto gamma = array(0.16f, float32);
|
||||
|
||||
auto term1 = multiply(beta, cos_x, s);
|
||||
|
||||
auto cos_sq = square(cos_x, s);
|
||||
auto term2 = multiply(gamma, cos_sq, s);
|
||||
|
||||
return add(subtract(alpha, term1, s), term2, s);
|
||||
}
|
||||
|
||||
/** Returns a sorted copy of the flattened array. */
|
||||
array sort(const array& a, StreamOrDevice s /* = {} */) {
|
||||
int size = a.size();
|
||||
|
||||
@@ -672,6 +672,9 @@ MLX_API array hanning(int M, StreamOrDevice s = {});
|
||||
/** Returns the Hamming window of size M. */
|
||||
MLX_API array hamming(int M, StreamOrDevice s = {});
|
||||
|
||||
/** Returns the Blackmann window of size M. */
|
||||
MLX_API array blackman(int M, StreamOrDevice s = {});
|
||||
|
||||
/** Returns the index of the minimum value in the array. */
|
||||
MLX_API array argmin(const array& a, bool keepdims, StreamOrDevice s = {});
|
||||
inline array argmin(const array& a, StreamOrDevice s = {}) {
|
||||
|
||||
@@ -1475,6 +1475,30 @@ void init_ops(nb::module_& m) {
|
||||
appears only if the number of samples is odd).
|
||||
)pbdoc");
|
||||
m.def(
|
||||
"blackman",
|
||||
&mlx::core::blackman,
|
||||
"M"_a,
|
||||
nb::kw_only(),
|
||||
"stream"_a = nb::none(),
|
||||
nb::sig(
|
||||
"def blackman(M: int, *, stream: Union[None, Stream, Device] = None) -> array"), // <--- J'ai rajouté ça
|
||||
R"pbdoc(
|
||||
Return the Blackman window.
|
||||
|
||||
The Blackman window is a taper formed by using the first three terms of a summation of cosines.
|
||||
|
||||
.. math::
|
||||
w(n) = 0.42 - 0.5 \cos\left(\frac{2\pi n}{M-1}\right) + 0.08 \cos\left(\frac{4\pi n}{M-1}\right)
|
||||
\qquad 0 \le n \le M-1
|
||||
|
||||
Args:
|
||||
M (int): Number of points in the output window.
|
||||
|
||||
Returns:
|
||||
array: The window, with the maximum value normalized to one (the value one
|
||||
appears only if the number of samples is odd).
|
||||
)pbdoc");
|
||||
m.def(
|
||||
"linspace",
|
||||
[](Scalar start,
|
||||
Scalar stop,
|
||||
|
||||
@@ -1474,6 +1474,18 @@ class TestOps(mlx_tests.MLXTestCase):
|
||||
self.assertEqual(a.size, 0)
|
||||
self.assertEqual(a.dtype, mx.float32)
|
||||
|
||||
def test_blackman_general(self):
|
||||
a = mx.blackman(10)
|
||||
expected = np.blackman(10)
|
||||
self.assertTrue(np.allclose(a, expected, atol=1e-5))
|
||||
|
||||
a = mx.blackman(1)
|
||||
self.assertEqual(a.item(), 1.0)
|
||||
|
||||
a = mx.blackman(0)
|
||||
self.assertEqual(a.size, 0)
|
||||
self.assertEqual(a.dtype, mx.float32)
|
||||
|
||||
def test_unary_ops(self):
|
||||
def test_ops(npop, mlxop, x, y, atol, rtol):
|
||||
r_np = npop(x)
|
||||
|
||||
Reference in New Issue
Block a user