Precision of variables saved using O.save

Asked by ipemath

Do we have any control on the precision of the variables saved using the O.save() function? Is it by default saved using the maximum possible precision??

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
Last query:
Last reply:
Revision history for this message
Jérôme Duriez (jduriez) said :
#1

Hi,

Type of saved variables obey to what is coded in YADE_CLASS_BASE_DOC_ATTRS_CTOR_..() block in hpp files. E.g. the radius of a sphere is a "Real" (= double ? you should check yourself to what typedef this "Real" corresponds to in Yade) according to https://github.com/yade/trunk/blob/master/pkg/common/Sphere.hpp#L13

But, I do not know if this answers actually to your question..

Jerome

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#2

Hi,
Precision depends on which format you save to. If you save in binary (filename.yade) it will have the maximum precision.
If you save in xml there is a conversion to string, and in that case I'm not sure what happens. You could check that in boost::serialization.
I hope it helps.
Bruno

Revision history for this message
Jan Stránský (honzik) said :
#3

Hello,

you can also easily try it yourself:

import random; r=random.random
O.bodies.append(sphere((r(),r(),r()),1))
base = '/tmp/a.'
for ext in 'yade','xml':
print O.bodies[0].state.pos[0]
O.save(base+ext)
O.reset()
O.load(base+ext)
print O.bodies[0].state.pos[0]

my output:
0.872136848902
0.872136848902
0.872136848902
0.872136848902

it means that in both .yade and .xml format, the numbers (double precision
numbers) are saved in maximum possible precision. Do you have any problems
with O.save/O.load?

cheers
Jan

2015-01-21 9:41 GMT+01:00 Bruno Chareyre <
<email address hidden>>:

> Question #260626 on Yade changed:
> https://answers.launchpad.net/yade/+question/260626
>
> Bruno Chareyre proposed the following answer:
> Hi,
> Precision depends on which format you save to. If you save in binary
> (filename.yade) it will have the maximum precision.
> If you save in xml there is a conversion to string, and in that case I'm
> not sure what happens. You could check that in boost::serialization.
> I hope it helps.
> Bruno
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#4

@Jan
The fact that two floats are converted to the same string with "print" does not imply that they are equal. Before printing a number, python is rounding and truncating.

Real number representation is still a mystery to me, I know just enough to know that it is never as simple as one expects.
For instance, this is not a bug:
>>> x=0.1; y=0.2
>>> x+y
0.30000000000000004
>>> print x+y
0.3

This being said, your conclusion may be right (I'm still not 100% sure) even though the proof was flawn, since a variant of your script with "all" digits displayed gives this:
0.2017354310946590789654919717577286064624786376953125
0.2017354310946590789654919717577286064624786376953125
0.2017354310946590789654919717577286064624786376953125
0.2017354310946590789654919717577286064624786376953125
___
import random; r=random.random
from decimal import Decimal #see https://docs.python.org/2/tutorial/floatingpoint.html
O.bodies.append(sphere((r(),r(),r()),1))
base = '/tmp/a.'
for ext in 'yade','xml':
 print Decimal(O.bodies[0].state.pos[0])
 O.save(base+ext)
 O.reset()
 O.load(base+ext)
 print Decimal(O.bodies[0].state.pos[0])

Revision history for this message
Best Jan Stránský (honzik) said :
#5

>
>
> @Jan

The fact that two floats are converted to the same string with "print" does
> not imply that they are equal. Before printing a number, python is rounding
> and truncating.
>

sorry, you are right, [1] shows that decimal representation is indeed
rounded..

> Real number representation is still a mystery to me, I know just enough to
> know that it is never as simple as one expects.
> For instance, this is not a bug:
> >>> x=0.1; y=0.2
> >>> x+y
> 0.30000000000000004
> >>> print x+y
> 0.3
>

see Vaclav's thesis, section 2.7.2 or [1]

>
> This being said, your conclusion may be right (I'm still not 100% sure)
> even though the proof was flawn, since a variant of your script with "all"
> digits displayed gives this:
> 0.2017354310946590789654919717577286064624786376953125
> 0.2017354310946590789654919717577286064624786376953125
> 0.2017354310946590789654919717577286064624786376953125
> 0.2017354310946590789654919717577286064624786376953125
>

see [1] (again :-)

> ___
> import random; r=random.random
> from decimal import Decimal #see
> https://docs.python.org/2/tutorial/floatingpoint.html
> O.bodies.append(sphere((r(),r(),r()),1))
> base = '/tmp/a.'
> for ext in 'yade','xml':
> print Decimal(O.bodies[0].state.pos[0])
> O.save(base+ext)
> O.reset()
> O.load(base+ext)
> print Decimal(O.bodies[0].state.pos[0])
>
>
Another (and it seems to me that really proving) alternative is to use
Python float.hex() function [2], that prints what is really in the memory:

...
print O.bodies[0].state.pos[0].hex()

cheers
Jan

>
[1] https://docs.python.org/2/tutorial/floatingpoint.html
[2] https://docs.python.org/2/library/stdtypes.html#float.hex

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#6

See the hyperlink in #4
;-)

Revision history for this message
ipemath (ipemathew1984) said :
#7

Thanks Jan Stránský, that solved my question.