import numpy
import numpy.linalg as la
from Lasso.Lasso import *
import math
# Graph is a part of Gato which could be installed as a module
try:
    import Graph
except ImportError:
    import Gato.Graph as Graph

import copy
#from GraphUtil import SaveCATBoxGraph
import random
import copy

small_value = 1e-100

def log2(x):
    
    try:
      res = numpy.zeros((len(x),len(x[0])),float)
      xs = len(x[0])
    except:
      res = numpy.zeros((len(x),1),float)
      xs = 1
    for i in range(len(x)):
        for j in range(1):
            try:
             res[i,j] = math.log(x[i,j],2)
            except OverflowError:
                print x[i,j]
    return res

def tableToString(table):
    saux = "------"
    s= '     |'
    for j in range(len(table[0])):
        s += "%12d" % (j+1)
        saux+="------------"
    s += " \n"+saux

    for i in range(len(table)):
        if numpy.sum(table[i]) != 0:
           s += "\n%5d |" % (i+1)
           for j in range(len(table[i])):
            s += ("%.5f" % (table[i][j])).rjust(12)

    return s

def inverseOld(x,y):
    x = numpy.array(x)
    y = numpy.array(y)
    s = numpy.dot(numpy.transpose(y),numpy.transpose(la.generalized_inverse(x)))
    #s = numpy.dot(transpose(y),transpose(la.pinv(x)))

    #print s
    
    s = maxPosteriorMixture(numpy.transpose(s))

    #getting the joining partition from s
    part = []
    for i in range(len(s[0])):
        part.append([])
        for j in range(len(s)):
            if( s[j,i] == 1.0):
               part[i].append(j)
                 

    z = numpy.dot(x,s)
    return z,s, part

def leastSquaresError(x,y,w):
    #print len(x), len(x[0])
    #print len(w), len(w[0])
    yhat = numpy.dot(x,w) # getting estimate y^hat of y
    serror = numpy.sum(numpy.power(numpy.subtract(yhat,y),2)) # square error of the estimate
    return yhat, serror

def leastSquares(x,y,shrink_type=0,select=0):    
    ''' shrink_type = 0 normal least squares
        shrink_type = 1 ridge
        shrink_type = 2 lasso
    '''
    
    L = len(x[0])
    print x
    print y

    #print len(x), len(x[0])
    #print len(y), len(y[0])

    # if no selection, accept all
    if select == 0:
        select = len(x[0])

    if shrink_type == 2: #lasso
        #xaux = normColums(x)
        w = Lasso(y,x,select)
        w = numpy.transpose(w)
    else:
      x = numpy.array(x != 0,numpy.float)  
      xx = numpy.dot(numpy.transpose(x),x)
      #print len(xx), len(xx[0])
      #print len(y), len(y[0]), len(x), len(x[0])
      yx = numpy.dot(numpy.transpose(y),x)
      #print len(yx), len(yx[0])
      # ridge selection
      if shrink_type == 1: # setting the ridge factor
        ridge=1
      else:
        ridge=0
      penalty = ridge*numpy.identity(len(x[0]))#*numpy.sum(x,0)/numpy.sum(numpy.sum(x,0))
      #xx1 = la.generalized_inverse(xx + penalty)
      xx1 = la.pinv(xx + penalty)                
      w = numpy.dot(yx,xx1) # W = YX/(XX -r*I)
      w = numpy.maximum(w,0) # W =|W|^+, so that w >= 0

    # filtering the w's with low value
    if shrink_type ==2: #lasso
        w = w * (w>0.00001) # getting ride of low w's
    elif shrink_type == 1:     
      wsum = [(j,i) for i,j in enumerate(numpy.sum(w,0))]
      wsum.sort() # making a list of highests sum(w)
      # zeroing the last L - select ones
      for i in range(L-select):
        w[:,wsum[i][1]]=0
    w = numpy.transpose(w)
    return w

