- Timestamp:
- 07/07/15 00:53:53 (11 months ago)
- Location:
- mystic
- Files:
-
- 5 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
mystic/mystic/constraints.py
r778 r802 545 545 546 546 547 from random import randrange, shuffle 548 def unique(seq, full=None): 549 """replace the duplicate values with unique values in 'full' 550 551 If full is a type (int or float), then unique values of the given type 552 are selected from range(min(seq),max(seq)). If full is a dict of 553 {'min':min, 'max':max}, then unique floats are selected from 554 range(min(seq),max(seq)). If full is a sequence (list or set), then 555 unique values are selected from the given sequence. 556 """ 557 unique = set() 558 # replace all duplicates with 'None' 559 seq = [x if x not in unique and not unique.add(x) else None for x in seq] 560 lseq = len(seq) 561 # check type if full not specified 562 if full is None: 563 if all([isinstance(x, int) for x in unique]): full = int 564 else: full = float 565 ok = True 566 else: ok = False 567 # check all unique show up in 'full' 568 if full in (int,float): # specified type, not range 569 ok = ok or full==float or all([isinstance(x, int) for x in unique]) 570 msg = "not all items are of type='%s'" % full.__name__ 571 _min = min(unique) 572 _max = max(unique) 573 elif isinstance(full, dict): # specified min/max for floats 574 ok = min(unique) >= full['min'] and max(unique) < full['max'] 575 if not ok: 576 oops = list(unique - set(range(full['min'],full['max']))) 577 msg = "x=%s not in %s <= x < %s" % (oops[-1],full['min'],full['max']) 578 _min = full['min'] 579 _max = full['max'] 580 full = float 581 else: # full is a list of all possible values 582 ok = unique.issubset(full) 583 if not ok: 584 oops = list(unique - set(full)) 585 msg = "%s not in given set" % oops[-1] 586 _min = _max = None 587 if not ok: raise ValueError(msg) 588 # check if a unique sequence is possible to build 589 if full is float: 590 if _min == _max and lseq > 1: 591 msg = "no unique len=%s sequence with %s <= x <= %s" % (lseq,_min,_max) 592 raise ValueError(msg) 593 # replace the 'None' values in seq with 'new' values 594 #XXX: HIGHLY UNLIKELY two numbers will be the same, but possible 595 return [randrange(_min,_max,_int=float) if x is None else x for x in seq] 596 # generate all possible values not found in 'unique' 597 if full is int: 598 if max(lseq - (_max+1 - _min), 0): 599 msg = "no unique len=%s sequence with %s <= x <= %s" % (lseq,_min,_max) 600 raise ValueError(msg) 601 new = list(set(range(_min,_max+1)) - unique) 602 else: 603 if lseq > len(full): 604 msg = "no unique len=%s sequence in given set" % lseq 605 raise ValueError(msg) 606 new = list(set(full) - unique) 607 # ensure randomly ordered 608 shuffle(new) 609 # replace the 'None' values in seq with 'new' values 610 return [new.pop() if x is None else x for x in seq] 611 612 613 #XXX: enable impose_unique on selected members of x? (see constraints.integers) 614 615 def impose_unique(seq=None): 616 """ensure all values are unique and found in the given set""" 617 def dec(f): 618 def func(x,*args,**kwds): 619 return f(unique(x, seq),*args,**kwds) 620 return func 621 return dec 622 623 624 #XXX: enable near_integers and has_unique on selected members of x? 625 626 from numpy import round, abs 627 def near_integers(x): # use as a penalty for int programming 628 """the sum of all deviations from int values""" 629 return abs(x - round(x)).sum() 630 631 def has_unique(x): # use as a penalty for unique numbers 632 """check for uniqueness of the members of x""" 633 return sum(x.count(xi) for xi in x) 634 #return len(x) - len(set(x)) 635 636 637 547 638 # EOF 639 640 # EOF -
mystic/mystic/symbolic.py
r776 r802 58 58 # Flatten b, in case it's in the form [[0, 1, 2]] for example. 59 59 if len(b) == 1: 60 b = list(ndarray.flatten(asarray(b)))60 b = ndarray.flatten(asarray(b)).tolist() 61 61 62 62 # Check dimensions and give errors if incorrect. … … 83 83 # Flatten h, in case it's in the form [[0, 1, 2]] for example. 84 84 if len(h) == 1: 85 h = list(ndarray.flatten(asarray(h)))85 h = ndarray.flatten(asarray(h)).tolist() 86 86 87 87 # Check dimensions and give errors if incorrect.
Note: See TracChangeset
for help on using the changeset viewer.