-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added erf op to math.py #908
Changes from 7 commits
6485433
61c9690
7960106
d9f99f2
ef05f70
8d4b8eb
e829832
686f339
6b52b8a
7f76459
5efabf5
ebe06c3
3f199c3
0307b74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -248,3 +248,7 @@ def istft( | |
|
||
def rsqrt(x): | ||
return jax.lax.rsqrt(x) | ||
|
||
|
||
def erf(x): | ||
return jnp.erf(x) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -302,3 +302,7 @@ def istft( | |
|
||
def rsqrt(x): | ||
return 1.0 / np.sqrt(x) | ||
|
||
|
||
def erf(x): | ||
return scipy.special.erf(x) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -239,3 +239,7 @@ def istft( | |
|
||
def rsqrt(x): | ||
return tf.math.rsqrt(x) | ||
|
||
|
||
def erf(x): | ||
return tf.math.erf(x) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -929,3 +929,37 @@ def rsqrt(x): | |
return Rsqrt().symbolic_call(x) | ||
x = backend.convert_to_tensor(x) | ||
return backend.math.rsqrt(x) | ||
|
||
|
||
class Erf(Operation): | ||
def compute_output_spec(self, x): | ||
return KerasTensor(shape=x.shape, dtype=x.dtype) | ||
|
||
def call(self, x): | ||
return backend.erf(x) | ||
|
||
|
||
@keras_core_export("keras_core.ops.erf") | ||
def erf(x): | ||
"""Computes the error function of x element-wise. | ||
|
||
Args: | ||
x: input tensor | ||
|
||
Returns: | ||
A tensor with the same type as `x`. | ||
|
||
Examples: | ||
|
||
# Basic usage | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you're not printing any outputs, just use a fenced code block for the code example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
>>> x = np.array([-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0]) | ||
>>> y = Erf()(x) | ||
# Using `float32` data type | ||
>>> x_float32 = np.array([-3.0, -2.0], dtype=np.float32) | ||
>>> y_float32 = Erf()(x_float32) | ||
# Using large values | ||
>>> x_large = np.array([1e10, -1e10]) | ||
>>> y_large = Erf()(x_large) | ||
""" | ||
|
||
return Erf()(x) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -835,3 +835,41 @@ def test_rsqrt(self): | |
x = np.array([[1, 4, 9], [16, 25, 36]], dtype="float32") | ||
self.assertAllClose(kmath.rsqrt(x), 1 / np.sqrt(x)) | ||
self.assertAllClose(kmath.Rsqrt()(x), 1 / np.sqrt(x)) | ||
|
||
def test_erf_operation_basic(self): | ||
# Sample values for testing | ||
sample_values = np.array([-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0]) | ||
|
||
# Expected output using numpy's approximation of the error function | ||
expected_output = (2 / np.sqrt(np.pi)) * np.vectorize(math.erf)( | ||
sample_values | ||
) | ||
|
||
# Output from the erf operation in keras_core | ||
output_from_erf_op = kmath.erf(sample_values).numpy() | ||
|
||
# Assert that the outputs are close | ||
self.assertAllClose(expected_output, output_from_erf_op, atol=1e-5) | ||
|
||
def test_erf_operation_dtype(self): | ||
# Test for float32 and float64 data types | ||
for dtype in ("float32", "float64"): | ||
sample_values = np.array( | ||
[-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0], dtype=dtype | ||
) | ||
expected_output = (2 / np.sqrt(np.pi)) * np.vectorize(math.erf)( | ||
sample_values | ||
) | ||
output_from_erf_op = kmath.erf(sample_values).numpy() | ||
self.assertAllClose(expected_output, output_from_erf_op, atol=1e-5) | ||
|
||
def test_erf_operation_edge_cases(self): | ||
# Test for edge cases | ||
edge_values = np.array([1e10, -1e10, 1e-10, -1e-10], dtype=np.float64) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your test values are too large. Try 1e5. This the source of the large discrepancy IMO. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have implemented the changes, but I can see from the tests that it is failing for the below array examples. I wonder if there is anything wrong in the implementation function itself.
|
||
expected_edge_output = (2 / np.sqrt(np.pi)) * np.vectorize(math.erf)( | ||
edge_values | ||
) | ||
output_from_edge_erf_op = kmath.erf(edge_values).numpy() | ||
self.assertAllClose( | ||
expected_edge_output, output_from_edge_erf_op, atol=1e-5 | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to call
backend.math
. Tests are failing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implemented it