sympy: what's wrong with this picture?

N

Nanjundi

Notice anything funny about the "random" choices?

import sympy
import time
import random

f = [i for i in sympy.primerange(1000,10000)]

for i in xrange(10):
f1 = random.choice(f)
print f1,
f2 = random.choice(f)
print f2,
C = f1*f2
ff = None
ff = sympy.factorint(C)
print ff

## 7307 7243 [(7243, 1), (7307, 1)]
## 4091 6829 [(4091, 1), (6829, 1)]
## 8563 2677 [(2677, 1), (8563, 1)]
## 4091 6829 [(4091, 1), (6829, 1)]
## 8563 2677 [(2677, 1), (8563, 1)]
## 4091 6829 [(4091, 1), (6829, 1)]
## 8563 2677 [(2677, 1), (8563, 1)]
## 4091 6829 [(4091, 1), (6829, 1)]
## 8563 2677 [(2677, 1), (8563, 1)]
## 4091 6829 [(4091, 1), (6829, 1)]

As in, "they're NOT random".

The random number generator is broken by the sympy.factorint()
function.

Random.choice() works ok if the factorint() function commented out.

## 6089 1811 None
## 6449 1759 None
## 9923 4639 None
## 4013 4889 None
## 4349 2029 None
## 6703 8677 None
## 1879 1867 None
## 5153 5279 None
## 2011 4937 None
## 7253 5507 None

This makes sympy worse than worthless, as it fucks up other modules.

Does seeding ( random.seed ) random with time fix this? It should.
-N
 
M

Mensanator

So you agree with me.  

Are you deliberately misconstruing what I write?
Lack of prefection = uselessness.  

_I_ never said that.

What I said was a zero change in net functionality is "worthless".

A negative change in net functionality is "less than worthless".

Haven't negative numbers been well understood since the Middle Ages?

Why is this concept so difficult to grasp?
Thanks for being honest,

I wish I could say the same.
whether your realized you defeated your own disclaimer or not.

Conclusion based on false premise.
 
M

Mensanator

Mensanator, for alls sake, you've done right by pointing out the bug
instead of muttering silently in your room,

I thought that was what's important. Who am I that anyone
cares about my opinions?
but there is a thing
called tolerance that you really should learn, it's about tolerating
and understanding the possibility that other people are humans too and
humans create mistakes, lots of them in fact and that includes you (if
you're humans).

Actually, I had resolved to do that and I thought my original
post reflected that. Guess I still have to work at it.
Along with tolerance should come a better choice of
wordings,
Apparently.

instead of saying "it sucks "

I didn't say that.
"because it does something unexpected and unwanted"

I didn't say that either. "Unexpected and unwanted" is not
necessarily a problem, provided those symptoms are confined
to the program. When they reach out and damage things outside
the program, it's a lot more serious.
and telling everyone not to use it,

It was intended as a warning not to use it. When I saw the
random number generator wasn't working, guess what the last
cause was that I considered? Do you realize how subtle that
error is, how many times I had to stare at it before realizing
the problem? You can't see it looking at the trees (factorint()
reurns exactly the factors of the composite it was given).

It isn't until you step back and look at the forest you suddenly
realize that the sequence coming from the "randomly" selected
factors is repeating. I was trying to prevent a lot of head
scratching by other end users who may be playing with it.
you could
just say "it does something unexpected and unwanted" and say that you
wanted it fixed.

I don't think that conveys the proper seriousness.
It's not that you've done anything wrong, but it's
about your attitude.

As I said, I thought I had toned done the attitude.

OTOH, I'm not sure certain others aren't deliberately
misconstuing what I wrote.
 
M

Mensanator

Notice anything funny about the "random" choices?
import sympy
import time
import random
f = [i for i in sympy.primerange(1000,10000)]
for i in xrange(10):
  f1 = random.choice(f)
  print f1,
  f2 = random.choice(f)
  print f2,
  C = f1*f2
  ff = None
  ff = sympy.factorint(C)
  print ff
##  7307 7243 [(7243, 1), (7307, 1)]
##  4091 6829 [(4091, 1), (6829, 1)]
##  8563 2677 [(2677, 1), (8563, 1)]
##  4091 6829 [(4091, 1), (6829, 1)]
##  8563 2677 [(2677, 1), (8563, 1)]
##  4091 6829 [(4091, 1), (6829, 1)]
##  8563 2677 [(2677, 1), (8563, 1)]
##  4091 6829 [(4091, 1), (6829, 1)]
##  8563 2677 [(2677, 1), (8563, 1)]
##  4091 6829 [(4091, 1), (6829, 1)]
As in, "they're NOT random".
The random number generator is broken by the sympy.factorint()
function.
Random.choice() works ok if the factorint() function commented out.
##  6089 1811 None
##  6449 1759 None
##  9923 4639 None
##  4013 4889 None
##  4349 2029 None
##  6703 8677 None
##  1879 1867 None
##  5153 5279 None
##  2011 4937 None
##  7253 5507 None
This makes sympy worse than worthless, as it fucks up other modules.