def leastSquaresWithFilter(x,y,w):
    filtered = numpy.nonzero(numpy.sum(w,1) == 0)
    nonfiltered = numpy.nonzero(numpy.sum(w,1) != 0)
    xf = numpy.transpose(numpy.take(numpy.transpose(x),nonfiltered,0)[0])
    wf = numpy.take(w,nonfiltered,0)[0]
    #print xf, wf, nonfiltered
    xf = normRows(xf)
    wf = normRows(wf)
    #print xf, wf
    return xf, wf, filtered, leastSquaresError(xf,y,wf)
               

def normRows(mat):
    res =  numpy.transpose(numpy.transpose(mat)/numpy.sum(mat,1))
    for i,j in enumerate(numpy.sum(mat,1)):
        if j == 0:
            res[i,:] = 0
    return res

def normColums(mat):
    return mat/numpy.sum(mat,0)



def join(x,i,j):

    dim = len(x[0])
    size = len(x)

    res = numpy.zeros((size,dim-1),float)

    mask = array(range(dim))
    mask[j] = i
    mask[j+1:] = mask[j+1:] -1

    #print mask

    for e in range(size):
        for l in range(dim):
            res[e,mask[l]] += x[e,l]

    return res
    
    
def greedJoining(x,y):
    dimx = len(x[0])
    dimy = len(y[0])
    odimx = dimx
    n = len(x)

    #print dimx, dimy

    xorig = x.copy()

    # gambi para evitar zeros!
    x = x + small_value

    queue = []

    cRE = GQLValidation.mutualInfo(x,y)

    #print cRE
    #print dimx,dimy

    entrMin = 0

    unions = []

    gain = numpy.zeros((dimx,dimx),float)
    gain[:,:] = -9999.99
    #gain2 = numpy.zeros((dimx,dimx),float)
    #relEntropy(:,:) = 9999.9999

    # getting the first entropy gain values

    actualEntropy = GQLValidation.mutualInfoTerms(x,y)

    for i in range(dimx-1):
        #print "oi",  numpy.transpose(numpy.resize(x[:,i],(dimx-i-1,n)))
        xsum = x[:,i+1:dimx] + numpy.transpose(numpy.resize(x[:,i],(dimx-i-1,n)))
        newEntropy = GQLValidation.mutualInfoTerms(xsum,y)
        for j in range(i+1,dimx):
                #print i, j
                #z = join(x,i,j)
                #print "rel", GQLValidation..mutualInfo(z,y)
                #z = x[:,i] + x[:,j]
                #zant = [x[:,i], x[:,j]]
                #print numpy.transpose([z])
                #gain2[i,j] = actualEntropy[i] + actualEntropy[j] - GQLValidation..mutualInfo(numpy.transpose([z]),y)
                gain[i,j] = (actualEntropy[i] + actualEntropy[j] - newEntropy[j-i-1])


    #fileTable = open("debug.txt","a")
    #print >> fileTable, tableToString(gain)
    #print gain

    while dimx > dimy:

        # geting the minimal values and comparing with

        (im,jm) = argmax2d(gain)
        print "max", im,jm, gain[im,jm]
        x[:,im] =  x[:,im] + x[:,jm]
        x[:,jm] =  numpy.zeros(n,float)

        actualEntropy[im] = GQLValidation.mutualInfoTerms(numpy.transpose([x[:,im]]),y)[0]

        xsum = x[:,im+1:odimx] + numpy.transpose(numpy.resize(x[:,im],(odimx-im-1,n)))
        newEntropy = GQLValidation.mutualInfoTerms(xsum,y)

        #update the gain matrix
        gain[:,jm] = -9999.99
        gain[jm,:] = -9999.99

        for j in range(im+1,odimx):
            if (gain[im,j] != -9999.99): # test if the variable was not already excluded
                #z = x[:,im] + x[:,j]
                #zant = [x[:,im], x[:,j]]
                #print numpy.transpose([z])
                #gain[im,j] = mutualInfo(numpy.transpose(zant),y) - mutualInfo(numpy.transpose([z]),y)
                gain[im,j] = (actualEntropy[im] + actualEntropy[j] - newEntropy[j-im-1])


        unions.append((jm,im))
        dimx = dimx - 1
        #print "juntou", im,jm, dimx, dimy
        #print gain

        #print >> fileTable, tableToString(gain)

    print "acabou!"

    unions.sort()
    #print unions
    size = len(unions)

    #fileTable = open("debug.txt","a")
    part = partitionFromJoinList(unions,odimx)
    #print >> fileTable, part
    #print gain

    #print unions
    return matrixFromPartition(xorig,part),entrMin,part

