Changeset 807


Ignore:
Timestamp:
07/24/15 12:00:50 (10 months ago)
Author:
mmckerns
Message:

functional interface for support_convergence and support_hypercube

Location:
mystic
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/__init__.py

    r805 r807  
    2525 
    2626__all__ = ['solvers', 'termination', 'strategy', 'munge', 'tools', \ 
    27            'constraints', 'penalty', 'coupler', 'symbolic'] 
     27           'constraints', 'penalty', 'coupler', 'symbolic', \ 
     28           'model_plotter', 'log_reader'] 
    2829 
    2930# solvers 
     
    4647 
    4748# scripts 
    48 from scripts import * 
     49from scripts import model_plotter, log_reader 
     50import support 
    4951 
    5052# backward compatibility 
  • mystic/mystic/scripts.py

    r806 r807  
    1717 
    1818from mystic.munge import read_history 
    19 from mystic.munge import logfile_reader, raw_to_support 
     19from mystic.munge import logfile_reader, raw_to_support, read_raw_file 
    2020 
    2121# globals 
     
    791791 
    792792    # parse file contents to get (i,id), cost, and parameters 
    793     from mystic.munge import logfile_reader, read_raw_file 
    794793    try: 
    795794        step, param, cost = logfile_reader(filename) 
     
    845844    #print "conv = %s" % conv 
    846845 
    847     import matplotlib.pyplot as plt 
    848  
    849846    fig = plt.figure() 
    850847 
  • mystic/mystic/tools.py

    r801 r807  
    1919    - multiply: recursive elementwise casting multiply of x by n 
    2020    - divide: recursive elementwise casting divide of x by n 
     21    - factor: generator for factors of a number 
    2122    - flatten: flatten a sequence 
    2223    - flatten_array: flatten an array  
     
    176177    if n is 1: return x 
    177178    return x/n 
     179 
     180def factor(n): 
     181    "generator for factors of a number" 
     182    #yield 1 
     183    i = 2 
     184    limit = n**0.5 
     185    while i <= limit: 
     186        if n % i == 0: 
     187            yield i 
     188            n = n / i 
     189            limit = n**0.5 
     190        else: 
     191            i += 1 
     192    if n > 1: 
     193        yield n 
    178194 
    179195def list_or_tuple(x): # set, ...? 
  • mystic/scripts/support_convergence.py

    r776 r807  
    66#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE 
    77 
    8 __doc__ = """ 
    9 support_convergence.py [options] filename 
     8from mystic.support import convergence 
    109 
    11 generate parameter convergence plots from file written with 'write_support_file' 
     10__doc__ = convergence.__doc__ 
    1211 
    13 The option "param" takes an indicator string. The indicator string is built 
    14 from comma-separated array slices. For example, params = ":" will plot all 
    15 parameters in a single plot.  Alternatively, params = ":2, 2:" will split the 
    16 parameters into two plots, and params = "0" will only plot the first parameter. 
     12if __name__ == '__main__': 
    1713 
    18 The option "label" takes comma-separated strings. For example, label = "x,y," 
    19 will label the y-axis of the first plot with 'x', a second plot with 'y', and 
    20 not add a label to a third or subsequent plots. If more labels are given than 
    21 plots, then the last label will be used for the y-axis of the 'cost' plot. 
    22 LaTeX is also accepted. For example, label = "$ h$, $ {\\alpha}$, $ v$" will 
    23 label the axes with standard LaTeX math formatting. Note that the leading 
    24 space is required, and the text is aligned along the axis. 
     14    import sys 
    2515 
    26 Required Inputs: 
    27   filename            name of the python convergence logfile (e.g paramlog.py) 
    28 """ 
    29  
    30 def factor(n): 
    31   "generator for factors of a number" 
    32   #yield 1 
    33   i = 2 
    34   limit = n**0.5 
    35   while i <= limit: 
    36     if n % i == 0: 
    37       yield i 
    38       n = n / i 
    39       limit = n**0.5 
    40     else: 
    41       i += 1 
    42   if n > 1: 
    43     yield n 
    44  
    45 def best_dimensions(n): 
    46   "get the 'best' dimensions (n x m) for arranging plots" 
    47   allfactors = list(factor(n)) 
    48   from numpy import product 
    49   cand = [1] + [product(allfactors[:i+1]) for i in range(len(allfactors))] 
    50  #return cand[-1], n/cand[-1] 
    51   best = [cand[len(cand)/2], n/cand[len(cand)/2]] 
    52   best.sort(reverse=True) 
    53   return tuple(best) 
    54 # if len(cand)%2: 
    55 #   return cand[len(cand)/2], cand[len(cand)/2] 
    56 # return cand[len(cand)/2], cand[len(cand)/2 - 1] 
     16    convergence(sys.argv[1:]) 
    5717 
    5818 
    59 if __name__ == '__main__': 
    60   #print __doc__ 
    61  
    62   #XXX: note that 'argparse' is new as of python2.7 
    63   from optparse import OptionParser 
    64   parser = OptionParser(usage=__doc__) 
    65   parser.add_option("-i","--iter",action="store",dest="step",metavar="INT",\ 
    66                     default=None,help="the largest iteration to plot") 
    67   parser.add_option("-p","--param",action="store",dest="param",\ 
    68                     metavar="STR",default=":", 
    69                     help="indicator string to select parameters") 
    70   parser.add_option("-l","--label",action="store",dest="label",\ 
    71                     metavar="STR",default="", 
    72                     help="string to assign label to y-axis") 
    73   parser.add_option("-n","--nid",action="store",dest="id",\ 
    74                     metavar="INT",default=None, 
    75                     help="id # of the nth simultaneous points to plot") 
    76   parser.add_option("-c","--cost",action="store_true",dest="cost",\ 
    77                     default=False,help="also plot the parameter cost") 
    78   parser.add_option("-g","--legend",action="store_true",dest="legend",\ 
    79                     default=False,help="show the legend") 
    80   parsed_opts, parsed_args = parser.parse_args() 
    81  
    82   # get the name of the parameter log file 
    83   from mystic.munge import read_history 
    84   params, cost = read_history(parsed_args[0]) 
    85  
    86   if parsed_opts.cost: # also plot the cost 
    87    #exec "from %s import cost" % file 
    88     pass 
    89   else: 
    90     cost = None 
    91  
    92   if parsed_opts.legend: # show the legend 
    93     legend = True 
    94   else: 
    95     legend = False 
    96  
    97   try: # select which iteration to stop plotting at 
    98     step = int(parsed_opts.step) 
    99   except: 
    100     step = None 
    101  
    102   try: # select which parameters to plot 
    103     select = parsed_opts.param.split(',')  # format is ":2, 2:4, 5, 6:" 
    104   except: 
    105     select = [':'] 
    106    #select = [':1'] 
    107    #select = [':2','2:'] 
    108    #select = [':1','1:2','2:3','3:'] 
    109    #select = ['0','1','2','3'] 
    110   plots = len(select) 
    111  
    112   try: # select labels for the axes 
    113     label = parsed_opts.label.split(',')  # format is "x, y, z" 
    114     label += [''] * max(0, plots - len(label)) 
    115   except: 
    116     label = [''] * plots 
    117      
    118   try: # select which 'id' to plot results for 
    119     id = int(parsed_opts.id) 
    120   except: 
    121     id = None # i.e. 'all' **or** use id=0, which should be 'best' energy ? 
    122  
    123   # ensure all terms of select have a ":" 
    124   for i in range(plots): 
    125     if isinstance(select[i], int): select[i] = str(select[i]) 
    126     if select[i] == '-1': select[i] = 'len(params)-1:len(params)' 
    127     elif not select[i].count(':'): 
    128       select[i] += ':' + str(int(select[i])+1) 
    129  
    130   # take only the first 'step' iterations 
    131   params = [var[:step] for var in params] 
    132   if cost: 
    133     cost = cost[:step] 
    134  
    135   # take only the selected 'id' 
    136   if id != None: 
    137     param = [] 
    138     for j in range(len(params)): 
    139       param.append([p[id] for p in params[j]]) 
    140     params = param[:] 
    141  
    142   import matplotlib.pyplot as plt 
    143  
    144   if cost: j = 1 
    145   else: j = 0 
    146   dim1,dim2 = best_dimensions(plots + j) 
    147  
    148   fig = plt.figure() 
    149   ax1 = fig.add_subplot(dim1,dim2,1) 
    150   ax1.set_ylabel(label[0]) 
    151   data = eval("params[%s]" % select[0]) 
    152   try: 
    153     n = int(select[0].split(":")[0]) 
    154   except ValueError: 
    155     n = 0 
    156   for line in data: 
    157     ax1.plot(line,label=str(n))#, marker='o') 
    158     n += 1 
    159   if legend: plt.legend() 
    160  
    161   for i in range(2, plots + 1): 
    162     exec "ax%d = fig.add_subplot(dim1,dim2,%d, sharex=ax1)" % (i,i) 
    163     exec "ax%d.set_ylabel(label[%d])" % (i,i-1) 
    164     data = eval("params[%s]" % select[i-1]) 
    165     try: 
    166       n = int(select[i-1].split(":")[0]) 
    167     except ValueError: 
    168       n = 0 
    169     for line in data: 
    170       exec "ax%d.plot(line,label='%s')#, marker='o')" % (i,n) 
    171       n += 1 
    172     if legend: plt.legend() 
    173   if cost: 
    174     exec "cx1 = fig.add_subplot(dim1,dim2,%d, sharex=ax1)" % int(plots+1) 
    175     exec "cx1.plot(cost,label='cost')#, marker='o')" 
    176     if max(0, len(label) - plots): exec "cx1.set_ylabel(label[-1])" 
    177     if legend: plt.legend() 
    178  
    179   plt.show() 
    180  
    181   ### USUAL WAY OF CREATING PLOTS ### 
    182   #fig = plt.figure() 
    183   #ax1 = fig.add_subplot(3,2,1) 
    184   ##ax1.ylim(60,105) 
    185   #ax1.plot(x) 
    186   #ax1.plot(x2) 
    187   #plt.title('convergence for thickness support') 
    188   ##plt.xlabel('iterations') 
    189   #plt.ylabel('thickness') 
    190   # 
    191   #ax2 = fig.add_subplot(3,2,2, sharex=ax1) 
    192   ##ax2.ylim(0,1) 
    193   #ax2.plot(wx) 
    194   #ax2.plot(wx2) 
    195   #plt.title('convergence for weight(thickness)') 
    196   ##plt.xlabel('iterations') 
    197   #plt.ylabel('weight') 
    198   # 
    199   #plt.show() 
    200   ################################### 
    201  
    20219# EOF 
  • mystic/scripts/support_hypercube.py

    r776 r807  
    66#  - http://mmckerns.github.io/project/mystic/browser/mystic/LICENSE 
    77 
    8 __doc__ = """ 
    9 support_hypercube.py [options] filename 
     8from mystic.support import hypercube 
    109 
    11 generate parameter support plots from file written with 'write_support_file' 
    12  
    13 The options "bounds", "axes", and "iters" all take indicator strings. 
    14 The bounds should be given as comma-separated slices. For example, using 
    15 bounds = "60:105, 0:30, 2.1:2.8" will set the lower and upper bounds for 
    16 x to be (60,105), y to be (0,30), and z to be (2.1,2.8).  Similarly, axes 
    17 also accepts comma-separated groups of ints; however, for axes, each entry 
    18 indicates which parameters are to be plotted along each axis -- the first 
    19 group for the x direction, the second for the y direction, and third for z.  
    20 Thus, axes = "2 3, 6 7, 10 11" would set 2nd and 3rd parameters along x. 
    21 Iters also accepts a string built from comma-separated array slices. For 
    22 example, iters = ":" will plot all iters in a single plot. Alternatively, 
    23 iters = ":2, 2:" will split the iters into two plots, while iters = "0" will 
    24 only plot the first iteration. 
    25  
    26 The option "label" takes comma-separated strings. For example, label = "x,y," 
    27 will place 'x' on the x-axis, 'y' on the y-axis, and nothing on the z-axis. 
    28 LaTeX is also accepted. For example, label = "$ h $, $ {\\alpha}$, $ v$" will 
    29 label the axes with standard LaTeX math formatting. Note that the leading 
    30 space is required, while a trailing space aligns the text with the axis 
    31 instead of the plot frame. 
    32  
    33 Required Inputs: 
    34   filename            name of the python convergence logfile (e.g paramlog.py) 
    35 """ 
    36  
    37 from support_convergence import best_dimensions 
    38  
     10__doc__ = hypercube.__doc__ 
    3911 
    4012if __name__ == '__main__': 
    4113 
    42   #XXX: note that 'argparse' is new as of python2.7 
    43   from optparse import OptionParser 
    44   parser = OptionParser(usage=__doc__) 
    45   parser.add_option("-b","--bounds",action="store",dest="bounds",\ 
    46                     metavar="STR",default="0:1, 0:1, 0:1", 
    47                     help="indicator string to set hypercube bounds") 
    48   parser.add_option("-x","--axes",action="store",dest="xyz",\ 
    49                     metavar="STR",default="0, 1, 2", 
    50                     help="indicator string to assign parameter to axis") 
    51   parser.add_option("-i","--iters",action="store",dest="iters",\ 
    52                     metavar="STR",default="-1", 
    53                     help="indicator string to select iterations to plot") 
    54   parser.add_option("-l","--label",action="store",dest="label",\ 
    55                     metavar="STR",default=",,", 
    56                     help="string to assign label to axis") 
    57   parser.add_option("-n","--nid",action="store",dest="id",\ 
    58                     metavar="INT",default=None, 
    59                     help="id # of the nth simultaneous points to plot") 
    60   parser.add_option("-s","--scale",action="store",dest="scale",\ 
    61                     metavar="INT",default=1.0, 
    62                     help="grayscale contrast multiplier for points in plot") 
    63   parser.add_option("-f","--flat",action="store_true",dest="flatten",\ 
    64                     default=False,help="show selected iterations in a single plot") 
    65   parsed_opts, parsed_args = parser.parse_args() 
     14    import sys 
    6615 
    67   # get the name of the parameter log file 
    68   from mystic.munge import read_history 
    69   params, _cost = read_history(parsed_args[0]) 
    70   # would be nice to use meta = ['wx','wx2','x','x2','wy',...] 
    71   # exec "from %s import meta" % file 
     16    hypercube(sys.argv[1:]) 
    7217 
    73   try: # select the bounds 
    74     bounds = parsed_opts.bounds.split(",")  # format is "60:105, 0:30, 2.1:2.8" 
    75     bounds = [tuple(float(j) for j in i.split(':')) for i in bounds] 
    76   except: 
    77     bounds = [(0,1),(0,1),(0,1)] 
    78      
    79   try: # select which params are along which axes 
    80     xyz = parsed_opts.xyz.split(",")  # format is "0 1, 4 5, 8 9" 
    81     xyz = [tuple(int(j) for j in i.split()) for i in xyz] 
    82   except: 
    83     xyz = [(0,),(1,),(2,)] 
    84      
    85   try: # select labels for the axes 
    86     label = parsed_opts.label.split(',')  # format is "x, y, z" 
    87   except: 
    88     label = ['','',''] 
    89      
    90   x = params[max(xyz[0])] 
    91   try: # select which iterations to plot 
    92     select = parsed_opts.iters.split(',')  # format is ":2, 2:4, 5, 6:" 
    93   except: 
    94     select = ['-1'] 
    95    #select = [':'] 
    96    #select = [':1'] 
    97    #select = [':2','2:'] 
    98    #select = [':1','1:2','2:3','3:'] 
    99    #select = ['0','1','2','3'] 
    100  
    101   try: # collapse non-consecutive iterations into a single plot... 
    102     flatten = parsed_opts.flatten 
    103   except: 
    104     flatten = False 
    105  
    106   try: # select which 'id' to plot results for 
    107     id = int(parsed_opts.id) 
    108   except: 
    109     id = None # i.e. 'all' **or** use id=0, which should be 'best' energy ? 
    110  
    111   try: # scale the color in plotting the weights 
    112     scale = float(parsed_opts.scale) 
    113   except: 
    114     scale = 1.0 # color = color**scale 
    115  
    116   # ensure all terms of bounds and xyz are tuples 
    117   for bound in bounds: 
    118     if not isinstance(bound, tuple): 
    119       raise TypeError, "bounds should be tuples of (lower_bound,upper_bound)" 
    120   for i in range(len(xyz)): 
    121     if isinstance(xyz[i], int): 
    122       xyz[i] = (xyz[i],) 
    123     elif not isinstance(xyz[i], tuple): 
    124       raise TypeError, "xyz should be tuples of (param1,param2,param3,...)" 
    125  
    126   # ensure all terms of select are strings that have a ":" 
    127   for i in range(len(select)): 
    128     if isinstance(select[i], int): select[i] = str(select[i]) 
    129     if select[i] == '-1': select[i] = 'len(x)-1:len(x)' 
    130     elif not select[i].count(':'): 
    131       select[i] += ':' + str(int(select[i])+1) 
    132  
    133   # take only the selected 'id' 
    134   if id != None: 
    135     param = [] 
    136     for j in range(len(params)): 
    137       param.append([p[id] for p in params[j]]) 
    138     params = param[:] 
    139  
    140   # at this point, we should have: 
    141   #bounds = [(60,105),(0,30),(2.1,2.8)] or [(None,None),(None,None),(None,None)] 
    142   #xyz = [(0,1),(4,5),(8,9)] for any length tuple 
    143   #select = ['-1:'] or [':'] or [':1','1:2','2:3','3:'] or similar 
    144   #id = 0 or None 
    145  
    146   from mpl_toolkits.mplot3d import Axes3D 
    147   import matplotlib.pyplot as plt 
    148   from matplotlib.axes import subplot_class_factory 
    149   Subplot3D = subplot_class_factory(Axes3D) 
    150  
    151   plots = len(select) 
    152   if not flatten: 
    153     dim1,dim2 = best_dimensions(plots) 
    154   else: dim1,dim2 = 1,1 
    155  
    156   # use the default bounds where not specified 
    157   bounds = [list(i) for i in bounds] 
    158   for i in range(len(bounds)): 
    159     if bounds[i][0] is None: bounds[i][0] = 0 
    160     if bounds[i][1] is None: bounds[i][1] = 1 
    161  
    162   # correctly bound the first plot.  there must be at least one plot 
    163   fig = plt.figure() 
    164   ax1 = Subplot3D(fig, dim1,dim2,1) 
    165   ax1.plot([bounds[0][0]],[bounds[1][0]],[bounds[2][0]]) 
    166   ax1.plot([bounds[0][1]],[bounds[1][1]],[bounds[2][1]]) 
    167   if not flatten: 
    168     exec "plt.title('iterations[%s]')" % select[0] 
    169   else:  
    170     exec "plt.title('iterations[*]')" 
    171   ax1.set_xlabel(label[0]) 
    172   ax1.set_ylabel(label[1]) 
    173   ax1.set_zlabel(label[2]) 
    174   a = [ax1] 
    175  
    176   # set up additional plots 
    177   if not flatten: 
    178     for i in range(2, plots + 1): 
    179       exec "ax%d = Subplot3D(fig, dim1,dim2,%d)" % (i,i) 
    180       exec "ax%d.plot([bounds[0][0]],[bounds[1][0]],[bounds[2][0]])" % i 
    181       exec "ax%d.plot([bounds[0][1]],[bounds[1][1]],[bounds[2][1]])" % i 
    182       exec "plt.title('iterations[%s]')" % select[i - 1] 
    183       exec "ax%d.set_xlabel(label[0])" % i 
    184       exec "ax%d.set_ylabel(label[1])" % i 
    185       exec "ax%d.set_zlabel(label[2])" % i 
    186       exec "a.append(ax%d)" % i 
    187  
    188   # turn each "n:m" in select to a list 
    189   _select = [] 
    190   for sel in select: 
    191     if sel[0] == ':': _select.append("0"+sel) 
    192     else: _select.append(sel) 
    193   for i in range(len(_select)): 
    194     if _select[i][-1] == ':': select[i] = _select[i]+str(len(x)) 
    195     else: select[i] = _select[i] 
    196   for i in range(len(select)): 
    197     p = select[i].split(":") 
    198     if p[0][0] == '-': p[0] = "len(x)"+p[0] 
    199     if p[1][0] == '-': p[1] = "len(x)"+p[1] 
    200     select[i] = p[0]+":"+p[1] 
    201   steps = [eval("range(%s)" % sel.replace(":",",")) for sel in select] 
    202  
    203   # at this point, we should have: 
    204   #xyz = [(0,1),(4,5),(8,9)] for any length tuple 
    205   #steps = [[0,1],[1,2],[2,3],[3,4,5,6,7,8]] or similar 
    206   if flatten: 
    207     from mystic.tools import flatten 
    208     steps = [list(flatten(steps))] 
    209  
    210   # build all the plots 
    211   from numpy import inf, e 
    212   scale = e**(scale - 1.0) 
    213   for v in range(len(steps)): 
    214     if len(steps[v]) > 1: qp = float(max(steps[v])) 
    215     else: qp = inf  
    216     for s in steps[v]: 
    217       # dot color determined by number of simultaneous iterations 
    218       t = str((s/qp)**scale) 
    219       for i in eval("[params[q][%s] for q in xyz[0]]" % s): 
    220         for j in eval("[params[q][%s] for q in xyz[1]]" % s): 
    221           for k in eval("[params[q][%s] for q in xyz[2]]" % s): 
    222             a[v].plot(i,j,k,marker='o',color=t,ms=10) 
    223  
    224   plt.show() 
    22518 
    22619# EOF 
Note: See TracChangeset for help on using the changeset viewer.