Does seeding ( random.seed ) random with time fix this? It should.

I suppose that depends on how long it takes factorint() to
process a number. If the seed is reset before the next clock
tick, you will get the same random numbers as the previous
iteration.

Frankly, I don't understand why factorint() reseeds at all.
Doesn't Random automatically initialize the seed?
Doesn't constantly reseeding degrade the performance of the
random number generator? With Robert Kern's patch, the reseeding
is no longer a constant, fixing the immediate symptom.

But what if _I_ wanted to make a repeatable sequence for test
purposes? Wouldn't factorint() destroy my attempt by reseeding
on every call?
 
I

Istvan Albert

But what if _I_ wanted to make a repeatable sequence for test
purposes? Wouldn't factorint() destroy my attempt by reseeding
on every call?

Would it?

It may just be that you are now itching to see a problem even where
there isn't one.

i.
 
B

bearophileHUGS

apatheticagnostic:
I swear, this is one of the most polite-oriented groups I've ever
seen.
Not that that's a bad thing or anything, it's nice to be nice.

Yep, and with lot more work it may even become a bit fit for women/
females too.

Bye,
bearophile
 
M

Mensanator

Would it?

I don't know, haven't tried it yet, merely extrapolating
from how I _THINK_ it works. I used to be a System Test Engineer
and had a gift for being able to walk up to hardware/software
and break it. Spooky? No, because I could extrapolate from
the design, I could often anticipate just where to nudge it to
cause it to crash. I wasn't very popular with the programmers.
It may just be that you are now itching to see a problem even where
there isn't one.

No, no, no. That would be an oh-what-a-giveaway, wouldn't it?
 
N

Nanjundi

I suppose that depends on how long it takes factorint() to
process a number. If the seed is reset before the next clock
tick, you will get the same random numbers as the previous
iteration.

Alright, then make it constant and don't worry about the clock tick..... f1 = random.choice(f)
.... print f1,
.... f2 = random.choice(f)
.... print f2,
.... C = f1*f2
.... ff = None
.... ff = sympy.factorint(C)
.... print ff
.... random.seed(i)
....
5573 5171 [(5171, 1), (5573, 1)]
8537 7673 [(7673, 1), (8537, 1)]
2063 8573 [(2063, 1), (8573, 1)]
9551 9473 [(9473, 1), (9551, 1)]
2909 5659 [(2909, 1), (5659, 1)]
2897 1789 [(1789, 1), (2897, 1)]
6361 7541 [(6361, 1), (7541, 1)]
8017 8293 [(8017, 1), (8293, 1)]
3671 2207 [(2207, 1), (3671, 1)]
2803 9629 [(2803, 1), (9629, 1)]

Frankly, I don't understand why factorint() reseeds at all.
Read the doc:
* The rho algorithm is a Monte Carlo method whose outcome can be
affected by changing the random seed value. *
Doesn't Random automatically initialize the seed?
Doesn't constantly reseeding degrade the performance of the
random number generator? With Robert Kern's patch, the reseeding
is no longer a constant, fixing the immediate symptom.

Does it matter? The factorint reseeds using a constant seed (1234).
But what if _I_ wanted to make a repeatable sequence for test
purposes? Wouldn't factorint() destroy my attempt by reseeding
on every call?

Repeatable sequence? save it and reuse!
Think about "What if"s doesn't get any work done.

-N
 
M

Mensanator

Alright, then make it constant and don't worry about the clock tick.

Reseeding with a constant always sets the sequence to the same
starting
point.
...   f1 = random.choice(f)
...   print f1,
...   f2 = random.choice(f)
...   print f2,
...   C = f1*f2
...   ff = None
...   ff = sympy.factorint(C)
...   print ff
...   random.seed(i)
...
5573 5171 [(5171, 1), (5573, 1)]
8537 7673 [(7673, 1), (8537, 1)]
2063 8573 [(2063, 1), (8573, 1)]
9551 9473 [(9473, 1), (9551, 1)]
2909 5659 [(2909, 1), (5659, 1)]
2897 1789 [(1789, 1), (2897, 1)]
6361 7541 [(6361, 1), (7541, 1)]
8017 8293 [(8017, 1), (8293, 1)]
3671 2207 [(2207, 1), (3671, 1)]
2803 9629 [(2803, 1), (9629, 1)]
Frankly, I don't understand why factorint() reseeds at all.

Read the doc:
*    The rho algorithm is a Monte Carlo method whose outcome can be
affected by changing the random seed value.  *

But that doesn't give it the right to mess with the state
of the random number generator _I'm_ using. Had I actually
known what was happening, I could have saved the state of
my random number generator s=random.getstate() and then restored
it after calling factorint(), random.setstate(s).

import sympy # with RK's patch removed
import time
import random

f = [i for i in sympy.primerange(1000,10000)]

for i in xrange(10):
f1 = random.choice(f)
print f1,
f2 = random.choice(f)
print f2,
C = f1*f2
ff = None
rs = random.getstate()
ff = sympy.factorint(C)
random.setstate(rs)
print ff