def partitionFromJoinList(list,size):
    partition = []
    for i in range(size):
        partition.append([i])

    list.reverse()

    for (i,j) in list:
        #print i,j,partition
        partition[j] = partition[j]+partition[i]
        partition[i] = []

    res = []
    for e in partition:
        if e !=[]:
            res.append(e)
    #print len(res), res
    return res

def greedJoiningDag(x,y,dag,terms,filter=0):
    dimx = len(x[0])
    dimy = len(y[0])
    odimx = dimx
    N = len(x)
    print 'aqui'
    print dimx, dimy
    factor = 0.0

    xorig = x.copy()


    # avoiding zero values for log operations
    x = x + small_value

    queue = []

    cRE = GQLValidation.mutualInfo(x,y)

    entrMin = 0
    unions = []

    # initializing gain matrix
    gain = numpy.zeros((dimx,dimx),float)
    gain[:,:] = -9999.99

    # getting the first entropy gain values
    actualEntropy = GQLValidation.mutualInfoTerms(x,y)

    #print terms
    # making goterm count matrix collumn map
    map = {}
    mapI = {}
    mapParents = {}
    for i,t in enumerate(terms):
        map[t] = i
        mapI[i] = [t]
        parents =  dag.getParent(t)
        mapParents[i]= set(parents)

    origMap = copy.copy(map)

    # geting the leafs of the graph    
    currentNodes = dag.getLeaves()

    changeTrack = numpy.zeros(dimx,int)

    #print 'leaves', len(currentNodes)

    mask = numpy.zeros(dimx)
    inres =  numpy.zeros(dimx,int)

    for i, n in enumerate(currentNodes):
        try:
          i = map[n.goId]
        except KeyError:
          break
        inres[i]=1

    for i, n in enumerate(currentNodes):
        try:
          i = map[n.goId]
        except KeyError:
          break  # leave not part of annotation
        parents = mapParents[i]
        iparents = []
        for p in parents:
            iparents.append(map[p])
        # check

        xsum = numpy.minimum(x[:,iparents] + numpy.transpose(numpy.resize(x[:,i],(len(iparents),N))),[1])
        #print iparents
        #print 'before', n.goId, len(xsum[0]), len(y)
        newEntropy = GQLValidation.mutualInfoTerms(xsum,y)
        mask[i]=1
        for k,j in enumerate(iparents):
            if inres[j]:
              gain[i,j] = (actualEntropy[i] + actualEntropy[j] - newEntropy[k])
            else:
              gain[i,j] = (actualEntropy[i] - newEntropy[k])            
            #print n.goId, mapI[j] , newEntropy, gain[i,j]

    #fileTable = open("debug.txt","a")
    #print >> fileTable, tableToString(gain)
    #print gain
    #print mapParents

    #print numpy.nonzero(mask)[0]
    oldEntropy = sum(actualEntropy[numpy.nonzero(mask)[0]])/len(currentNodes)
    
    while dimx > dimy :
        
        # geting the minimal values and comparing with

        (im,jm) = argmax2d(gain)
        #print "max", mapI[im],mapI[jm], gain[im,jm], actualEntropy[im], actualEntropy[jm], inres[im], inres[jm],  inres[im] & inres[jm]
        if gain[im,jm] < 0:
            break;
        
        #updating new group
        x[:,im] =   numpy.minimum(x[:,im]+x[:,jm],[1]) # doing a or in the groups
        #deleting old group
        #x[:,jm] =  numpy.zeros(N,float) # deleting old group
        x[:,jm] = 0
        inres[jm]=0
        inres[im]=1
        mask[jm]=0
        mask[im]=1

        # updating the groups of terms and mappings, and parents
        for t in mapI[jm]:
          map[t] = im
        mapI[im] = mapI[im] + mapI[jm]
        mapI[jm] = mapI[im]
        #print jm, mapI[jm], mapParents
        mapParents[im] = mapParents[im].union(mapParents[jm]) # merging the parents
        #print mapI[im],  mapParents[im]
        mapParents[im] = mapParents[im].difference(set(mapI[im])) # taking self references out
        #print  im, mapParents[im]
        mapParents[jm] = mapParents[im]

        #print 'new entropy', GQLValidation.mutualInfoTerms(numpy.transpose([x[:,im]]),y)
        actualEntropy[im] = GQLValidation.mutualInfoTerms(numpy.transpose([x[:,im]]),y)[0]

        parents =  mapParents[im]
        iparents = []
        for p in parents:
            iparents.append(map[p])            

        #update the gain matrix
        gain[:,jm] = -9999.99
        gain[jm,:] = -9999.99

        if len(iparents) > 0:          
          xsum = numpy.minimum(x[:,iparents] + numpy.transpose(numpy.resize(x[:,im],(len(iparents),N))),[1])
          #print iparents, xsum, y
          newEntropy = GQLValidation.mutualInfoTerms(xsum,y)

          for k,j in enumerate(iparents):            
            if inres[j]: #if was already in result, account for prior j cont.
              gain[im,j] = actualEntropy[im] + actualEntropy[j] - newEntropy[k]
            else:
              gain[im,j] = (actualEntropy[im] - newEntropy[k])
            #print n.goId, mapI[j] , newEntropy, gain[im,j]
              
        unions.append((jm,im))
        dimx = dimx - 1
        #print "juntou", im,jm, dimx, dimy
        #print gain

        newEntropy = sum(actualEntropy[numpy.nonzero(mask)[0]])/sum(mask)
        #print oldEntropy, ' > ', str(newEntropy)
        oldEntropy = newEntropy
        
        #print >> fileTable, tableToString(gain)

    print "acabou!"


    unions.sort()
    #print unions
    size = len(unions)

    # calculating the end entropy, to check terms with higher entropy
    # and relations of terms from x to groups in y
    (endEntropy,entropyMatrix) = GQLValidation.mutualInfoTerms(x,y,t=1)

    # getting ride of joined lines
    nz = numpy.nonzero(mask)[0]
    part = []
    newnz = []
    newnzleaves = []
    partleaves = []
    for i in nz:
        group = mapI[i]
        aux = []
        if  len(group) == 1:
            newnzleaves.append(i)
            for j in group:
              aux.append(origMap[j])
            partleaves.append(aux)
        elif bool(endEntropy[i] < - 0.01) & bool(len(group) > 1):
            for j in group:
              aux.append(origMap[j])
            part.append(aux)
            newnz.append(i)
    print 'newz', newnz
    if len(newnz) > 0:
      nz = newnz
      nzall = newnz+newnzleaves
    else: # keep old for random data
      nz = newnzleaves
      nzall = newnzleaves
      part = partleaves


    endEntropy = endEntropy[nzall]
    entropyMatrix = entropyMatrix[nz]
    
    #filter only the n highests entropies
    indices = [(i,j) for i,j in enumerate(endEntropy)]
    indices.sort()

    #print endEntropy
    #print entropyMatrix
    
    #if filter > 0:
    #  filtered = indices[:-filter]
    #  print filtered
    #  filtered = [i for (i,j) in filtered]
    #  print filtered

    #  newpart = []
    #  for i in filtered:
    #    newpart.append(part[i])
    #  part = newpart
    #  endEntropy = endEntropy[nz[filtered]]
    #  entropyMatrix = entropyMatrix[nz[filtered]]    
    
    #print >> fileTable, 'matrix', entropyMatrix, '\n\n'

    #print >> fileTable, 'assigment', numpy.argmax(entropyMatrix,axis=1), '\n\n'

    #print >> fileTable, 'mutual', endEntropy, '\n\n'
    
    assigm = numpy.argmax(entropyMatrix,axis=1)    
    
    return matrixFromPartition(xorig,part),assigm,-sum(endEntropy)/len(endEntropy),part

