source: sasview/park-1.2.1/park/deps.py @ 3540156

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 3540156 was 3570545, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Adding park Part 2

  • Property mode set to 100644
File size: 3.0 KB
Line 
1# This program is public domain
2# Author: Paul Kienzle
3"""
4Functions for manipulating dependencies.
5
6Parameter values must be updated in the correct order.  If parameter A
7depends on parameter B, then parameter B must be evaluated first. 
8"""
9
10def order_dependencies(pairs):
11    """
12    Order elements from pairs so that b comes before a in the
13    ordered list for all pairs (a,b).
14    """
15    #print "order_dependencies",pairs
16    emptyset = set()
17    order = []
18
19    # Break pairs into left set and right set
20    left,right = [set(s) for s in zip(*pairs)] if pairs != [] else ([],[])
21    while pairs != []:
22        #print "within",pairs
23        # Find which items only occur on the right
24        independent = right - left
25        if independent == emptyset:
26            cycleset = ", ".join(str(s) for s in left)
27            raise ValueError,"Cyclic dependencies amongst %s"%cycleset
28
29        # The possibly resolvable items are those that depend on the independents
30        dependent = set([a for a,b in pairs if b in independent])
31        pairs = [(a,b) for a,b in pairs if b not in independent]
32        if pairs == []:
33            resolved = dependent
34        else:
35            left,right = [set(s) for s in zip(*pairs)]
36            resolved = dependent - left
37        #print "independent",independent,"dependent",dependent,"resolvable",resolved
38        order += resolved
39        #print "new order",order
40    order.reverse()
41    return order
42
43# ========= Test code ========
44def _check(msg,pairs):
45    """
46    Verify that the list n contains the given items, and that the list
47    satisfies the partial ordering given by the pairs in partial order.
48    """
49    left,right = zip(*pairs) if pairs != [] else ([],[])
50    items = set(left)
51    n = order_dependencies(pairs)
52    if set(n) != items or len(n) != len(items):
53        n.sort()
54        items = list(items); items.sort()
55        raise Exception,"%s expect %s to contain %s for %s"%(msg,n,items,pairs)
56    for lo,hi in pairs:
57        if lo in n and hi in n and n.index(lo) >= n.index(hi):
58            raise Exception,"%s expect %s before %s in %s for %s"%(msg,lo,hi,n,pairs)
59
60def test():
61    import numpy
62
63    # Null case
64    _check("test empty",[])
65
66    # Some dependencies
67    _check("test1",[(2,7),(1,5),(1,4),(2,1),(3,1),(5,6)])
68    _check("test1 renumbered",[(6,1),(7,3),(7,4),(6,7),(5,7),(3,2)])
69    _check("test1 numpy",numpy.array([(2,7),(1,5),(1,4),(2,1),(3,1),(5,6)]))
70
71    # No dependencies
72    _check("test2",[(4,1),(3,2),(8,4)])
73
74    # Cycle test
75    pairs = [(1,4),(4,3),(4,5),(5,1)] 
76    try: n = order_dependencies(pairs)
77    except ValueError: pass
78    else: raise Exception,"test3 expect ValueError exception for %s"%(pairs,)
79
80    # large test for gross speed check
81    A = numpy.random.randint(4000,size=(1000,2))
82    A[:,1] += 4000  # Avoid cycles
83    _check("test-large",A)
84
85    # depth tests
86    k = 200
87    A = numpy.array([range(0,k),range(1,k+1)]).T
88    _check("depth-1",A)
89
90    A = numpy.array([range(1,k+1),range(0,k)]).T
91    _check("depth-2",A)
92
93if __name__ == "__main__":
94    test()
Note: See TracBrowser for help on using the repository browser.