From 4bbd9382f803842098490607827c204fc9ac9da2 Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Thu, 20 Nov 2025 19:53:32 +0900 Subject: [PATCH 1/6] Add ldexp initial version --- keras/api/_tf_keras/keras/ops/__init__.py | 1 + .../api/_tf_keras/keras/ops/numpy/__init__.py | 1 + keras/api/ops/__init__.py | 1 + keras/api/ops/numpy/__init__.py | 1 + keras/src/backend/jax/numpy.py | 6 +++ keras/src/backend/numpy/numpy.py | 7 +++ keras/src/backend/tensorflow/numpy.py | 9 ++++ keras/src/backend/torch/numpy.py | 6 +++ keras/src/ops/numpy.py | 47 +++++++++++++++++++ 9 files changed, 79 insertions(+) diff --git a/keras/api/_tf_keras/keras/ops/__init__.py b/keras/api/_tf_keras/keras/ops/__init__.py index e22715971d62..01e7d9f806b3 100644 --- a/keras/api/_tf_keras/keras/ops/__init__.py +++ b/keras/api/_tf_keras/keras/ops/__init__.py @@ -215,6 +215,7 @@ from keras.src.ops.numpy import kaiser as kaiser from keras.src.ops.numpy import kron as kron from keras.src.ops.numpy import lcm as lcm +from keras.src.ops.numpy import ldexp as ldexp from keras.src.ops.numpy import left_shift as left_shift from keras.src.ops.numpy import less as less from keras.src.ops.numpy import less_equal as less_equal diff --git a/keras/api/_tf_keras/keras/ops/numpy/__init__.py b/keras/api/_tf_keras/keras/ops/numpy/__init__.py index 82b6b6dff363..ad912016ee44 100644 --- a/keras/api/_tf_keras/keras/ops/numpy/__init__.py +++ b/keras/api/_tf_keras/keras/ops/numpy/__init__.py @@ -101,6 +101,7 @@ from keras.src.ops.numpy import kaiser as kaiser from keras.src.ops.numpy import kron as kron from keras.src.ops.numpy import lcm as lcm +from keras.src.ops.numpy import ldexp as ldexp from keras.src.ops.numpy import left_shift as left_shift from keras.src.ops.numpy import less as less from keras.src.ops.numpy import less_equal as less_equal diff --git a/keras/api/ops/__init__.py b/keras/api/ops/__init__.py index e22715971d62..01e7d9f806b3 100644 --- a/keras/api/ops/__init__.py +++ b/keras/api/ops/__init__.py @@ -215,6 +215,7 @@ from keras.src.ops.numpy import kaiser as kaiser from keras.src.ops.numpy import kron as kron from keras.src.ops.numpy import lcm as lcm +from keras.src.ops.numpy import ldexp as ldexp from keras.src.ops.numpy import left_shift as left_shift from keras.src.ops.numpy import less as less from keras.src.ops.numpy import less_equal as less_equal diff --git a/keras/api/ops/numpy/__init__.py b/keras/api/ops/numpy/__init__.py index 82b6b6dff363..ad912016ee44 100644 --- a/keras/api/ops/numpy/__init__.py +++ b/keras/api/ops/numpy/__init__.py @@ -101,6 +101,7 @@ from keras.src.ops.numpy import kaiser as kaiser from keras.src.ops.numpy import kron as kron from keras.src.ops.numpy import lcm as lcm +from keras.src.ops.numpy import ldexp as ldexp from keras.src.ops.numpy import left_shift as left_shift from keras.src.ops.numpy import less as less from keras.src.ops.numpy import less_equal as less_equal diff --git a/keras/src/backend/jax/numpy.py b/keras/src/backend/jax/numpy.py index 15df1b7696f6..445b13559b30 100644 --- a/keras/src/backend/jax/numpy.py +++ b/keras/src/backend/jax/numpy.py @@ -845,6 +845,12 @@ def lcm(x1, x2): return jnp.lcm(x1, x2) +def ldexp(x1, x2): + x1 = convert_to_tensor(x1) + x2 = convert_to_tensor(x2) + return jnp.ldexp(x1, x2) + + def less(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) diff --git a/keras/src/backend/numpy/numpy.py b/keras/src/backend/numpy/numpy.py index eb8b7111ed8f..fc06f83704ce 100644 --- a/keras/src/backend/numpy/numpy.py +++ b/keras/src/backend/numpy/numpy.py @@ -773,6 +773,13 @@ def lcm(x1, x2): return np.lcm(x1, x2).astype(dtype) +def ldexp(x1, x2): + x1 = convert_to_tensor(x1) + x2 = convert_to_tensor(x2) + dtype = dtypes.result_type(x1.dtype, x2.dtype) + return np.ldexp(x1, x2).astype(dtype) + + def less(x1, x2): return np.less(x1, x2) diff --git a/keras/src/backend/tensorflow/numpy.py b/keras/src/backend/tensorflow/numpy.py index c1f4e8066e37..37b35cfcb2d2 100644 --- a/keras/src/backend/tensorflow/numpy.py +++ b/keras/src/backend/tensorflow/numpy.py @@ -1844,6 +1844,15 @@ def lcm(x1, x2): return result +def ldexp(x1, x2): + x1 = convert_to_tensor(x1) + x2 = convert_to_tensor(x2) + dtype = dtypes.result_type(x1.dtype, x2.dtype) + x1 = tf.cast(x1, tf.float32) + x2 = tf.cast(x2, tf.float32) + return tf.cast(x1 * tf.pow(2.0, x2), dtype) + + def less(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) diff --git a/keras/src/backend/torch/numpy.py b/keras/src/backend/torch/numpy.py index bd2a5cea2ac1..c53a387278d9 100644 --- a/keras/src/backend/torch/numpy.py +++ b/keras/src/backend/torch/numpy.py @@ -975,6 +975,12 @@ def lcm(x1, x2): return torch.lcm(x1, x2) +def ldexp(x1, x2): + x1 = convert_to_tensor(x1) + x2 = convert_to_tensor(x2) + return torch.ldexp(x1, x2) + + def less(x1, x2): x1, x2 = convert_to_tensor(x1), convert_to_tensor(x2) return torch.less(x1, x2) diff --git a/keras/src/ops/numpy.py b/keras/src/ops/numpy.py index 5190ff2cd807..37c7c54ce535 100644 --- a/keras/src/ops/numpy.py +++ b/keras/src/ops/numpy.py @@ -4059,6 +4059,53 @@ def lcm(x1, x2): return backend.numpy.lcm(x1, x2) +class Ldexp(Operation): + def call(self, x1, x2): + return backend.numpy.ldexp(x1, x2) + + def compute_output_spec(self, x1, x2): + x1_shape = getattr(x1, "shape", []) + x2_shape = getattr(x2, "shape", []) + output_shape = broadcast_shapes(x1_shape, x2_shape) + + x1_type = backend.standardize_dtype(getattr(x1, "dtype", type(x1))) + x2_type = backend.standardize_dtype(getattr(x2, "dtype", type(x2))) + dtype = dtypes.result_type(x1_type, x2_type) + return KerasTensor(output_shape, dtype=dtype) + + +@keras_export(["keras.ops.ldexp", "keras.ops.numpy.ldexp"]) +def ldexp(x1, x2): + """Multiply `x1` by 2 raised to the power of `x2`, element-wise. + + This function computes: + ldexp(x1, x2) = x1 * 2**x2 + + Notes: + - TensorFlow does *not* provide a built-in `tf.math.ldexp`. + - The `backend.numpy.ldexp` implementation in TF NumPy is currently + unreliable due to a naming-collision bug and should not be used. + - This implementation provides correct broadcasting, dtype inference, + and gradient support. + + Args: + x1: Floating-point input tensor. + x2: Integer or floating-point exponent tensor. + + Returns: + Output tensor, element-wise equal to `x1 * 2**x2`. + + Example: + >>> x1 = keras.ops.convert_to_tensor([0.75, 1.5]) + >>> x2 = keras.ops.convert_to_tensor([1, 2]) + >>> keras.ops.ldexp(x1, x2) + array([1.5, 6. ], dtype=float32) + """ + if any_symbolic_tensors((x1, x2)): + return Ldexp().symbolic_call(x1, x2) + return backend.numpy.ldexp(x1, x2) + + class Less(Operation): def call(self, x1, x2): return backend.numpy.less(x1, x2) From e682f7ccf351b55ebb445b461ef70f044e90b72f Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Thu, 20 Nov 2025 21:17:38 +0900 Subject: [PATCH 2/6] Add numpy_test for ldexp --- keras/src/backend/jax/numpy.py | 7 ++++ keras/src/backend/numpy/numpy.py | 11 ++++- .../openvino/excluded_concrete_tests.txt | 4 ++ keras/src/backend/openvino/numpy.py | 4 ++ keras/src/backend/tensorflow/numpy.py | 9 +++- keras/src/backend/torch/numpy.py | 10 ++++- keras/src/ops/numpy.py | 15 ++----- keras/src/ops/numpy_test.py | 41 +++++++++++++++++++ 8 files changed, 87 insertions(+), 14 deletions(-) diff --git a/keras/src/backend/jax/numpy.py b/keras/src/backend/jax/numpy.py index 445b13559b30..24eea3b402a7 100644 --- a/keras/src/backend/jax/numpy.py +++ b/keras/src/backend/jax/numpy.py @@ -848,6 +848,13 @@ def lcm(x1, x2): def ldexp(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) + + if standardize_dtype(x2.dtype) not in dtypes.INT_TYPES: + raise TypeError( + f"ldexp exponent must be an integer type. " + f"Received: x2 dtype={x2.dtype}" + ) + return jnp.ldexp(x1, x2) diff --git a/keras/src/backend/numpy/numpy.py b/keras/src/backend/numpy/numpy.py index fc06f83704ce..1525743fed1b 100644 --- a/keras/src/backend/numpy/numpy.py +++ b/keras/src/backend/numpy/numpy.py @@ -776,7 +776,16 @@ def lcm(x1, x2): def ldexp(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) - dtype = dtypes.result_type(x1.dtype, x2.dtype) + dtype = dtypes.result_type(x1.dtype, x2.dtype, float) + + if standardize_dtype(x2.dtype) not in dtypes.INT_TYPES: + raise TypeError( + f"ldexp exponent must be an integer type. " + f"Received: x2 dtype={x2.dtype}" + ) + + x1 = np.asarray(x1).astype(np.float32) + x2 = np.asarray(x2).astype(np.int32) return np.ldexp(x1, x2).astype(dtype) diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index 7c5d295a44da..b26482a13ba2 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -29,6 +29,7 @@ NumpyDtypeTest::test_isin NumpyDtypeTest::test_isreal NumpyDtypeTest::test_kron NumpyDtypeTest::test_lcm +NumpyDtypeTest::test_ldexp NumpyDtypeTest::test_logaddexp2 NumpyDtypeTest::test_matmul_ NumpyDtypeTest::test_maximum_python_types @@ -108,6 +109,7 @@ NumpyTwoInputOpsCorrectnessTest::test_inner NumpyTwoInputOpsCorrectnessTest::test_isin NumpyTwoInputOpsCorrectnessTest::test_kron NumpyTwoInputOpsCorrectnessTest::test_lcm +NumpyTwoInputOpsCorrectnessTest::test_ldexp NumpyTwoInputOpsCorrectnessTest::test_quantile NumpyTwoInputOpsCorrectnessTest::test_tensordot NumpyTwoInputOpsCorrectnessTest::test_vdot @@ -131,11 +133,13 @@ NumpyTwoInputOpsDynamicShapeTest::test_hypot NumpyTwoInputOpsDynamicShapeTest::test_isin NumpyTwoInputOpsDynamicShapeTest::test_kron NumpyTwoInputOpsDynamicShapeTest::test_lcm +NumpyTwoInputOpsDynamicShapeTest::test_ldexp NumpyTwoInputOpsStaticShapeTest::test_gcd NumpyTwoInputOpsStaticShapeTest::test_hypot NumpyTwoInputOpsStaticShapeTest::test_isin NumpyTwoInputOpsStaticShapeTest::test_kron NumpyTwoInputOpsStaticShapeTest::test_lcm +NumpyTwoInputOpsStaticShapeTest::test_ldexp CoreOpsBehaviorTests::test_associative_scan_invalid_arguments CoreOpsBehaviorTests::test_scan_invalid_arguments CoreOpsCallsTests::test_associative_scan_basic_call diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 445ddb7b1fd4..5e73bb3c840a 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1149,6 +1149,10 @@ def lcm(x1, x2): raise NotImplementedError("`lcm` is not supported with openvino backend") +def ldexp(x1, x2): + raise NotImplementedError("`ldexp` is not supported with openvino backend") + + def less(x1, x2): element_type = None if isinstance(x1, OpenVINOKerasTensor): diff --git a/keras/src/backend/tensorflow/numpy.py b/keras/src/backend/tensorflow/numpy.py index 37b35cfcb2d2..d166b3b30f03 100644 --- a/keras/src/backend/tensorflow/numpy.py +++ b/keras/src/backend/tensorflow/numpy.py @@ -1847,7 +1847,14 @@ def lcm(x1, x2): def ldexp(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) - dtype = dtypes.result_type(x1.dtype, x2.dtype) + dtype = dtypes.result_type(x1.dtype, x2.dtype, float) + + if standardize_dtype(x2.dtype) not in dtypes.INT_TYPES: + raise TypeError( + f"ldexp exponent must be an integer type. " + f"Received: x2 dtype={x2.dtype}" + ) + x1 = tf.cast(x1, tf.float32) x2 = tf.cast(x2, tf.float32) return tf.cast(x1 * tf.pow(2.0, x2), dtype) diff --git a/keras/src/backend/torch/numpy.py b/keras/src/backend/torch/numpy.py index c53a387278d9..feb1ac181dbe 100644 --- a/keras/src/backend/torch/numpy.py +++ b/keras/src/backend/torch/numpy.py @@ -978,7 +978,15 @@ def lcm(x1, x2): def ldexp(x1, x2): x1 = convert_to_tensor(x1) x2 = convert_to_tensor(x2) - return torch.ldexp(x1, x2) + dtype = dtypes.result_type(x1.dtype, x2.dtype, float) + + if standardize_dtype(x2.dtype) not in dtypes.INT_TYPES: + raise TypeError( + f"ldexp exponent must be an integer type. " + f"Received: x2 dtype={x2.dtype}" + ) + + return cast(torch.ldexp(x1, x2), dtype) def less(x1, x2): diff --git a/keras/src/ops/numpy.py b/keras/src/ops/numpy.py index 37c7c54ce535..2231fee3dd4b 100644 --- a/keras/src/ops/numpy.py +++ b/keras/src/ops/numpy.py @@ -4070,7 +4070,7 @@ def compute_output_spec(self, x1, x2): x1_type = backend.standardize_dtype(getattr(x1, "dtype", type(x1))) x2_type = backend.standardize_dtype(getattr(x2, "dtype", type(x2))) - dtype = dtypes.result_type(x1_type, x2_type) + dtype = dtypes.result_type(x1_type, x2_type, float) return KerasTensor(output_shape, dtype=dtype) @@ -4081,19 +4081,12 @@ def ldexp(x1, x2): This function computes: ldexp(x1, x2) = x1 * 2**x2 - Notes: - - TensorFlow does *not* provide a built-in `tf.math.ldexp`. - - The `backend.numpy.ldexp` implementation in TF NumPy is currently - unreliable due to a naming-collision bug and should not be used. - - This implementation provides correct broadcasting, dtype inference, - and gradient support. - Args: - x1: Floating-point input tensor. - x2: Integer or floating-point exponent tensor. + x1: Float input tensor. + x2: Integer exponent tensor. Returns: - Output tensor, element-wise equal to `x1 * 2**x2`. + Output tensor Example: >>> x1 = keras.ops.convert_to_tensor([0.75, 1.5]) diff --git a/keras/src/ops/numpy_test.py b/keras/src/ops/numpy_test.py index 42a8c37b49e3..0bc35c36c9a4 100644 --- a/keras/src/ops/numpy_test.py +++ b/keras/src/ops/numpy_test.py @@ -254,6 +254,11 @@ def test_lcm(self): y = KerasTensor((2, None)) self.assertEqual(knp.lcm(x, y).shape, (2, 3)) + def test_ldexp(self): + x = KerasTensor((None, 3)) + y = KerasTensor((1, 3)) + self.assertEqual(knp.ldexp(x, y).shape, (None, 3)) + def test_less(self): x = KerasTensor((None, 3)) y = KerasTensor((2, None)) @@ -837,6 +842,15 @@ def test_lcm(self): y = KerasTensor((2, 3)) self.assertEqual(knp.lcm(x, y).shape, (2, 3)) + def test_ldexp(self): + x = KerasTensor((2, 3)) + y = KerasTensor((2, 3)) + self.assertEqual(knp.ldexp(x, y).shape, (2, 3)) + + x = KerasTensor((2, 3)) + y = KerasTensor((1, 3)) + self.assertEqual(knp.ldexp(x, y).shape, (2, 3)) + def test_less(self): x = KerasTensor((2, 3)) y = KerasTensor((2, 3)) @@ -3114,6 +3128,12 @@ def test_lcm(self): self.assertAllClose(knp.lcm(x, y), np.lcm(x, y)) self.assertAllClose(knp.Lcm()(x, y), np.lcm(x, y)) + def test_ldexp(self): + x = np.array([[1, 2, 3], [3, 2, 1]]) + y = np.array([[4, 5, 6], [3, 2, 1]]) + self.assertAllClose(knp.ldexp(x, y), np.ldexp(x, y)) + self.assertAllClose(knp.Ldexp()(x, y), np.ldexp(x, y)) + def test_less(self): x = np.array([[1, 2, 3], [3, 2, 1]]) y = np.array([[4, 5, 6], [3, 2, 1]]) @@ -7884,6 +7904,27 @@ def test_lcm(self, dtypes): expected_dtype, ) + @parameterized.named_parameters( + named_product(dtypes=list(itertools.product(ALL_DTYPES, INT_DTYPES))) + ) + def test_ldexp(self, dtypes): + import jax.numpy as jnp + + dtype1, dtype2 = dtypes + x1 = knp.ones((), dtype=dtype1) + x2 = knp.ones((), dtype=dtype2) + x1_jax = jnp.ones((), dtype=dtype1) + x2_jax = jnp.ones((), dtype=dtype2) + expected_dtype = standardize_dtype(jnp.ldexp(x1_jax, x2_jax).dtype) + + self.assertEqual( + standardize_dtype(knp.ldexp(x1, x2).dtype), expected_dtype + ) + self.assertEqual( + standardize_dtype(knp.Ldexp().symbolic_call(x1, x2).dtype), + expected_dtype, + ) + @parameterized.named_parameters( named_product(dtypes=itertools.combinations(ALL_DTYPES, 2)) ) From 8b0c56138cf95ea9e4db9714e39361606ea9a174 Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Thu, 20 Nov 2025 21:40:54 +0900 Subject: [PATCH 3/6] Update code by gemini reveiw --- keras/src/backend/numpy/numpy.py | 2 -- keras/src/backend/tensorflow/numpy.py | 9 ++++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/keras/src/backend/numpy/numpy.py b/keras/src/backend/numpy/numpy.py index 1525743fed1b..094628c51817 100644 --- a/keras/src/backend/numpy/numpy.py +++ b/keras/src/backend/numpy/numpy.py @@ -784,8 +784,6 @@ def ldexp(x1, x2): f"Received: x2 dtype={x2.dtype}" ) - x1 = np.asarray(x1).astype(np.float32) - x2 = np.asarray(x2).astype(np.int32) return np.ldexp(x1, x2).astype(dtype) diff --git a/keras/src/backend/tensorflow/numpy.py b/keras/src/backend/tensorflow/numpy.py index d166b3b30f03..67019c603afc 100644 --- a/keras/src/backend/tensorflow/numpy.py +++ b/keras/src/backend/tensorflow/numpy.py @@ -1855,9 +1855,12 @@ def ldexp(x1, x2): f"Received: x2 dtype={x2.dtype}" ) - x1 = tf.cast(x1, tf.float32) - x2 = tf.cast(x2, tf.float32) - return tf.cast(x1 * tf.pow(2.0, x2), dtype) + x1 = tf.cast(x1, dtypes.result_type(x1.dtype, float)) + + x1 = tf.cast(x1, tf.float32 if not x1.dtype.is_floating else x1.dtype) + x2 = tf.cast(x2, x1.dtype) + result = x1 * tf.pow(tf.constant(2.0, dtype=x1.dtype), x2) + return tf.cast(tf.where(tf.math.is_inf(x1) | (x1 == 0), x1, result), dtype) def less(x1, x2): From 65a5423b18fa9f30c2b3329a978f4f3cd23d0a9a Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Wed, 26 Nov 2025 15:16:29 +0900 Subject: [PATCH 4/6] Update code by review --- keras/src/backend/tensorflow/numpy.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/keras/src/backend/tensorflow/numpy.py b/keras/src/backend/tensorflow/numpy.py index 67019c603afc..4691a80e6140 100644 --- a/keras/src/backend/tensorflow/numpy.py +++ b/keras/src/backend/tensorflow/numpy.py @@ -1855,12 +1855,10 @@ def ldexp(x1, x2): f"Received: x2 dtype={x2.dtype}" ) - x1 = tf.cast(x1, dtypes.result_type(x1.dtype, float)) - - x1 = tf.cast(x1, tf.float32 if not x1.dtype.is_floating else x1.dtype) + x1 = tf.cast(x1, dtype) x2 = tf.cast(x2, x1.dtype) result = x1 * tf.pow(tf.constant(2.0, dtype=x1.dtype), x2) - return tf.cast(tf.where(tf.math.is_inf(x1) | (x1 == 0), x1, result), dtype) + return tf.where(tf.math.is_inf(x1) | (x1 == 0), x1, result) def less(x1, x2): From 7eee64c26073382e96f6a0a159fb7339246534f0 Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Wed, 26 Nov 2025 15:58:51 +0900 Subject: [PATCH 5/6] Add cast for tensorflow return value --- keras/src/backend/tensorflow/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/tensorflow/numpy.py b/keras/src/backend/tensorflow/numpy.py index 4691a80e6140..c35be3d35bc8 100644 --- a/keras/src/backend/tensorflow/numpy.py +++ b/keras/src/backend/tensorflow/numpy.py @@ -1858,7 +1858,7 @@ def ldexp(x1, x2): x1 = tf.cast(x1, dtype) x2 = tf.cast(x2, x1.dtype) result = x1 * tf.pow(tf.constant(2.0, dtype=x1.dtype), x2) - return tf.where(tf.math.is_inf(x1) | (x1 == 0), x1, result) + return tf.cast(tf.where(tf.math.is_inf(x1) | (x1 == 0), x1, result), dtype) def less(x1, x2): From e2d5218b452f2308ba8da0e2f877f8325bb10ab1 Mon Sep 17 00:00:00 2001 From: ugeunpark Date: Fri, 28 Nov 2025 19:12:49 +0900 Subject: [PATCH 6/6] merge master --- keras/src/backend/numpy/numpy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/keras/src/backend/numpy/numpy.py b/keras/src/backend/numpy/numpy.py index 094628c51817..cdff50137588 100644 --- a/keras/src/backend/numpy/numpy.py +++ b/keras/src/backend/numpy/numpy.py @@ -783,7 +783,6 @@ def ldexp(x1, x2): f"ldexp exponent must be an integer type. " f"Received: x2 dtype={x2.dtype}" ) - return np.ldexp(x1, x2).astype(dtype)