def partitionFromJoinList(list,size):
    partition = []
    for i in range(size):
        partition.append([i])

    list.reverse()

    for (i,j) in list:
        #print i,j,partition
        partition[j] = partition[j]+partition[i]
        partition[i] = []

    res = []
    for e in partition:
        if e !=[]:
            res.append(e)
    #print len(res), res
    return res

def matrixFromPartition(x,partition):
    dim = len(x[0])
    size = len(x)

    res = numpy.zeros((size,len(partition)),float)

    #print "antes", size,len(partition)
    #print len(res), len(res[0])

    for (i,p) in enumerate(partition):
        for e in p:
            res[:,i] = res[:,i] + x[:,e]
    #print len(res), len(res[0])

    #renormalizing matrix
    res = normRows(res)
    
    return res

##def maxFlowGraph(x,y):
##    ''' build a multiple source/destination graph from mixtures x and y
##    where len(x[0]) > len(y[0]) '''

##    g = Graph.Graph()
##    g.directed = 1
##    source = g.AddVertex()
##    sink =g.AddVertex() 
##    edges = g.edgeWeights[0]


##    n = len(x)

##    for i in range(n):
##        aux = g.AddVertex()
##        g.AddEdge(source,aux)
##        edges[(source,aux)] = 1.0
##        if i == 0:
##            firstX = aux

