Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/ein16/synth/d2/obj_apply.py
ViewVC logotype

View of /branches/ein16/synth/d2/obj_apply.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3946 - (download) (as text) (annotate)
Sat Jun 11 00:39:19 2016 UTC (3 years, 2 months ago) by cchiw
File size: 12778 byte(s)
 added outer prod
import sys
import re
import os
from obj_ex import *
from obj_apply import *
from obj_ty import *
from obj_operator import *
from obj_field import *

class apply:
    def __init__(self, name, opr, lhs, rhs, oty, isrootlhs, isrootrhs):
        self.name=name
        self.opr=opr
        self.lhs=lhs
        self.rhs=rhs
        self.oty=oty
        self.isrootlhs=isrootlhs
        self.isrootrhs=isrootrhs
    def toStr(self, layer):
        if (self==None):
            return "None"
        s = (str(layer)+": opr:"+self.opr.name+" isrootlhs: "+str(self.isrootlhs)+" isrootrhs: "+str(self.isrootrhs)+" oty: "+str(self.oty.name))
        lhs = self.lhs
        rhs= self.rhs
        if(self.isrootlhs):
            if(lhs!=None):
                s+="\n"+str( layer)+"\tlhs:"+ field.toStr(lhs)
        else:
            s+= "\nnot a root: look to lhs"
            if (lhs!=None):
                s+="\n"+str( layer)+"lhs:"+apply.toStr(lhs, layer+1)
            else:
                s+="\n"+str( layer)+"lhs:None"
        if (self.isrootrhs):
            if(rhs!=None):
                s+="\n"+str( layer)+"\trhs:"+field.toStr(rhs)
        else:
            s+= "\nnot a root: look to rhs"
            if(rhs!=None):
                s+="\n"+str( layer)+"rhs:"+apply.toStr(rhs, layer+1)
            else:
                s+="\n"+str( layer)+"rhs:None"
        return s
    
    def checkDim(self):
        if (self.isroot):
            d1=self.lhs.fldty.ty.dim
            d2=self.rhs.fldty.ty.dim
            if (d1==d2):
                return d1
            else :
                raise "dimension is not the same"
        else :
            raise "not a root app"
    def get_arity(self):
        return self.opr.arity
    def get_unary(self):
        return self.lhs

    def get_binary(self):
        f=self.lhs
        g=self.rhs
        return (f,g)

    def get_types(self):
        #if (self.isroot):
        rtn=[]
        if(self.lhs!=None):
            rtn.append(self.lhs.fldty)
        if(self.rhs!=None):
            rtn.append(self.rhs.fldty)
        return rtn
            #else :
            #raise "not a root app"

    # single list
    def get_exps(self):
        rtn=[]
        if(self.lhs!=None):
            rtn.append(self.lhs)
        if(self.rhs!=None):
            rtn.append(self.rhs)
        return rtn


    def get_root_types(self):
        rtn=[]
        if (self.isroot):
            for i in [self.lhs, self.rhs]:
                rtn.append(i.fldty)
            return rtn
        else :
            for i in [self.lhs, self.rhs]:
                rtn=rtn+(apply.get_root_types(i))
            return rtn
    def get_root_app(self):
        if (self.isrootlhs):
            return self
        else :
            if(self.rhs== None):
                return (apply.get_root_app(self.lhs))
            else:
                raise "more expressions in root"

    def get_all_Fields(self):
        flds = []
        lhs = self.lhs
        rhs = self.rhs
        if (lhs!=None):
            if (self.isrootlhs):
                flds.append(lhs)
            else :
                flds = flds + apply.get_all_Fields(lhs)
        if (rhs!=None):
            if (self.isrootrhs):
                flds.append(rhs)
            else :
                flds = flds + apply.get_all_Fields(rhs)
        return flds

    def get_oty(self):
        return self.oty
#------------------------------ helpers -----------------------------------------------------
#field dimension is the same as vector length
def checkNd(ityp1):
    if(fty.is_Vector(ityp1)):
        n1 = fty.get_vecLength(ityp1)
        dim1 = fty.get_dim(ityp1)
        return (n1==dim1)
    else:
        return (false,"needs vector")

