My favorites | Sign in
Project Logo
                
New issue | Search
for
| Advanced search | Search tips
Issue 77: prettier printing of intervals
1 person starred this issue and may be notified of changes. Back to list
Status:  Started
Owner:  Vinzent.Steinberg
Type-Enhancement
Priority-Medium


Sign in to add a comment
 
Reported by Vinzent.Steinberg, Oct 05, 2008
Compare

[5.2582327113062393041, 5.2582327113062749951]

to

5.2582327113062[393041,749951]

It would be especially useful for matrices.
Comment 1 by fredrik.johansson, Oct 05, 2008
Agreed.
Comment 2 by fredrik.johansson, Oct 05, 2008
Also nstr should work for intervals, and matrices containing intervals.
Comment 3 by fredrik.johansson, Oct 05, 2008
To implement this properly, the code in to_str needs to be made more modular. This is
related to issue 69.

I'm not personally interested in working on this right now.
Comment 4 by Vinzent.Steinberg, Oct 05, 2008
Yeah, that's not too interesting. :)

It would be nice to also have 

mpi.mid +- (mpi.a - mpi.mid)

printed optionally.
Labels: -Type-Defect Type-Enhancement
Comment 5 by Vinzent.Steinberg, Feb 05, 2009
I think we should port the nice number formatting from hcpy. Things like

1.234 +- 0.3
1.234 +- 2.5%
2143124214214124124...24124124
etc.

would be nice for mpmath. It should be trivial to port it. I'll give it a try in a
week or something, when I'll have time.
Comment 6 by Vinzent.Steinberg, Feb 14, 2009
I took the parsing and printing from hcpy. someonesdad1, how do you want to be
credited? Do you want a copyright notice inside the file (not usual in mpmath as of
now) or is it sufficient to mention you in the list of contributors? Thank you a lot
for sharing your code!

Fredrik, which formatting options for floating point numbers should be ported in your
opinion? hcpy has the following:

from mpformat import *
from mpmath import *

mp.dps = 30
fp = mpFormat()
mpFormat.comma_decorate = True
x = mpf("12345.67890123456789")
fp.digits(10)
print fp.fix(x)
print fp.sig(x)
print fp.sci(x)
print fp.eng(x)
print fp.engsi(x)
mpFormat.cuddle_si = True
print fp.engsi(x)

Output:

12,345.67890 12346
12,345.67890
1.234567890e+4
12.34567890e+3
12.34567890 k
12.34567890k
mpistr.py
2.8 KB   Download
Comment 7 by Vinzent.Steinberg, Feb 14, 2009
Implemented 5.2582327113062[393041,749951], some doctests.

mpistr.py
3.6 KB   Download
Comment 8 by fredrik.johansson, Feb 14, 2009
To be honest, I don't think those mpf printing formats are particularly useful for
mpmath. Something that could be useful is a condensed format for mpf, e.g. 
"3.14159265358979323[ 966 digits ]1195909216420198"

The interval printing and parsing is nice, though. A problem (looks like it doesn't
include enough digits):

>>> mp.dps = 30
>>> print_mpi(cos(mpi(1)), mode='diff')
0.54030230586813971740093660744[3, 3]

Also both these are weird. I think exponent should be shown after [] unless the
exponents differ:

>>> print_mpi(exp(mpi(50000)), mode='diff')
5.29779516443031532513576499866e+2171[4, 4]
>>> print_mpi(exp(mpi('50000.1')), mode='diff')
5.8549691456501781558378663[1396e+21714, 518e+21714]
Comment 9 by Vinzent.Steinberg, Feb 14, 2009
My fault, the implementation is quite trivial. It just looks where the first
difference occurs. If this doesn't happen, we get [3, 3] and similar things. The
comparison should just cancel when a 'e' occurs (and the exponents are identical).

Are you sure about thinks like

>>> print_mpi(mpi(1e123, 1e129))
1.0e12[3, 9]

?

I think it is not necessary for exponents.


Which mpf printing formats (that are not yet available) are desirable in your opinion?
Comment 10 by fredrik.johansson, Feb 14, 2009
If the exponents differ, it is misleading to display any mantissa digits as shared.
So that should really fall back to [1.0e123, 1.0e129].

> Which mpf printing formats (that are not yet available) are desirable in your opinion?

My list in issue 69 mostly covers what I think is desirable.
Comment 11 by Vinzent.Steinberg, Feb 15, 2009
I fixed it.

>>> print_mpi(cos(mpi(1)), mode='diff')
0.540302305868139717400936607443[] # should there be a ','?
>>> print_mpi(exp(mpi('50000.1')), mode='diff')
5.8549691456501781558378663[1396, 518]e+21714]


mpistr.py
4.2 KB   Download
Comment 12 by fredrik.johansson, Feb 15, 2009
> 0.540302305868139717400936607443[]

This could still be improved. For nonempty intervals, enough digits could be added to
show the difference.

Comment 13 by Vinzent.Steinberg, Feb 15, 2009
How to do this?

I'm just using str(cos(mpi(1))).
Status: Started
Comment 14 by fredrik.johansson, Feb 16, 2009
You could use to_str directly and ask for repr_dps(mp.prec) digits.
Comment 15 by Vinzent.Steinberg, Feb 17, 2009
Thanks. If the string representations are equal, it now falls back to using to_str
directly.

