clifford
clifford copied to clipboard
Consider leveraging the numpy printing mechanism
We could consider using numpy to round coefficients etc with:
f = np.core.arrayprint._get_format_function(self.value, **np.core.arrayprint._format_options)
# use `f` instead of `round` in `MultiVector.__str__
Trying this out:
# copied from MultiVector.__str__, with the above change
def new_str(self) -> str:
s = ''
# abs because we handle the minus signs
fmt = np.core.arrayprint._get_format_function(abs(self.value), **np.core.arrayprint._format_options)
for grade, name, coeff in zip(self.layout._basis_blade_order.grades, self.layout.names, self.value):
# if we have nothing yet, don't use + and - as operators but
# use - as an unary prefix if necessary
if s:
seps = (' + ', ' - ')
else:
seps = ('', '-')
# note: these comparisons need to ensure nan is shown, noting that
# `nan {} x` is always false for all comparisons `{}`.`
if abs(coeff) < clifford._settings._eps:
continue # too small to print
else:
if coeff < 0:
sep = seps[1]
coeff_str = fmt(-coeff)
else:
sep = seps[0]
coeff_str = fmt(coeff)
if grade == 0:
# scalar
s = '%s%s%s' % (s, sep, coeff_str)
else:
# not a scalar
s = '%s%s(%s^%s)' % (s, sep, coeff_str, name)
if s:
# non-zero
return s
else:
# return scalar 0
return '0'
gives
In [26]: x = 1 + 1.234 * e1 - 1.1 * e12
In [27]: x
Out[27]: 1.0 + (1.234^e1) - (1.1^e12)
In [28]: new_str(x)
Out[28]: '1. + (1.234^e1) - (1.1 ^e12)'
Note numpy is trying to make all the coefficients the same width, which may or may not be something we care about.
With the abs in fmt = np.core.arrayprint._get_format_function(abs(self.value), **np.core.arrayprint._format_options)
, will this give the correct behaviour for complex .value
?
Probably not, good point - though coeff < 0
isn't particularly sensible either.
Alternative, we could create a subclass of numpy.polynomial.ABCPolyBase
and implement _str_term_ascii
(and _repr_latex_term
) to emit the basis blade names, which would give us the repr for free.