#type of field after operation is applied
def applyUnaryOp(op1,ityps):
    ityp1=ityps[0]
    if (op_probe==op1) or (op_negation==op1):
        return (true, ityp1) #type unaffected by operation
    elif (op_gradient==op1):
        if (fty.isEq_id(ityp1, ty_scalarF_d2)):
            k=ityp1.k
            name = ty_vec2F_d2
            return (true,fty.convertTy(name, k-1))
        elif (fty.isEq_id(ityp1, ty_scalarF_d3)):
            k=ityp1.k
            name = ty_vec3F_d3
            return(true, fty.convertTy(name, k-1))
        else:
            return (false, "wrong type for gradient operation")
    elif(op_divergence==op1):
        k=ityp1.k
        if(not checkNd(ityp1)):
            return(false, ("divergence not supported for this type", op1))
        if (fty.isEq_id(ityp1, ty_vec2F_d2)):
            k=ityp1.k
            name =  ty_scalarF_d2
            return (true,fty.convertTy(name, k-1))
        elif (fty.isEq_id(ityp1, ty_vec3F_d3)):
            k=ityp1.k
            name = ty_scalarF_d3
            return(true, fty.convertTy(name, k-1))
        else:
            return (false, "wrong type for divergence operation")
    elif(op_curl==op1):            # apply curl
        if(fty.is_Vector(ityp1)):
            n1 = fty.get_vecLength(ityp1)
            k=ityp1.k
            if(not checkNd(ityp1)):
                return(false, ("curl not supported for this type: "+ityp1.name))
            if((n1==2)):
                return (true,fty.convertTy(ty_scalarF_d2,k-1))
            elif(n1==3):
                return (true,fty.convertTy(ty_vec3F_d3,k-1))
        else:
            return(false, ("curl not supported for this type: "+ityp1.name))
    elif(op_jacob==op1):            # apply op_jacob
        if(fty.is_Vector(ityp1)):
            n1 = fty.get_vecLength(ityp1)
            k=ityp1.k
            if(not checkNd(ityp1)):
                return(false, ("jacob not supported for this type: "+ityp1.name))
            if((n1==2)):
                return (true,fty.convertTy(ty_mat2x2F_d2, k-1))
            elif(n1==3):
                return (true,fty.convertTy(ty_mat3x3F_d3, k-1))
        else:
            return (false, ("curl not supported for this type: "+ityp1.name))
    else:
        raise Exception("operation not represented in unary operations:"+op1.name)

#type of field after operation is applied
def applyBinaryOp(op1,ityps):
    # print "iypes:",len(ityps),"-", ityps

    ityp1=ityps[0]

    ityp2=ityps[1]
   
    #print "checking",op1.name,"-",ityp1.name,"-",ityp2.name
    (tf, fldty) = find_field(ityp1,ityp2) #assures same dimension for both fields

    if(not tf):
        return (false, "not the same dimension")

    k = fldty.k
    dim = fldty.dim

    if (op_add==op1) or (op_subtract==op1):
        if(ityp1.id==ityp2.id):
            return (true, ityp1) #type unaffected by operation
        else:
            return (false, "not the right shape")
    elif(op_scale==op1):

        if(fty.is_Scalar(ityp1) or fty.is_Scalar(ityp2)):
            shape1 = fty.get_shape(ityp1)
            shape2 = fty.get_shape(ityp2)
            rty1 = shapeToTy(shape1+shape2, dim)
            rtn2 = fty.convertTy(rty1, k)
            return (true, rtn2)
        else:
            return (false, "scaling applied to non scalar fields")
    elif(op_outer==op1):
        if(fty.is_Scalar(ityp1) or fty.is_Scalar(ityp2)):
            return  (false,  "outer product applied to scalar fields")
        shape1 = fty.get_shape(ityp1)
        shape2 = fty.get_shape(ityp2)
        beta = shape1+shape2
        if (len(beta)>3):
            return (false,"output to bigfor outer product"+ityp1.name+ityp2.name)
        n1 = fty.get_last_ix(ityp1)
        n2= fty.get_first_ix(ityp2)
        if(n1!=n2): #must have equal vector lengths
            return  (false, ("must have equal vector length:"+ityp1.name+ityp2.name))
        
        
        rty = shapeToTy(beta, dim)
        return (true, fty.convertTy(rty, k))
    elif(op_inner==op1):
        if(fty.is_Scalar(ityp1) or fty.is_Scalar(ityp2)):
            #print "ityp1:",ityp1, "ityp2:",ityp2
            return  (false,  "inner product applied to scalar fields")
        else:
            n1 = fty.get_last_ix(ityp1)
            n2= fty.get_first_ix(ityp2)
            if(n1!=n2): #must have equal vector lengths
                return  (false, ("must have equal vector length:"+ityp1.name+ityp2.name))
            shape1 = fty.drop_first(ityp1)
            shape2 = fty.drop_last(ityp2)
            rty = shapeToTy(shape1+shape2, dim)
            return (true, fty.convertTy(rty, k))
    elif(op_cross==op1):
        if(fty.is_Scalar(ityp1) or fty.is_Scalar(ityp2)):
            return  (false,  "cross product applied to scalar fields")
        if(fty.is_Vector(ityp1) and fty.is_Vector(ityp2)):
            n1 = fty.get_vecLength(ityp1)
            n2 = fty.get_vecLength(ityp2)
            # apply cross product
            if((n1==n2) and (n1==2)):
                return (true, fty.convertTy(ty_scalarF_d2,k))
            elif((n1==n2) and (n1==3)):
                return (true, fldty)
            else:
                return  (false, ("cross product needs to be applied to vectors of the same size", op1.name))
        return  (false, ("cross product needs to be applied to vectors", op1.name))
    else:
        raise Exception("operation not represented in binary operations"+ op1.name)


