def merge(CVlist1, CVlist2, ep, eh, epChild1, ehChild1, epChild2, \
          ehChild2, eventType):
    ''' Given two lists of CostVectors, returns a new list of CostVectors, each
        of which is the sum of a pair of vectors from the two given lists.'''
    global CVevents
    global CVallEvents
    global CandidateCVlist

    intersection = CONFIG.intersection
    if intersection:
        global CVseen
        global CVcommonEvents

    output = []
    for v in CVlist1:
        for w in CVlist2:
            if eventType == "cospeciation":
                newCV = CostVector(1, 0, 0, 0, 1) + v + w
            elif eventType == "duplication":
                newCV = CostVector(0, 1, 0, 0, 1) + v + w
            else:  # eventType == "switch":
                newCV = CostVector(0, 0, 1, 0, 1) + v + w
            keepnewCV = True
            for cv in CandidateCVlist:
                if cv < newCV:
                    keepnewCV = False
                    break

            if keepnewCV:
                output.append(newCV)
                vsoln = (epChild1, ehChild1) + v.toTupleCDSL()
                wsoln = (epChild2, ehChild2) + w.toTupleCDSL()
                if eventType == "switch":
                    eventType = "switch to " + str(ehChild2)
                nswe = (ep, eh, eventType) + newCV.toTupleCDSL()
                ns = (ep, eh) + newCV.toTupleCDSL()
                CVevents[nswe].add(nswe)
                CVevents[nswe] = CVevents[nswe].\
                                 union(CVallEvents[vsoln]).\
                                 union(CVallEvents[wsoln])
                CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe])

                if intersection:
                    key = newCV.toTupleCDSL()
                    if CVseen[key]:
                        CVcommonEvents[key] = CVcommonEvents[key].\
                                              intersection(CVevents[nswe])
                    else:
                        CVcommonEvents[key] = CVevents[nswe]
                        CVseen[key] = True
    return output
def merge(CVlist1, CVlist2, ep, eh, epChild1, ehChild1, epChild2, \
          ehChild2, eventType):
    ''' Given two lists of CostVectors, returns a new list of CostVectors, each
        of which is the sum of a pair of vectors from the two given lists.'''
    global CVevents
    global CVallEvents
    global CandidateCVlist

    intersection = CONFIG.intersection
    if intersection:
        global CVseen
        global CVcommonEvents
        
    output = []
    for v in CVlist1:
        for w in CVlist2:
            if eventType == "cospeciation":
                newCV = CostVector(1, 0, 0, 0, 1) + v + w
            elif eventType == "duplication":
                newCV = CostVector(0, 1, 0, 0, 1) + v + w
            else:   # eventType == "switch":
                newCV = CostVector(0, 0, 1, 0, 1) + v + w
            keepnewCV = True
            for cv in CandidateCVlist:
                if cv < newCV: 
                    keepnewCV = False
                    break
    
            if keepnewCV:
                output.append(newCV)
                vsoln = (epChild1, ehChild1) + v.toTupleCDSL()
                wsoln = (epChild2, ehChild2) + w.toTupleCDSL()
                if eventType == "switch": eventType = "switch to "+str(ehChild2)
                nswe = (ep, eh, eventType) + newCV.toTupleCDSL()
                ns = (ep, eh) + newCV.toTupleCDSL()
                CVevents[nswe].add(nswe)
                CVevents[nswe] = CVevents[nswe].\
                                 union(CVallEvents[vsoln]).\
                                 union(CVallEvents[wsoln])
                CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe])

                if intersection:
                    key = newCV.toTupleCDSL()
                    if CVseen[key]:
                        CVcommonEvents[key] = CVcommonEvents[key].\
                                              intersection(CVevents[nswe])
                    else:
                        CVcommonEvents[key] = CVevents[nswe]
                        CVseen[key] = True
    return output
def lossmerge(ep, eh, ehChild, CVlist):
    global CVevents
    global CVallEvents
    global CandidateCVlist

    intersection = CONFIG.intersection
    if intersection:
        global CVseen
        global CVcommonEvents

    output = []
    for v in CVlist:
        newCV = CostVector(0, 0, 0, 1, 1) + v
        keepnewCV = True
        for cv in CandidateCVlist:
            if cv < newCV:
                keepnewCV = False
                break

        if keepnewCV:
            output.append(newCV)
            vsoln = (ep, ehChild) + v.toTupleCDSL()
            nswe = (ep, eh, "loss " + str(ehChild)) + newCV.toTupleCDSL()
            ns = (ep, eh) + newCV.toTupleCDSL()
            CVevents[nswe].add(nswe)
            CVevents[nswe] = CVevents[nswe].union(CVallEvents[vsoln])
            CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe])

            if intersection:
                key = newCV.toTupleCDSL()
                if CVseen[key]:
                    CVcommonEvents[key] = CVcommonEvents[key].\
                                              intersection(CVevents[nswe])
                else:
                    CVcommonEvents[key] = CVevents[nswe]
                    CVseen[key] = True
    return output
def lossmerge(ep, eh, ehChild, CVlist):
    global CVevents
    global CVallEvents
    global CandidateCVlist

    intersection = CONFIG.intersection
    if intersection:
        global CVseen
        global CVcommonEvents
    
    output = []
    for v in CVlist:
        newCV = CostVector(0, 0, 0, 1, 1) + v
        keepnewCV = True
        for cv in CandidateCVlist:
            if cv < newCV: 
                keepnewCV = False
                break
    
        if keepnewCV:
            output.append(newCV)
            vsoln = (ep, ehChild) + v.toTupleCDSL()
            nswe = (ep, eh, "loss "+str(ehChild)) + newCV.toTupleCDSL()
            ns = (ep, eh) + newCV.toTupleCDSL()
            CVevents[nswe].add(nswe)
            CVevents[nswe] = CVevents[nswe].union(CVallEvents[vsoln])
            CVallEvents[ns] = CVallEvents[ns].union(CVevents[nswe])

            if intersection:
                key = newCV.toTupleCDSL()
                if CVseen[key]:
                    CVcommonEvents[key] = CVcommonEvents[key].\
                                              intersection(CVevents[nswe])
                else:
                    CVcommonEvents[key] = CVevents[nswe]
                    CVseen[key] = True
    return output