1 # For licensing info see the included LICENSE file
3 # Josef Moudrik, <J dot Moudrik at standard google mail ending>, 2012
5 from itertools
import product
, chain
8 from exc
import IncompatibleUnits
, MemExceeded
10 def search(base_numbers
, ops
, cc
, max_round
=None, mem_limit
=2*1024**2):
13 # check if measurements do not mean anything directly
14 for m
in base_numbers
:
15 cc
.checkCandidate(m
, verbose
=True)
18 final_round
= max_round
== 0
21 while not final_round
:
22 final_round
= max_round
== round_count
25 print "ROUND %d started"%(round_count
,)
29 for op
in ops
.get(round_count
, ops
.get('default', None)):
32 raise NotImplementedError
35 sofar
= list(chain(*bf
))
37 pr
= [last
] + [sofar
]*(ar
-1)
41 if not op
.isCommutative() and ar
== 2:
42 i2
= product(chain(*(bf
[:-1])), last
)
44 for t
in chain(i1
, i2
):
45 if elem_count
% 10000 == 0 and not final_round
:
46 mem_used
= resource
.getrusage(resource
.RUSAGE_SELF
).ru_maxrss
47 if mem_used
> mem_limit
:
50 print "Limit %.1f MB, Used %.1f MB"%(mem_limit
/ 1024.0, mem_used
/ 1024.0)
51 print "FINAL ROUND FOLLOWS"
57 # we do not need to add if we are in the final round
58 # we save a lot of memory this way (and may even be able to compute one more round therefore
61 # register the result to see improving matches incrementaly
62 cc
.checkCandidate(res
, verbose
=True)
63 except IncompatibleUnits
:
65 except ZeroDivisionError:
69 # set the limit so that we end in the next iteration
70 max_round
= round_count
+ 1
74 print "ROUND %d ended, searched %d combinations in total"%(round_count
, elem_count
)
78 except KeyboardInterrupt:
87 # show what we have found