##    sum = []

##    for i in range(len(x[0])):
##        aux = g.AddVertex()
##        sum.append(0.0)
##        for j in range(n):
##            if x[j,i] != 0.0:                
##              g.AddEdge(firstX+j,aux)
##              edges[(firstX+j,aux)] = x[j,i]
##              sum[i] = sum[i] + x[j,i]
##        if i == 0:
##            firstCX = aux


##    for i in range(len(x[0])):
##        aux = g.AddVertex()
##        for j in range(len(y[0])):
##           g.AddEdge(firstCX+j,aux)
##           edges[(firstCX+j,aux)] = sun[i]
##        if i == 0:
##            firstCY = aux

##    for i in range(n):
##        aux = g.AddVertex()
##        for j in range(len(y[0])):
##            if y[i,j] != 0.0:                
##              g.AddEdge(firstCY+j,aux)
##              edges[(firstCY+j,aux)] = y[i,j]
##        g.AddEdge(aux,sink)
##        edges[(aux,sink)] = 1.0
##        if i == 0:
##            firstY = aux

##    file = open("/home/filho/graph_res.cat",'w')
##    SaveCATBoxGraph(g,file)
##    file.close()

##def argmax2d(m):
##    i = 0
##    j = 0
##    maxs = []
##    indices = []
##    for i in range(len(m)):
##        indices.append(numpy.argmax(m[i]))
##        maxs.append(max(m[i]))
##    #print maxs, indices
##    #print 'argmax', argmax(maxs),indices[numpy.argmax(maxs)]
##    return numpy.argmax(maxs),indices[numpy.argmax(maxs)]

def argmax2d(m):
    i = numpy.argmax(m,1)
    maxi = numpy.max(m,1)
    j = numpy.argmax(maxi)
    return j,i[j]