# create apply, operator and field objects
# from an example opr number, type number, and input file
#Apply to two field expressions
def mkApply_fld(name,opr,ishape, inputfile):
    arity=opr.arity
    # synthetic field-1
    #check that we have the right number of parameters
    k=2 #hardcoded for now
    index1=0
    ity1= ishape[index1]
    dim1  = fty.get_dim(ity1)
    if (arity==1): # unary operator
        (F, finfo1, coeff1) = mk_Field(index1, ishape, k, inputfile, dim1)
        (tf, otype) = applyUnaryOp(opr,[finfo1])
        if (tf==false):
            raise Exception(otype)
        z1 = apply(name, opr,F, None, otype, true, true)
        return (z1, [coeff1], dim1, otype)
    elif (arity==2): # binary operator
        index2=1
        ity2  = ishape[index2]
        dim2  = fty.get_dim(ity2)
        (F, finfo1, coeff1) = mk_Field(index1, ishape, k, inputfile, dim1)
        (G, finfo2, coeff2) = mk_Field(index2, ishape, k, inputfile, dim2)
        finfos= [finfo1, finfo2]
        #print "opr",opr.name,"finfos",len(finfos)
        (tf,otype) = applyBinaryOp(opr, finfos)
        if (tf==false):
            raise Exception(otype)
        z = apply(name, opr, F,G, otype,true, true)
        coeffs = [coeff1,coeff2]
        (_,fldty) = find_field(ity1, ity2) # dimension for field involved
        dimF= fldty.dim
        return (z, coeffs, dimF, otype)
    else:
        raise Exception ("arity is not supported: "+str(arity))

# embed inside a unary operator
def mkApply_opr(name, opr, lhs, rhs, otypes):
    arity=opr.arity
    if (arity==1): # unary operator
        otype1 = otypes[0]
        (tf, otypertn) = applyUnaryOp(opr, [otype1])
        if (tf==false):
            raise "can not apply unary operator"
        z2 = apply(name, opr,lhs, rhs, otypertn, false, true)
        return z2
    elif (arity==2): # binary operator
        otype1 = otypes[0]
        otype2 = otypes[1]
        (tf, otypertn) = applyBinaryOp(opr, [otype1,otype2])
        if (tf==false):
            raise "can not apply unary operator"
        z2 = apply(name, opr,lhs, rhs, otypertn, false, true)
        return z2
    else:
        raise Exception ("arity is not supported: "+str(arity))

def mkApply_twice(name,opr_inner,opr_outer, ishape, inputfile):
    arity=opr_outer.arity
    #print "mkapply twice"
    #print "ishape:",len(ishape),"-", ishape
    if (arity==1): # unary operator
        (z1, coeffs, dim1, otype1) =  mkApply_fld(name,opr_inner,ishape, inputfile)
        z2 = mkApply_opr(name, opr_outer, z1, None, [otype1])
        #apply.toStr(z1)
        #apply.toStr(z2)
        # print "coeff1",coeffs
        return (z2, coeffs, dim1)
    elif (arity==2): # binary operator
        # first is an application
        
        (z1, coeff1, dim1, otype1) =  mkApply_fld(name, opr_inner, ishape, inputfile)
        # second is just a field
        id = 2 # index of field exp
        ity2 =ishape[id]
        k = 2
        dim2  = fty.get_dim(ity2)

        (F2, finfo2, coeff2) = mk_Field(id, ishape, k, inputfile+"cat", dim2)
        #print "coeff2",coeff2
        #print "coeff1",len(coeff1),"-",coeff1
        #print "coeff1-a",ishape[0].name,"-",len(coeff1[0]),"-",coeff1[0]
        #print "coeff1-b",ishape[1].name,"-",len(coeff1[1]),"-",coeff1[1]
        #print "coeff2",ishape[2].name,"-",len(coeff2),"-",coeff2
        coeffs = coeff1+[coeff2]
        #print "coeffs",coeffs
        rhs = F2

        z2 = mkApply_opr(name,opr_outer, z1, rhs, [otype1, finfo2])
        #apply.toStr(z1)
        #apply.toStr(z2)

        return (z2, coeffs, dim1)
    else:
        raise Exception ("arity is not supported: "+str(arity))

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0