Skip to content

Commit 2b8ddf3

Browse files
authored
Implement trapezoid function in keras.ops (#21757)
* Add trapezoid for numpy * Add trapezoid for ops * Add test cases for initial version * Add more test cases * Update openvino side for trapezoid * Code update by gemini
1 parent 61ac8c1 commit 2b8ddf3

File tree

12 files changed

+159
-0
lines changed

12 files changed

+159
-0
lines changed

keras/api/_tf_keras/keras/ops/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@
286286
from keras.src.ops.numpy import tile as tile
287287
from keras.src.ops.numpy import trace as trace
288288
from keras.src.ops.numpy import transpose as transpose
289+
from keras.src.ops.numpy import trapezoid as trapezoid
289290
from keras.src.ops.numpy import tri as tri
290291
from keras.src.ops.numpy import tril as tril
291292
from keras.src.ops.numpy import triu as triu

keras/api/_tf_keras/keras/ops/numpy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
from keras.src.ops.numpy import tile as tile
173173
from keras.src.ops.numpy import trace as trace
174174
from keras.src.ops.numpy import transpose as transpose
175+
from keras.src.ops.numpy import trapezoid as trapezoid
175176
from keras.src.ops.numpy import tri as tri
176177
from keras.src.ops.numpy import tril as tril
177178
from keras.src.ops.numpy import triu as triu

keras/api/ops/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@
286286
from keras.src.ops.numpy import tile as tile
287287
from keras.src.ops.numpy import trace as trace
288288
from keras.src.ops.numpy import transpose as transpose
289+
from keras.src.ops.numpy import trapezoid as trapezoid
289290
from keras.src.ops.numpy import tri as tri
290291
from keras.src.ops.numpy import tril as tril
291292
from keras.src.ops.numpy import triu as triu

keras/api/ops/numpy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
from keras.src.ops.numpy import tile as tile
173173
from keras.src.ops.numpy import trace as trace
174174
from keras.src.ops.numpy import transpose as transpose
175+
from keras.src.ops.numpy import trapezoid as trapezoid
175176
from keras.src.ops.numpy import tri as tri
176177
from keras.src.ops.numpy import tril as tril
177178
from keras.src.ops.numpy import triu as triu

keras/src/backend/jax/numpy.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,14 @@ def transpose(x, axes=None):
13611361
return jnp.transpose(x, axes=axes)
13621362

13631363

1364+
def trapezoid(y, x=None, dx=1.0, axis=-1):
1365+
y = convert_to_tensor(y)
1366+
if x is not None:
1367+
x = convert_to_tensor(x)
1368+
dx = convert_to_tensor(dx)
1369+
return jnp.trapezoid(y, x, dx=dx, axis=axis)
1370+
1371+
13641372
def var(x, axis=None, keepdims=False):
13651373
x = convert_to_tensor(x)
13661374
# `jnp.var` does not handle low precision (e.g., float16) overflow

keras/src/backend/numpy/numpy.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,15 @@ def transpose(x, axes=None):
13361336
return np.transpose(x, axes=axes)
13371337

13381338

1339+
def trapezoid(y, x=None, dx=1.0, axis=-1):
1340+
y = convert_to_tensor(y)
1341+
result_dtype = dtypes.result_type(y.dtype, float)
1342+
if x is not None:
1343+
x = convert_to_tensor(x)
1344+
dx = convert_to_tensor(dx)
1345+
return np.trapezoid(y, x, dx=dx, axis=axis).astype(result_dtype)
1346+
1347+
13391348
def var(x, axis=None, keepdims=False):
13401349
axis = standardize_axis_for_numpy(axis)
13411350
x = convert_to_tensor(x)

keras/src/backend/openvino/excluded_concrete_tests.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ NumpyDtypeTest::test_swapaxes
4646
NumpyDtypeTest::test_tensordot_
4747
NumpyDtypeTest::test_tile
4848
NumpyDtypeTest::test_trace
49+
NumpyDtypeTest::test_trapezoid
4950
NumpyDtypeTest::test_trunc
5051
NumpyDtypeTest::test_unravel
5152
NumpyDtypeTest::test_var
@@ -95,6 +96,7 @@ NumpyOneInputOpsCorrectnessTest::test_swapaxes
9596
NumpyOneInputOpsCorrectnessTest::test_tile
9697
NumpyOneInputOpsCorrectnessTest::test_trace
9798
NumpyOneInputOpsCorrectnessTest::test_transpose
99+
NumpyOneInputOpsCorrectnessTest::test_trapezoid
98100
NumpyOneInputOpsCorrectnessTest::test_trunc
99101
NumpyOneInputOpsCorrectnessTest::test_unravel_index
100102
NumpyOneInputOpsCorrectnessTest::test_var

keras/src/backend/openvino/numpy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,12 @@ def transpose(x, axes=None):
23982398
return OpenVINOKerasTensor(ov_opset.transpose(x, axes).output(0))
23992399

24002400

2401+
def trapezoid(y, x=None, dx=1.0, axis=-1):
2402+
raise NotImplementedError(
2403+
"`trapezoid` is not supported with openvino backend"
2404+
)
2405+
2406+
24012407
def var(x, axis=None, keepdims=False):
24022408
x = get_ov_output(x)
24032409
if axis is None:

keras/src/backend/tensorflow/numpy.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,6 +2984,42 @@ def transpose(x, axes=None):
29842984
return tf.transpose(x, perm=axes)
29852985

29862986

2987+
def trapezoid(y, x=None, dx=1.0, axis=-1):
2988+
def _move_axis_to_last(tensor, axis):
2989+
if axis == -1:
2990+
return tensor
2991+
rank = tf.rank(tensor)
2992+
if axis < 0:
2993+
axis = rank + axis
2994+
perm = tf.concat(
2995+
[
2996+
tf.range(axis, dtype=tf.int32),
2997+
tf.range(axis + 1, rank, dtype=tf.int32),
2998+
tf.constant([axis], dtype=tf.int32),
2999+
],
3000+
axis=0,
3001+
)
3002+
return tf.transpose(tensor, perm=perm)
3003+
3004+
y = convert_to_tensor(y)
3005+
dtype = dtypes.result_type(y.dtype, float)
3006+
y = tf.cast(y, dtype)
3007+
3008+
if x is None:
3009+
dx_array = tf.cast(dx, dtype)
3010+
else:
3011+
x = convert_to_tensor(x, dtype=dtype)
3012+
dx_array = diff(x, axis=axis)
3013+
dx_array = _move_axis_to_last(dx_array, axis)
3014+
3015+
y = _move_axis_to_last(y, axis)
3016+
3017+
avg_heights = 0.5 * (y[..., 1:] + y[..., :-1])
3018+
result = tf.reduce_sum(avg_heights * dx_array, axis=-1)
3019+
3020+
return result
3021+
3022+
29873023
def var(x, axis=None, keepdims=False):
29883024
x = convert_to_tensor(x)
29893025
compute_dtype = dtypes.result_type(x.dtype, "float32")

keras/src/backend/torch/numpy.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,18 @@ def transpose(x, axes=None):
17891789
return x.T
17901790

17911791

1792+
def trapezoid(y, x=None, dx=1.0, axis=-1):
1793+
y = convert_to_tensor(y)
1794+
if standardize_dtype(y.dtype) == "bool":
1795+
y = cast(y, config.floatx())
1796+
if x is not None:
1797+
x = convert_to_tensor(x)
1798+
return torch.trapz(y, x=x, dim=axis)
1799+
else:
1800+
dx = convert_to_tensor(dx)
1801+
return torch.trapz(y, dx=dx, dim=axis)
1802+
1803+
17921804
def var(x, axis=None, keepdims=False):
17931805
x = convert_to_tensor(x)
17941806
compute_dtype = dtypes.result_type(x.dtype, "float32")

0 commit comments

Comments
 (0)