if __name__ == '__main__':

 x =[[0.5,  0,   0,  0,   0,     0, 0.0,  0.5],
     [0.1,  0.9, 0,  0,   0,     0, 0.0,  0.0],
     [0,    0,   0.8,0.0, 0,     0, 0.2,  0.0],
     [0,    0,   0.0,1.0, 0,     0, 0.0,  0.0],
     [0,    0,   0,  0,   1.0,   0, 0.0,  0.0],
     [0,    0,   0,  0,   0.5,   0, 0.0,  0.5],
     [0,    0,   0,  0,   0,   0.8, 0.2,  0.0],
     [0,    0,   0,  0,   0,   1.0, 0.0,  0.0]]

 x =[[0.5,  0,   0,  0,   0,     0, 0.0,  0.5],
     [0.1,  0.9, 0,  0,   0,     0, 0.0,  0.0],
     [0,    0,   0.5,0.0, 0,     0, 0.5,  0.0],
     [0,    0,   0.0,1.0, 0,     0, 0.0,  0.0],
     [0,    0,   0,  0,   1.0,   0, 0.0,  0.0],
     [0,    0,   0,  0,   0.5,   0, 0.0,  0.5],
     [0,    0,   0,  0,   0,   0.8, 0.2,  0.0],
     [0,    0,   0,  0,   0.1,   0.9, 0.0,  0.0]] 

 y = [[1, 0, 0],
      [1, 0, 0],
      [1, 0, 0],
      [0, 1, 0],
      [0, 1, 0],
      [0, 1, 0],
      [0, 0, 1],
      [0, 0, 1]]

 import GQLValidation
 p1 = [[0,1,2,8],[3,4,5],[6,7]]
 y =  GQLValidation.mixtureFromOverlappingartition(p1,9)

 p2 = [[0,1,2,8],[1,2],[3,4],[3,5],[6,7],[7],[0,4],[5,6,7],[0,1,2,3,4,5,6,7]]
 #p2 = [[0,1],[1,2],[2],[3,4],[3,5],[6,7],[7],[0,4],[5,6,7],[0,1,2,3,4,5,6,7]]
 #p2 = [[0],[1],[2],[3],[4],[5],[6],[7],[1,2],[4,5],[0,1,2,3,4,5,6,7]]
 x =  GQLValidation.mixtureFromOverlappingartition(p2,9)
 print p2

 print x
 print y
 
 x = numpy.array(x != 0,numpy.float)

 print greedJoining(x,y)
 
## x = array(x)
## y = array(y)

 from GO.GODag import *
## go = GODag()
## go.addTerm('GO_1','Term_1','bla','test') 
## go.addTerm('GO_2','Term_2','bla','test')
## go.addTerm('GO_3','Term_3','bla','test')
## go.addTerm('GO_4','Term_4','bla','test')
## go.addTerm('GO_5','Term_5','bla','test') 
## go.addTerm('GO_6','Term_6','bla','test')
## go.addTerm('GO_7','Term_7','bla','test')
## go.addTerm('GO_8','Term_8','bla','test')
## go.addTerm('GO_9','Term_9','bla','test')
## go.addTerm('GO_10','Term_10','bla','test')
## go.addRelation('GO_1','GO_2',1)
## go.addRelation('GO_1','GO_3',1)
## go.addRelation('GO_1','GO_4',1)
## go.addRelation('GO_1','GO_6',1)
## go.addRelation('GO_3','GO_7',1)
## go.addRelation('GO_4','GO_5',1) 
## go.addRelation('GO_6','GO_8',1)
## go.addRelation('GO_6','GO_9',1)
## go.addRelation('GO_8','GO_9',1)
## go.addRelation('GO_9','GO_10',1)
## root = go.terms['GO_1']
## go.setRoots([root])
 