Do you think we need parsing for 5.2582327113062[393041, 749951] etc.?
mpistr.py
4.6 KB   Download
Comment 16 by fredrik.johansson, Feb 17, 2009
A nice application: primepi2 (just implemented):

>>> primepi(3141592)
226277
>>> print_mpi(primepi2(3141592), mode='percent')
226449.5 (0.466108337620529%)
>>> print_mpi(primepi2(3141592), mode='plusminus')
226449.5 +- 1055.5

I say limiting the percentage value to 2-4 digits should be posible at least as an
option.

> Do you think we need parsing for 5.2582327113062[393041, 749951] etc.?

Supporting it in the mpi() constructor at least wouldn't hurt anybody.
Comment 17 by Vinzent.Steinberg, Feb 17, 2009
I implemented parsing for mode='diff' and added some tests. (I'll upload the code later.)

parse_mpi() will be called from mpmathify(). mpi_to_str() will be added to libmpi.py.
Should it by called from nstr()? Any objections?

What about renaming to_str() to mpf_to_str()? (Like mpc_to_str().)
Comment 18 by fredrik.johansson, Feb 18, 2009
> Should it by called from nstr()? Any objections?

I think nstr and nprint should provide all pretty-printing options. An mpi method
could also be useful.

> What about renaming to_str() to mpf_to_str()? (Like mpc_to_str().)

Yes, to_int, from_int, etc could also all be renamed for consistency.
Comment 19 by Vinzent.Steinberg, Feb 22, 2009
It doesn't seem possible to have mpi_to_str() and mpi_from_str() in libmpi.py,
because they rely on mpf() and mpi(), which I can't import from there. Moving it to
mptypes.py does not feel right. Which solution would you propose?

(The code is ready to be committed, apart from this.)
Comment 21 by fredrik.johansson, Feb 22, 2009
I suggest putting it in mptypes.py for now, but the better solution would be to
rewrite the code in low-level mpmath (which would make it a bit faster, although this
code is surely not a speed-critical).

For significance arithmetic, how about an option not to show just as many digits as
necessary to specify the magnitude of the error? To take a recent example from the
sympy list, with x = sin(mpi(0.5-0.005, 0.5+0.005)), instead of

   0.479419545797455 +- 0.0043878945265047

one would get something like (independent of working precision):

   0.4794 +- 0.0044
Comment 22 by Vinzent.Steinberg, Feb 23, 2009
I just implemented and committed mpi support for mpmathify() and nstr().

This is certainly worth adding, what about just using a custom dps like for
mode='percent'? We could rename the keyword percent_dps to error_dps and use it for
both modes.
Comment 23 by fredrik.johansson, Feb 23, 2009
Something along the following lines could be used to automatically determine the
digits to display:

value_dps = -int(ceil(log(x.delta,10)))+2
error_dps = 2

Also, to_str should perhaps be more clever about when to use fixed point if dps is
small. For example,

>>> nstr(mpf(4.38789e-3), 6)
'4.38789e-3'

0.00438789 would be more readable.
Comment 24 by Vinzent.Steinberg, Feb 23, 2009
I implemented error_dps as proposed. However:

>>> nprint(mpi(1,2), mode='plusminus')
1.5 +- 5.0e-1
>>> nprint(mpi(1,2), mode='plusminus', error_dps=4)
1.5 +- 5.0e-1
>>> nprint(mpi(1,2), mode='plusminus', error_dps=5)
1.5 +- 5.0e-1
>>> nprint(mpi(1,2), mode='plusminus', error_dps=6)
1.5 +- 0.5
>>> nprint(mpf('5e-1'), 4)
5.0e-1
>>> nprint(mpf('5e-1'), 6)
0.5

This is annoying. Do you know what could cause this behaviour?
Comment 25 by Vinzent.Steinberg, Feb 23, 2009
> Also, to_str should perhaps be more clever about when to use fixed point if dps is
> small.

Sorry, I missed that. I agree completely, my example is even more extreme.

+1 for a to_str() more clever about small values.
Comment 26 by Vinzent.Steinberg, Feb 23, 2009
There should be a parameter indicating the maximal allowed number of zeros after the
point. Something like

if abs(x) < 10**-max_zeros:
    use_floating_point()
else:
    use_fixed_point()
Comment 27 by Vinzent.Steinberg, Mar 11, 2009
I think min_fixed and max_fixed in to_str() should be replaced by max_zeros as
proposed. What do you think?

If you have no objections, I'll implement it this way.
Comment 28 by fredrik.johansson, Mar 12, 2009
How would you replace both min_fixed and max_fixed? It is useful that fac(200) (for
example) prints as an integer when the precision is large enough.

If you do make any changes to to_str, please post a patch for review here before
committing.
Comment 29 by Vinzent.Steinberg, Mar 12, 2009
What is the behavior you want?

I think the only thing that needs fixing is 5.0e-1 etc. So instead of replacing
min_fixed and max_fixed (I see that it is necessary for integers) there should be
additionally max_zeros having a higher priority. In my opinion to_str() should just
prefer 0.001 over 1.0e-3.

Sign in to add a comment

Hosted by Google Code