def force_rank0 (funkslice): """Reduction function to reduce the polynomial rank of a set of funklets""" output = []; for funk in funkslice: c00 = funk.coeff if isinstance(funk.coeff,float) else funk.coeff.ravel()[0]; output.append(meq.polc(coeff=c00,domain=funk.domain)); return output;
def phase_parm(tdeg, fdeg): """helper function to create a t/f parm for phase, including constraints. Placeholder until Maaijke implements periodic constraints. """ polc = meq.polc(Timba.array.zeros((tdeg + 1, fdeg + 1)) * 0.0, scale=array([3600.0, 8e8, 0, 0, 0, 0, 0, 0])) shape = [tdeg + 1, fdeg + 1] # work out constraints on coefficients # maximum excursion in freq is pi/2 # max excursion in time is pi/2 dt = 0.2 df = 0.5 cmin = [] cmax = [] for it in range(tdeg + 1): for jf in range(fdeg + 1): mm = math.pi / (dt ** it * df ** jf) cmin.append(-mm) cmax.append(mm) cmin[0] = -1e9 cmax[0] = 1e9 return Meq.Parm( polc, shape=shape, real_polc=polc, node_groups="Parm", constrain_min=cmin, constrain_max=cmax, table_name=get_mep_table(), )
def linear_interpol (funkslice): """Reduction function to replace a set of funklets with piecewise linear interpolations. If the original N funklet c00 coefficients C0,C1,... are defined for domains [a0,b0] [a1,b1] ..., then the output N-1 funklets will be defined on domains [a0,(a1+b1)/2],[(a1+b1)/2,(a2+b2)/2],..., and will correspond to linear slopes passing through C0 at (a0+b0)/2, C1 at (a1+b1)/2, etc. """ # transform only available with more than two funklets if len(funkslice) < 2: return funkslice; if funkslice.rank > 1: raise TypeError,"linear interpolation only available for rank-1 slices"; iaxis0 = funkslice.slice_iaxes[0]; axis0 = funkslice.slice_axes[0]; output = []; for ifunk0,funk0 in enumerate(funkslice[:-1]): # funklet for next domain funk1 = funkslice[ifunk0+1]; dom0,dom1 = funk0.domain,funk1.domain; # centerpoint and c00 of ourselves x0 = sum(dom0[axis0])/2; c0 = funk0.coeff if isinstance(funk0.coeff,float) else funk0.coeff.ravel()[0]; # centerpoint and c00 of next domain x1 = sum(dom1[axis0])/2; c1 = funk1.coeff if isinstance(funk1.coeff,float) else funk1.coeff.ravel()[0]; # make output domain out_domain = copy.copy(dom0); # output domain boundaries are original subdomains' centers, with the exception of the first # and the last funklet, in which case the domain needs to extend to the edge of the first/last # subdomain a0 = dom0[axis0][0] if funk0 is funkslice[0] else x0; a1 = dom1[axis0][1] if funk1 is funkslice[-1] else x1; out_domain[axis0] = (a0,a1); # now make output polc output.append(meq.polc(coeff=[c0,c1-c0],domain=out_domain,offset=x0,scale=x1-x0,axis_index=iaxis0)) return output;
def phase_parm(tdeg, fdeg): """helper function to create a t/f parm for phase, including constraints. Placeholder until Maaijke implements periodic constraints. """ polc = meq.polc(Timba.array.zeros((tdeg + 1, fdeg + 1)) * 0.0, scale=array([3600., 8e+8, 0, 0, 0, 0, 0, 0])) shape = [tdeg + 1, fdeg + 1] # work out constraints on coefficients # maximum excursion in freq is pi/2 # max excursion in time is pi/2 dt = .2 df = .5 cmin = [] cmax = [] for it in range(tdeg + 1): for jf in range(fdeg + 1): mm = math.pi / (dt**it * df**jf) cmin.append(-mm) cmax.append(mm) cmin[0] = -1e+9 cmax[0] = 1e+9 return Meq.Parm(polc, shape=shape, real_polc=polc, node_groups='Parm', constrain_min=cmin, constrain_max=cmax, table_name=get_mep_table())
def _define_forest_1(ns, **kwargs): # constant side is a t+f thingy, # two parms: a const thingy with size-2 tiles # and a linear-n-freq thingy with size-3 tiles ns.c = Meq.Freq() + Meq.Time() ns.x = Meq.Parm(0, node_groups='Parm', tiling=record(time=2)) ns.y = Meq.Parm(meq.polc([0, 0]), node_groups='Parm', tiling=record(time=3)) ns.solver << Meq.Solver( num_iter=3, epsilon=1e-5, debug_level=10, solvable=["x", "y"], children=ns.condeq << Meq.Condeq(ns.x + ns.y, ns.c))
def make_node (self,node,station,**kw): ns = node.Subscope(); coeff = [random.uniform(self.min0,self.max0)*random.choice([-1,1])] for i in range(1,4): c = getattr(self,'max%d'%i); if c: coeff.append(random.uniform(-c,c)); scale = self.scale*3600; offset = self.offset*(3600*24); polc = meq.polc(coeff,scale=scale,offset=offset); ns.offset << Meq.Parm(polc); node << ns.offset*self.factor; if self.dump: file(self.dump,'a').write("%s %f %f %s\n"%(station,offset,scale, " ".join(["%f"%c for c in coeff]))); return node;
def make_node(self, node, station, axis, **kw): ns = node.Subscope() coeff = [random.uniform(self.min0, self.max0) * random.choice([-1, 1])] for i in range(1, 4): c = getattr(self, 'max%d' % i) if c: coeff.append(random.uniform(-c, c)) scale = self.scale * 3600 offset = self.offset * (3600 * 24) polc = meq.polc(coeff, scale=scale, offset=offset) ns.offset << Meq.Parm(polc) node << ns.offset * self.factor if self.dump: file(self.dump, 'a').write("%s %s %f %f %s\n" % (station, axis, offset, scale, " ".join( ["%f" % c for c in coeff]))) return node
def _define_forest_2(ns, **kwargs): # constant side is a t slope, plus a sine wave # two parms: c00 with tile size 2 (expecting to fit the slope in steps) # and 4-th degree polc in time with tile size 10 (expecting to fit the sine) # Fit should be on a 100x1 grid. ns.c = Meq.Time() * 5 + Meq.Sin(Meq.Time() * 6.28 * 7) # a bit more than one period over a tile ns.x = Meq.Parm([0, 0], node_groups='Parm', tiling=record(time=6)) ns.y = Meq.Parm(meq.polc([0, 0, 0, 0], shape=(4, 1)), node_groups='Parm', tiling=record(time=5)) ns.solver << Meq.Solver( num_iter=30, epsilon=1e-5, debug_level=10, solvable=["x", "y"], children=ns.condeq << Meq.Condeq(ns.x + ns.y, ns.c))
def change_parm(ns, node, new_value): # first delete old node #try: #if ns.__hasattr__(nodename): # #ns.__delattr__(nodename) # pass #gg=ns._repository.pop(nodename) #del gg #ns.Resolve() #except AttributeError: # print "WARNING: no node exists with name ",nodename # pass # now recreate a new node #work_str="ns['"+nodename+"']<<Meq.Parm(meq.polc("+str(new_value)+"))" #print work_str #exec work_str in globals(),locals() #print "trying to change params of ",node.name g = node.initrec() #print g g['init_funklet'] = meq.polc(new_value)
def change_parm(ns,node,new_value): # first delete old node #try: #if ns.__hasattr__(nodename): # #ns.__delattr__(nodename) # pass #gg=ns._repository.pop(nodename) #del gg #ns.Resolve() #except AttributeError: # print "WARNING: no node exists with name ",nodename # pass # now recreate a new node #work_str="ns['"+nodename+"']<<Meq.Parm(meq.polc("+str(new_value)+"))" #print work_str #exec work_str in globals(),locals() #print "trying to change params of ",node.name g=node.initrec() #print g g['init_funklet']=meq.polc(new_value)
def create_polc_ft(degree_f=0, degree_t=0, c00=0.0): polc = meq.polc(zeros((degree_t+1, degree_f+1))*0.0) polc.coeff[0,0] = c00 return polc
def create_polc(c00=0.0,deg_f=0,deg_t=0): """helper function to create a t/f polc with the given c00 coefficient, and with given order in t/f"""; polc = meq.polc(zeros((deg_t+1, deg_f+1))*0.0); polc.coeff[0,0] = c00; return polc;
# from Timba.TDL import * from Timba.Meq import meq from Timba.array import * import Meow def create_polc(c00=0.0,deg_f=0,deg_t=0): """helper function to create a t/f polc with the given c00 coefficient, and with given order in t/f"""; polc = meq.polc(zeros((deg_t+1, deg_f+1))*0.0); polc.coeff[0,0] = c00; return polc; # type of polc object POLC_TYPE = type(meq.polc(0)); def resolve_parameter (name,node,value,tags=[],solvable=True,solvables=None): """Helper function, resolves 'value' to a parameter-like node. 'name' is a parameter name (only used for error messages) 'node' is an uninitialized node stub 'value' specifies the parameter. (a) If value is numeric, creates a Meq.Constant() and binds it to 'node'. (b) If value is a node, returns it as-is. (c) If value is a Meow.Parm specification, creates a Meq.Parm(), and binds it to 'node'. If 'solvable' is True, create Meq.Parm will have a 'solvable' tag. 'solvables' may be None, or a list. If it is a list, then any solvable parameters will be appended to this list. In case (c) this is the created Parm (if solvable=True). In case (b) a search will be performed on the node to extract any solvable parameters. """ # make sure tags is a list, and add name