## terms = ['GO_3','GO_7','GO_4','GO_5','GO_8','GO_9','GO_2','GO_6','GO_1']


 go = GODag()
 go.addTerm('GO_1','Term1','bla','test') 
 go.addTerm('GO_2','Term2','bla','test')
 go.addTerm('GO_3','Term3','bla','test')
 go.addTerm('GO_4','Term4','bla','test')
 go.addTerm('GO_5','Term5','bla','test') 
 go.addTerm('GO_6','Term6','bla','test')
 go.addTerm('GO_7','Term7','bla','test')
 go.addRelation('GO_1','GO_2',1)
 go.addRelation('GO_2','GO_3',1)
 go.addRelation('GO_2','GO_4',1)
 go.addRelation('GO_3','GO_5',1)
 go.addRelation('GO_4','GO_5',1)
 go.addRelation('GO_1','GO_6',1)
 go.addRelation('GO_6','GO_7',1)
 root = go.terms['GO_1']
 go.setRoots([root])
 

 terms = ['GO_1','GO_2','GO_3','GO_4','GO_5','GO_6','GO_7']
 goSub = go.getSubDag(terms)

 p1 = [[0,1,2,3,4,5,6,10],[7,8,9]]
 y =  GQLValidation.mixtureFromOverlappingartition(p1,11)

 #p2 = [[0,1,2,3,4,5,6,7,8,9,10],[0,1,2,3,4,5,6,7,10],[0,1,2],[6,7],[6],[6,7,8,9][6,7,8,9]]
 x = numpy.array([[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],
      [1,1,1,0,0,0,0],[1,1,1,1,1,1,1],[1,1,0,1,0,1,1],[1,0,0,0,0,1,1],[1,0,0,0,0,1,1],[1,1,0,0,0,0,0]],float)
 #x =  GQLValidation.mixtureFromOverlappingartition(p2,11)
 
 
 [a,b,c,d] = greedJoiningDag(x,y,goSub,terms)

 print 'matrix from partitions'
 print 'final entropy', b
 print 'partition', d
 print 'partition X cluster', numpy.argmax(c,axis=1)

 assigm =  numpy.argmax(c,axis=1)

 anotCounts = numpy.dot(numpy.transpose(y),x>0)
 print anotCounts 

 counts={}
 for i,j in enumerate(terms):
   counts[j] = '_'.join([str(z) for z in anotCounts[:,i]])

 print counts

 for c,i in enumerate(d):
     #goCopy = GODag()
     #graphCopy(goSub,goCopy)
     goterms = []
     for j in i:
         goterms.append(terms[j])
     goaux = goSub.getSubDagParents(copy.deepcopy(goterms))
     print goSub.Edges()
     print goterms
     goaux.toDotandSave('dag'+str(c)+'.png',highlight=[goterms],extra=counts)

 goSub = go.getSubDag(terms) 
 goSub.toDotandSave('dag.png',extra=counts)

 mut = GQLValidation.mutualInfoTerms(x,y)

 xaux = numpy.zeros((11,6),float)
 
 xaux[:,0] = numpy.minimum(x[:,2]+x[:,4],[1])
 xaux[:,1] = numpy.minimum(x[:,3]+x[:,4],[1])
 xaux[:,2] = numpy.minimum(x[:,2]+x[:,3]+x[:,4],[1])
 xaux[:,3] = numpy.minimum(x[:,1]+x[:,2]+x[:,4],[1])
 xaux[:,4] = numpy.minimum(x[:,2]+x[:,3]+x[:,1]+x[:,0],[1])
 xaux[:,5] = numpy.minimum(x[:,6]+x[:,0],[1])
 m =  GQLValidation.mutualInfoTerms(xaux,y)


 print mut
 
 print '3 e 5', m[0], mut[4],  m[0]-mut[4]
 print '4 e 5', m[1], mut[4], m[1]-mut[4]
 print '{3,5} e 4',  m[2], m[0], m[2]-m[0]
 print '{3,5} e 2', m[3], m[0], m[3]-m[0]
 print '{2,3,5} e 1',  m[4], m[4]-m[3]
 print '1 e {6,7}', m[5], m[5]-mut[6]

 print numpy.transpose(x)
 print numpy.transpose(xaux)
 


## w = leastSquares(x,y,0)
## (yhat, serror)  =  leastSquaresError(x,y,w)
  
## print 'w', w
## print 'yhat', yhat
## print 'serror', serror

## w = leastSquares(x,y,1,5)
## (yhat, serror)  =  leastSquaresError(x,y,w)
## print 'w', w
## print 'yhat', yhat
## print 'serror', serror
 
## (xf, wf, filtered, (yhat, serror)) = leastSquaresWithFilter(x,y,w)
## print 'w', wf
## print 'yhat', yhat
## print 'serror', serror
## print filtered

## w = leastSquares(x,y,2,1)
## (yhat, serror)  =  leastSquaresError(x,y,w)
## print 'w', w
## print 'yhat', yhat
## print 'serror', serror
 
## ( xf, wf, filtered, (yhat, serror)) = leastSquaresWithFilter(x,y,w)
## print 'w', wf
## print 'yhat', yhat
## print 'serror', serror
## print filtered
 
 

 

