Skip to content

Commit

Permalink
norm now uses metric.square_root_of_expr again, with fixes
Browse files Browse the repository at this point in the history
1. It now accepts a hint that the expr is nonnegative etc, avoiding unnecessary `abs` calls
2. It had a bug that incorrectly assumed that the sqrt of even product is the product of powers divided by 2 is nonnegative, thus lacking an `abs` call.

Passing previously failing tests locally without modifying any notebooks:

```
pytest test/test_mv.py -vv
pytest --nbval examples/ipython/test_gsg_undual_etc.ipynb --nbval-current-env --nbval-sanitize-with test/.nbval_sanitize.cfg -vv
```
  • Loading branch information
utensil committed Apr 12, 2024
1 parent caa4cf8 commit 530fe58
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
26 changes: 18 additions & 8 deletions galgebra/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,17 @@ def collect(A, nc_list):
return C


def square_root_of_expr(expr):
def square_root_of_expr(expr, hint='0'):
"""
If expression is product of even powers then every power is divided
by two and the product is returned. If some terms in product are
not even powers the sqrt of the absolute value of the expression is
returned. If the expression is a number the sqrt of the absolute
value of the number is returned.
If expression is product of even powers then every power is divided by two
and the absolute value of product is returned.
If some terms in product are not even powers the sqrt of the absolute value of
the expression is returned.
If the expression is a number the sqrt of the absolute value of the number is returned.
String values '+', '-', or '0' of hint respectively determine
whether expr should be regarded as nonnegative, nonpositive,
or of unknown sign.
"""
if expr.is_number:
if expr > 0:
Expand All @@ -137,11 +141,17 @@ def square_root_of_expr(expr):
coef = sqrt(abs(coef)) # Product coefficient not a number
for p in pow_lst:
f, n = p
# Product not all even powers
if n % 2 != 0:
return sqrt(abs(expr)) # Product not all even powers
if hint == '+':
return sqrt(expr)
elif hint == '-':
return sqrt(-expr)
else:
return sqrt(abs(expr))
else:
coef *= f ** (n / S(2)) # Positive sqrt of the square of an expression
return coef
return abs(coef)


def symbols_list(s, indices=None, sub=True, commutative=False):
Expand Down
2 changes: 1 addition & 1 deletion galgebra/mv.py
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ def norm(self, hint='0') -> Expr:
sign, except when the quadratic form's sign can be determined
by other considerations, such as the metric being Euclidean.
"""
return simplify(sqrt(self.norm2(hint)))
return simplify(metric.square_root_of_expr(self.norm2(hint), hint='+'))
# ## GSG code ends ###

__abs__ = norm # allow `abs(x)` to call z.norm()
Expand Down

0 comments on commit 530fe58

Please sign in to comment.