5669 3863 [(3863, 1), (5669, 1)]
1973 5431 [(1973, 1), (5431, 1)]
7577 6089 [(6089, 1), (7577, 1)]
8761 4957 [(4957, 1), (8761, 1)]
4153 2719 [(2719, 1), (4153, 1)]
4999 5669 [(4999, 1), (5669, 1)]
8863 5417 [(5417, 1), (8863, 1)]
7151 7951 [(7151, 1), (7951, 1)]
7867 9887 [(7867, 1), (9887, 1)]
9283 5227 [(5227, 1), (9283, 1)]

Of course, this is new as of Python 2.4, so if factorint()
tried to save & restore state, sympy wouldn't work on Python
2.3 or earlier.

If I'm reading RK's patch correctly, he doesn't reseed the
random number generator, he creates a new random object that
maintains it's own state that can be freely seeded to any
value without disturbing the state of my random number generator.
Does it matter?

I was wrong. It is a constant, just not 1234. If that's what
factorint() needs, fine. As long as it maintains a seperate state
than the one I'm using.
The factorint reseeds using a constant seed (1234).

Not now it doesn't:

@@ -92,8 +92,8 @@ def pollard_pm1(n, B=10, seed=1234):

"""
from math import log
- random.seed(seed + B)
- a = random.randint(2, n-1)
+ prng = random.Random(seed + B)
+ a = prng.randint(2, n-1)
for p in sieve.primerange(2, B):
e = int(log(B, p))
a = pow(a, p**e, n)
Repeatable sequence? save it and reuse!

As part of my resolution to tone down my attitude,
I won't even reply to that.
 
N

Nanjundi

Reseeding with a constant always sets the sequence to the same
starting
point.

Right, not a good idea.
... f1 = random.choice(f)
... print f1,
... f2 = random.choice(f)
... print f2,
... C = f1*f2
... ff = None
... ff = sympy.factorint(C)
... print ff
... random.seed(i)
...
5573 5171 [(5171, 1), (5573, 1)]
8537 7673 [(7673, 1), (8537, 1)]
2063 8573 [(2063, 1), (8573, 1)]
9551 9473 [(9473, 1), (9551, 1)]
2909 5659 [(2909, 1), (5659, 1)]
2897 1789 [(1789, 1), (2897, 1)]
6361 7541 [(6361, 1), (7541, 1)]
8017 8293 [(8017, 1), (8293, 1)]
3671 2207 [(2207, 1), (3671, 1)]
2803 9629 [(2803, 1), (9629, 1)]
Frankly, I don't understand why factorint() reseeds at all.
Read the doc:
* The rho algorithm is a Monte Carlo method whose outcome can be
affected by changing the random seed value. *

But that doesn't give it the right to mess with the state
of the random number generator _I'm_ using. Had I actually
known what was happening, I could have saved the state of
my random number generator s=random.getstate() and then restored
it after calling factorint(), random.setstate(s).

import sympy # with RK's patch removed
import time
import random

f = [i for i in sympy.primerange(1000,10000)]

for i in xrange(10):
f1 = random.choice(f)
print f1,
f2 = random.choice(f)
print f2,
C = f1*f2
ff = None
rs = random.getstate()
ff = sympy.factorint(C)
random.setstate(rs)
print ff

5669 3863 [(3863, 1), (5669, 1)]
1973 5431 [(1973, 1), (5431, 1)]
7577 6089 [(6089, 1), (7577, 1)]
8761 4957 [(4957, 1), (8761, 1)]
4153 2719 [(2719, 1), (4153, 1)]
4999 5669 [(4999, 1), (5669, 1)]
8863 5417 [(5417, 1), (8863, 1)]
7151 7951 [(7151, 1), (7951, 1)]
7867 9887 [(7867, 1), (9887, 1)]
9283 5227 [(5227, 1), (9283, 1)]

Of course, this is new as of Python 2.4, so if factorint()
tried to save & restore state, sympy wouldn't work on Python
2.3 or earlier.

If I'm reading RK's patch correctly, he doesn't reseed the
random number generator, he creates a new random object that
maintains it's own state that can be freely seeded to any
value without disturbing the state of my random number generator.


Does it matter?

I was wrong. It is a constant, just not 1234. If that's what
factorint() needs, fine. As long as it maintains a seperate state
than the one I'm using.
The factorint reseeds using a constant seed (1234).

Not now it doesn't:
:)


@@ -92,8 +92,8 @@ def pollard_pm1(n, B=10, seed=1234):

"""
from math import log
- random.seed(seed + B)
- a = random.randint(2, n-1)
+ prng = random.Random(seed + B)
+ a = prng.randint(2, n-1)
for p in sieve.primerange(2, B):
e = int(log(B, p))
a = pow(a, p**e, n)


Repeatable sequence? save it and reuse!

As part of my resolution to tone down my attitude,
I won't even reply to that.
Thanks.
Think about "What if"s doesn't get any work done.
?
nevermind.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top