Skip to content
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

Consider leveraging the numpy printing mechanism #356

Open
eric-wieser opened this issue Sep 11, 2020 · 4 comments
Open

Consider leveraging the numpy printing mechanism #356

eric-wieser opened this issue Sep 11, 2020 · 4 comments

Comments

@eric-wieser
Copy link
Member

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__
@eric-wieser
Copy link
Member Author

eric-wieser commented Sep 11, 2020

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.

@hugohadfield
Copy link
Member

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?

@eric-wieser
Copy link
Member Author

eric-wieser commented Sep 11, 2020

Probably not, good point - though coeff < 0 isn't particularly sensible either.

@eric-wieser
Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants