Exemple #1
0
def knnClassifier(train, test, k, kdtree=False, weight=naiveWeight):
    predictions = test
    probs = []
    kdTreeKnn = None
    kNeighbors = None
    kWeights = None
    if kdtree:
        kdTreeKnn = KdTree(train)

    for i in range(len(test)):
        for j in range(len(test[0])):
            predictions[i][j] = test[i][j]
        if kdtree:
            kdTreeKnn.knn(k, predictions[i])
            kNeighbors = kdTreeKnn.knnResults
            kWeights = kdTreeKnn.knnDistances
        else:
            kNeighbors, kWeights = knn_naive(k, train, predictions[i])

        kWeights = weight(kWeights)
        sumWeights = 0
        sumPred = 0
        for j in range(k):
            sumWeights += kWeights[j]
            sumPred += kWeights[j] * kNeighbors[j][-1]

        predictions[i][-1] = round(sumPred / sumWeights)
        probs.append(list(predictions[i]))
        probs[i][-1] = sumPred / sumWeights
    return (predictions, probs)
    def test_is_fully_contained(self):
        """Test if all the leafs of a region is being returned"""

        region_x_1 = [None, None]
        region_y_1 = [None, None]
        self.assertFalse(
            KdTree._is_fully_contained(self.kd_tree_even, region_x_1,
                                       region_y_1, self.query_x, self.query_y))

        region_x_2 = [2, 3]
        region_y_2 = [2, None]
        self.assertFalse(
            KdTree._is_fully_contained(self.kd_tree_even, region_x_2,
                                       region_y_2, self.query_x, self.query_y))

        region_x_3 = [2, 3]
        region_y_3 = [2, 5]
        self.assertFalse(
            KdTree._is_fully_contained(self.kd_tree_even, region_x_3,
                                       region_y_3, self.query_x, self.query_y))

        region_x_4 = [2, 3]
        region_y_4 = [2, 3]
        self.assertTrue(
            KdTree._is_fully_contained(self.kd_tree_even, region_x_4,
                                       region_y_4, self.query_x, self.query_y))
    def test_get_index_median(self):
        """Test if the median returned is correct"""

        # ODD CASE
        self.assertEqual(
            KdTree._get_index_median(self.kd_tree_odd, self.points_odd), 3)

        # EVEN CASE
        self.assertEqual(
            KdTree._get_index_median(self.kd_tree_even, self.points_even), 2)
    def test_sort_points(self):
        """Test if the sorted list is like expected"""

        # ODD CASE
        result_odd_x, result_odd_y = KdTree._sort_points(
            self.kd_tree_odd, self.points_odd)
        self.assertListEqual(self.points_odd_sorted_x, result_odd_x)
        self.assertListEqual(self.points_odd_sorted_y, result_odd_y)

        # EVEN CASE
        result_even_sorted_x, result_even_sorted_y = KdTree._sort_points(
            self.kd_tree_even, self.points_even)
        self.assertListEqual(self.points_even_sorted_x, result_even_sorted_x)
        self.assertListEqual(self.points_even_sorted_y, result_even_sorted_y)
class NearestNeighbor:

    def train(self, X, y):
        self.tree = KdTree(X, y)
        self.X = X
        self.y = y
        
    def predict(self, X, k=5, method='tree'):
        count = 0
        yPredict = np.zeros(X.shape[0])    

        for i in range(X.shape[0]):
            if method == 'tree':
                values = self.tree.kNN(X[i], k)
                c = Counter([pair[0].value for pair in values]).most_common()                            
                yPredict[i] = c[0][0]
            else:
                a = np.abs(self.X - X[i])
                s = np.sum(a, axis=1)
                
                y_idxs = np.argsort(s)[:k]
                c = Counter(self.y[y_idxs]).most_common()
                yPredict[i] = c[0][0]
            
            count += 1
            print('{:}: {:,}/28,000'.format(yPredict[i], count))

        return yPredict
    def test_report_sub_tree(self):
        """Test if the points returned from a region are correct"""

        expected_tree = [[3, 1], [1, 2], [4, 5], [2, 6], [5, 7]]
        result = KdTree._report_sub_tree(self.kd_tree_even,
                                         self.node_level_1_1)

        self.assertListEqual(result, expected_tree)
Exemple #7
0
 def buildNodalTree(self, sNodes):
     log.info("---start buildNodalTree---")
     raise Exception('DEPRECATED...buildNodalTree in mapLoads.py')
     sys.stdout.flush()
     #print "type(aCentroids)=%s type(sCentroids)=%s" %(type(aCentroids), type(sCentroids))
     self.nodalTree = KdTree('node', sNodes, nClose=self.nCloseNodes)
     log.info("---finish buildNodalTree---")
     sys.stdout.flush()
Exemple #8
0
    def buildCentroidTree(self, sCentroids):
        """
        sCentroids - dict of structural centroids
        id:  element id
        """
        log.info("---start buildCentroidTree---")
        sys.stdout.flush()
        #print "type(aCentroids)=%s type(sCentroids)=%s" %(type(aCentroids), type(sCentroids))

        msg = 'Element '
        for (id,sCentroid) in sorted(iteritems(sCentroids)):
            msg += "%s " % id
        log.info(msg + '\n')

        self.centroidTree = KdTree('element', sCentroids, nClose=self.nCloseElements)
        log.info("---finish buildCentroidTree---")
        sys.stdout.flush()
    def test_build(self):
        """Test if we are building correctly the Kd-Tree"""

        kd_tree_generated_by_function = KdTree(self.points)
        kd_tree_generated_by_hand = self.kd_tree

        self.validate_node(kd_tree_generated_by_function.root_node,
                           kd_tree_generated_by_hand.root_node)
Exemple #10
0
def main():
    number_of_points = 1000
    points = generate_points(number_of_points)
    kd_tree = KdTree(points)

    # Query to search points
    query_x = [400, 500]
    query_y = [300, 400]
    region_x = [None, None]
    region_y = [None, None]

    search_result = kd_tree.search(query_x, query_y, region_x, region_y)
    print("The query:")
    print("X = [%d, %d]" % (query_x[0], query_x[1]))
    print("Y = [%d, %d]" % (query_y[0], query_y[1]))
    print("Returns:")
    print(search_result)
    print("######################################################################################################\n")
    def test_search(self):
        """Test if the search result is correct"""

        region_x_1 = [None, None]
        region_y_1 = [None, None]
        query_x_1 = [1, 6]
        query_y_1 = [1, 4]
        expected_result_1 = [[3, 1], [1, 2], [6, 3]]
        result_1 = KdTree.search(self.kd_tree, query_x_1, query_y_1,
                                 region_x_1, region_y_1)
        self.assertListEqual(result_1, expected_result_1)

        region_x_2 = [None, None]
        region_y_2 = [None, None]
        query_x_2 = [2, 8]
        query_y_2 = [4, 8]
        expected_result_2 = [[4, 5], [2, 6], [5, 7], [8, 4], [7, 8]]
        result_2 = KdTree.search(self.kd_tree, query_x_2, query_y_2,
                                 region_x_2, region_y_2)
        self.assertListEqual(result_2, expected_result_2)
Exemple #12
0
def group_tweets_by_state(tweets):
    """Return a dictionary that aggregates tweets by their nearest state center.

    The keys of the returned dictionary are state names, and the values are
    lists of tweets that appear closer to that state center than any other.

    tweets -- a sequence of tweet abstract data types

    >>> sf = make_tweet("welcome to san francisco", None, 38, -122)
    >>> ny = make_tweet("welcome to new york", None, 41, -74)
    >>> two_tweets_by_state = group_tweets_by_state([sf, ny])
    >>> len(two_tweets_by_state)
    2
    >>> california_tweets = two_tweets_by_state['CA']
    >>> len(california_tweets)
    1
    >>> tweet_string(california_tweets[0])
    '"welcome to san francisco" @ (38, -122)'
    """
    center_state_dict = {}
    centers = []

    for state, polygons in us_states.items():
        center = find_state_center(polygons)
        centers.append(center)
        center_state_dict[center] = state

    state_centers = KdTree(centers)
    tweets_by_state = {}

    for tweet in tweets:
        location = tweet_location(tweet)
        nearest_state_center = state_centers.nearest_neigbour(
            location).location
        nearest_state = center_state_dict[nearest_state_center]

        if nearest_state not in tweets_by_state:
            tweets_by_state[nearest_state] = []
        tweets_by_state[nearest_state].append(tweet)

    return tweets_by_state
    def test_has_intersection(self):
        """Test if a point has intersection with a query"""

        point_1 = 3
        query = [1, 3]
        self.assertFalse(
            KdTree._has_intersection(self.kd_tree_even, point_1, query))

        point_2 = 2
        query = [1, 3]
        self.assertTrue(
            KdTree._has_intersection(self.kd_tree_even, point_2, query))

        point_3 = 1
        query = [1, 3]
        self.assertTrue(
            KdTree._has_intersection(self.kd_tree_even, point_3, query))

        point_4 = 0
        query = [1, 3]
        self.assertFalse(
            KdTree._has_intersection(self.kd_tree_even, point_4, query))
    def test_split_points(self):
        """Test if the splitted list is like expected"""

        # ODD CASE CUT BY X ON THE SORTED Y LIST
        left_points_1 = [[3, -3], [1, 2], [2, 4], [-1, 5]]
        right_points_1 = [[6, 1]]
        result_left_points_odd_1, result_right_points_odd_1 = \
            KdTree._split_points(self.kd_tree_odd, self.points_odd_sorted_y, [3, -3], 0)

        self.assertListEqual(result_left_points_odd_1, left_points_1)
        self.assertListEqual(result_right_points_odd_1, right_points_1)

        # EVEN CASE CUT BY X ON THE SORTED Y LIST
        left_points_2 = [[1, 2], [2, 4], [-1, 5]]
        right_points_2 = [[3, -3]]
        result_left_points_even_1, result_right_points_even_1 = \
            KdTree._split_points(self.kd_tree_even, self.points_even_sorted_y, [2, 4], 0)

        self.assertListEqual(result_left_points_even_1, left_points_2)
        self.assertListEqual(result_right_points_even_1, right_points_2)

        # ODD CASE CUT BY Y ON THE SORTED X LIST
        left_points_3 = [[1, 2], [2, 4], [3, -3], [6, 1]]
        right_points_3 = [[-1, 5]]
        result_left_points_odd_2, result_right_points_odd_2 = \
            KdTree._split_points(self.kd_tree_odd, self.points_odd_sorted_x, [2, 4], 1)

        self.assertListEqual(result_left_points_odd_2, left_points_3)
        self.assertListEqual(result_right_points_odd_2, right_points_3)

        # EVEN CASE CUT BY Y ON THE SORTED X LIST
        left_points_4 = [[1, 2], [2, 4], [3, -3]]
        right_points_4 = [[-1, 5]]
        result_left_points_even_2, result_right_points_even_2 = \
            KdTree._split_points(self.kd_tree_even, self.points_even_sorted_x, [2, 4], 1)

        self.assertListEqual(result_left_points_even_2, left_points_4)
        self.assertListEqual(result_right_points_even_2, right_points_4)
    def test_is_valid_leaf(self):
        """Test if a node is a valid leaf"""

        node_1 = Node()
        node_1.point = [2, 4]
        node_2 = Node()
        node_2.point = [3, -3]
        node_3 = Node()
        node_3.point = [3, 4]
        node_4 = Node()
        node_4.point = [-1, 6]

        self.assertTrue(
            KdTree._is_valid_leaf(self.kd_tree_even, node_1, self.query_x,
                                  self.query_y))
        self.assertFalse(
            KdTree._is_valid_leaf(self.kd_tree_even, node_2, self.query_x,
                                  self.query_y))
        self.assertTrue(
            KdTree._is_valid_leaf(self.kd_tree_even, node_3, self.query_x,
                                  self.query_y))
        self.assertFalse(
            KdTree._is_valid_leaf(self.kd_tree_even, node_4, self.query_x,
                                  self.query_y))
Exemple #16
0
class LoadMapping(object):
    def __init__(self, aeroModel, structuralModel, configpath='', workpath=''):
        self.nCloseElements = 30

        self.configpath = configpath
        self.workpath = workpath
        self.aeroModel = aeroModel
        self.structuralModel = structuralModel

        self.mappingMatrix = {}
        self.mapfile = 'mapfile.in'
        self.bdffile = 'fem.bdf'

        self.Sref = 1582876. # inches
        self.Lref = 623.  # inch
        self.xref = 268.

    #@entryExit
    def setOutput(self,bdffile='fem.bdf', loadCase=1):
        self.bdffile = bdffile
        self.loadCase = loadCase

    #@entryExit
    def set_flight_condition(self, pInf=499.3, qInf=237.885):
        self.pInf = pInf
        self.qInf = qInf  #1.4/2.*pInf*Mach**2.

    #@entryExit
    def loadMappingMatrix(self):
        infile = open(self.mapfile,'r')
        self.mappingMatrix = cPickle.loads(infile)
        infile.close()

    #@entryExit
    def save_mapping_matrix(self):
        outString = cPickle.dumps(self.mappingMatrix)
        outfile = open(self.mapfile, 'wb')
        outfile.write(outString)
        outfile.close()

    #@entryExit
    def getPressure(self, Cp):
        """
        Caculates the pressure based on:
           Cp = (p-pInf)/qInf
        """
        p = Cp * self.qInf + self.pInf
        #p = Cp*self.qInf # TODO:  for surface with atmospheric pressure inside
        return p

    #@entryExit
    def mapLoads(self):
        """
        Loops thru the unitLoad mappingMatrix and multiplies by the
        total force F on each panel to calculate the PLOAD that will be
        printed to the output file.
        Also, performs a sum of Forces & Moments to verify the aero loads.
        """
        log.info("---starting mapLoads---")
        self.bdf = open(self.bdffile, 'wb')
        #self.buildMappingMatrix()
        log.info("self.loadCase = %s" % self.loadCase)
        self.loadCases = {self.loadCase:{}}

        #self.loadCases = {self.loadCase={}, }
        momentCenter = array([self.xref, 0., 0.])
        sumMoments = array([0., 0., 0.])
        sumForces  = array([0., 0., 0.])
        sys.stdout.flush()
        for aEID, distribution in iteritems(self.mappingMatrix):
            #print "aEID = ",aEID
            #print "***distribution = ", distribution
            sumLoad = 0.
            area   = self.aeroModel.Area(aEID)
            normal = self.aeroModel.Normal(aEID)
            Cp     = self.aeroModel.Cp(aEID)
            #print "Cp = ",Cp
            #print "area[%s]=%s" % (aEID, area)

            p = self.getPressure(Cp)
            centroid = self.aeroModel.Centroid(aEID)
            r = momentCenter - centroid
            F = area * p
            Fn = F * normal
            sumMoments += cross(r, Fn)
            sumForces  += Fn
            for sNID, percentLoad in sorted(iteritems(distribution)):
                sumLoad += percentLoad

                Fxyz = Fn * percentLoad  # negative sign is to be consistent with nastran
                self.addForce(sNID, Fxyz)

                #print("Fxyz = ",Fxyz)
                #print("type(structuralModel) = ", type(self.structuralModel))

                #comment = 'percentLoad=%.2f' % percentLoad
                #self.structuralModel.writeLoad(self.bdf, self.loadCase, sNID,
                #                               Fxyz[0], Fxyz[1], Fxyz[2], comment)

            #msg = '$ End of aEID=%s sumLoad=%s p=%s area=%s F=%s normal=%s\n' % (aEID, sumLoad, p, area, F, normal)
            #self.bdf.write(msg)

        self.writeLoads()  # short version of writing loads...
        self.bdf.close()

        log.info("pInf=%g [psi]; qInf= %g [psi]" % (self.pInf, self.qInf))
        log.info("sumForcesFEM  [lb]    = %s" % ListPrint(sumForces))
        log.info("sumMomentsFEM [lb-ft] = %s" % ListPrint(sumMoments/12.))  # divided by 12 to have moments in lb-ft

        Cf = sumForces /(self.Sref * self.qInf)
        log.info("Cf = %s" % ListPrint(Cf))

        Cm = sumMoments / (self.Sref * self.qInf * self.Lref)
        log.info("Cm = %s" % ListPrint(Cm*12.)) # multiply by 12 to nondimensionalize ???  maybe 144...

        #self.bdf.write('$***********\n')
        log.info("wrote loads to %r" % self.bdffile)
        log.info("---finished mapLoads---")

    #@entryExit
    def writeLoads(self):
        """writes the load in BDF format"""
        log.info("---starting writeLoads---")
        self.bdf.write('$ ***writeLoads***\n')
        self.bdf.write('$ nCloseElements=%s\n' % self.nCloseElements)
        for loadCase, loads in sorted(iteritems(self.loadCases)):
            log.info("  loadCase = %s" % loadCase)
            for (sNID, Fxyz) in sorted(iteritems(loads)):
                self.structuralModel.write_load(self.bdf, loadCase, sNID, *Fxyz)

        log.info("finished writeLoads---")

    def addForce(self, sNID, Fxyz):
        try:
            self.loadCases[self.loadCase][sNID] += Fxyz
        except KeyError:
            self.loadCases[self.loadCase][sNID] = Fxyz

    #@entryExit
    def buildCentroids(self, model, eids=None):
        centroids = {}
        if eids is None:
            eids = model.ElementIDs()
        for eid in eids:
            centroid = model.Centroid(eid)
            if centroid is not None:
                centroids[eid] = centroid
        return centroids

    #@entryExit
    def buildNodalTree(self, sNodes):
        log.info("---start buildNodalTree---")
        raise Exception('DEPRECATED...buildNodalTree in mapLoads.py')
        sys.stdout.flush()
        #print "type(aCentroids)=%s type(sCentroids)=%s" %(type(aCentroids), type(sCentroids))
        self.nodalTree = KdTree('node', sNodes, nClose=self.nCloseNodes)
        log.info("---finish buildNodalTree---")
        sys.stdout.flush()

    #@entryExit
    def buildCentroidTree(self, sCentroids):
        """
        sCentroids - dict of structural centroids
        id:  element id
        """
        log.info("---start buildCentroidTree---")
        sys.stdout.flush()
        #print "type(aCentroids)=%s type(sCentroids)=%s" %(type(aCentroids), type(sCentroids))

        msg = 'Element '
        for (id,sCentroid) in sorted(iteritems(sCentroids)):
            msg += "%s " % id
        log.info(msg + '\n')

        self.centroidTree = KdTree('element', sCentroids, nClose=self.nCloseElements)
        log.info("---finish buildCentroidTree---")
        sys.stdout.flush()

    #@entryExit
    def parseMapFile(self, mapFilename='mappingMatrix.new.out'):
        """
        This is used for rerunning an analysis quickly (cuts out building the mapping matrix ~1.5 hours).
        1 {8131: 0.046604568185355716, etc...}
        """
        log.info("---starting parseMapFile---")
        mappingMatrix = {}

        log.info('loading mapFile=%r' % mapFilename)
        mapFile = open(mapFilename,'r')
        lines = mapFile.readlines()
        mapFile.close()

        for (i, line) in enumerate(lines[1:]):  # dont read the first line, thats a header line
            line = line.strip()
            #print "line = %r" % line
            (aEID, dictLine) = line.split('{') # splits the dictionary from the aEID
            aEID = int(aEID)
            #assert i == int(aEID)

            # time to parse a dictionary with no leading brace
            distribution = {}
            mapSline = dictLine.strip('{}, ').split(',')
            for pair in mapSline:
                (sEID, weight) = pair.strip(' ').split(':')
                sEID = int(sEID)
                weight = float(weight)
                distribution[sEID] = weight
            mappingMatrix[aEID] = distribution
        #log.info("mappingKeys = %s" %(sorted(mappingMatrix.keys())))
        self.runMapTest(mappingMatrix)
        log.info("---finished parseMapFile---")
        return mappingMatrix

    #@entryExit
    def runMapTest(self, mappingMatrix, mapTestFilename='mapTest.out'):
        """
        Checks to see what elements loads were mapped to.
        Ideally, all elements would have a value of 1.0, given equal area.
        Instead, each element should have a value of area[i].
        """
        mapTest = {}
        for (aEID, distribution) in sorted(iteritems(mappingMatrix)):
            for (sEID,weight) in distribution.items():
                if sEID in mapTest:
                    mapTest[sEID] += weight
                else:
                    mapTest[sEID] = weight

        mapOut = open(mapTestFilename, 'wb')
        mapOut.write('# sEID  weight\n')
        for sEID, weight in sorted(iteritems(mapTest)):
            mapOut.write("%s %s\n" % (sEID, weight))
        mapOut.close()

    def map_loads_mp_func(self, aEID, aModel):
        aElement = aModel.Element(aEID)
        (aArea, aCentroid, aNormal) = aModel.get_element_properties(aEID)
        percentDone = i / nAeroElements * 100

        pSource = aCentroid
        distribution = self.pierce_elements(aCentroid, aEID, pSource, aNormal)
        #distribution = self.poorMansMapping(aCentroid, aEID, pSource, aNormal)
        self.mappingMatrix[aEID] = distribution

    #@entryExit
    def build_mapping_matrix(self, debug=False):
        """
        Skips building the matrix if it already exists
        A mapping matrix translates element ID to loads on the nearby
        strucutral nodes.

        eid,distribution
        """
        if self.mappingMatrix != {}:
            return self.mappingMatrix

        log.info("---starting buildMappingMatrix---")
        #print "self.mappingMatrix = ",self.mappingMatrix
        if os.path.exists('mappingMatrix.new.out'):
            self.mappingMatrix = self.parseMapFile('mappingMatrix.new.out')
            log.info("---finished buildMappingMatrix based on mappingMatrix.new.out---")
            sys.stdout.flush()
            return self.mappingMatrix
        log.info("...couldn't find 'mappingMatrix.new.out' in %r, so going to make it..." % os.getcwd())

        # this is the else...
        log.info("creating...")
        aModel = self.aeroModel
        sModel = self.structuralModel

        #aNodes = aModel.getNodes()
        #sNodes = sModel.getNodes()
        #treeObj = Tree(nClose=5)
        #tree    = treeObj.buildTree(aNodes,sNodes) # fromNodes,toNodes

        aElementIDs  = aModel.ElementIDs() # list
        sElementIDs  = sModel.getElementIDsWithPIDs() # list
        sElementIDs2 = sModel.ElementIDs() # list

        msg = "there are no internal elements in the structural model?\n   ...len(sElementIDs)=%s len(sElementIDs2)=%s" % (len(sElementIDs), len(sElementIDs2))
        assert sElementIDs != sElementIDs2, msg
        log.info("maxAeroID=%s maxStructuralID=%s sElements=%s" % (max(aElementIDs), max(sElementIDs),len(sElementIDs2)))

        log.info("buildCentroids - structural")
        sCentroids = self.buildCentroids(sModel, sElementIDs)
        self.buildCentroidTree(sCentroids)
        #self.buildNodalTree(sNodes)

        log.info("buildCentroids - aero")
        aCentroids = self.buildCentroids(aModel)

        mapFile = open('mappingMatrix.out', 'wb')
        mapFile.write('# aEID distribution (sEID:  weight)\n')

        t0 = time()
        nAeroElements = float(len(aElementIDs))
        log.info("---start piercing---")
        if debug:
            log.info("nAeroElements = %s" % nAeroElements)
        tEst = 1.
        tLeft = 1.
        percent_done = 0.

        if 1:
            num_cpus = 4
            pool = mp.Pool(num_cpus)
            result = pool.imap(self.map_loads_mp_func, [(aEID, aModel) for aEID in aElementIDs ])

            for j, return_values in enumerate(result):
                aEID, distribution = return_values
                #self.mappingMatrix[aEID] = distribution
                mapFile.write('%s %s\n' % (aEID, distribution))
            pool.close()
            pool.join()
        else:
            for (i, aEID) in enumerate(aElementIDs):
                if i % 1000 == 0 and debug:
                    log.debug('  piercing %sth element' % i)
                    log.debug("tEst=%g minutes; tLeft=%g minutes; %.3f%% done" %(tEst, tLeft, percent_done))
                    sys.stdout.flush()

                aElement = aModel.Element(aEID)
                (aArea, aCentroid, aNormal) = aModel.get_element_properties(aEID)
                percentDone = i / nAeroElements * 100
                if debug:
                    log.info('aEID=%s percentDone=%.2f aElement=%s aArea=%s aCentroid=%s aNormal=%s' %(aEID,percentDone,aElement,aArea,aCentroid,aNormal))
                pSource = aCentroid
                (distribution) = self.pierce_elements(aCentroid, aEID, pSource, aNormal)
                #(distribution)  = self.poorMansMapping(aCentroid, aEID, pSource, aNormal)
                self.mappingMatrix[aEID] = distribution
                mapFile.write('%s %s\n' % (aEID, distribution))

                dt = (time() - t0) / 60.
                tEst = dt * nAeroElements / (i + 1)  # dtPerElement*nElements
                tLeft = tEst - dt
                percent_done = dt / tEst * 100.

        mapFile.close()
        log.info("---finish piercing---")
        self.runMapTest(self.mappingMatrix)
        #print "mappingMatrix = ", self.mappingMatrix
        log.info("---finished buildMappingMatrix---")
        sys.stdout.flush()
        return self.mappingMatrix

    def poor_mans_mapping(self, aCentroid, aEID, pSource, normal):
        """
        distributes load without piercing elements
        based on distance
        """
        (sElements, sDists) = self.centroidTree.getCloseElementIDs(aCentroid)
        log.debug("aCentroid = %s" % aCentroid)
        log.debug("sElements = %s" % sElements)
        log.debug("sDists    = %s" % ListPrint(sDists))

        setNodes = set([])
        sModel = self.structuralModel
        for sEID in sElements:
            sNodes = sModel.get_element_nodes(sEID)
            setNodes.union(set(sNodes))

        nIDs = list(setNodes)
        sNodes = sModel.getNodeIDLocations(nIDs)
        weights = self.get_weights(closePoint, sNodes)
        distribution = self.create_distribution(nIDs, weights)
        return distribution

    def pierce_elements(self, aCentroid, aEID, pSource, normal):
        """
        Pierces *1* element with a ray casted from the centroid/pSource
        in the direction of the normal vector of an aerodynamic triangle

         A  1
          \/ \
          / * \
         2---\-3
               \
                B

        *P = A+(B-A)*t
        """
        #direction = -1. # TODO: direction of normal...?
        (sElements, sDists) = self.centroidTree.getCloseElementIDs(aCentroid)
        log.info("aCentroid = %s" % aCentroid)
        log.info("sElements = %s" % sElements)
        log.info("sDists    = %s" % ListPrint(sDists))
        #(nearbySElements, nearbyDistances) = sElements
        piercedElements = []

        for sEID, sDist in zip(sElements, sDists):
            #print "aEID=%s sEID=%s" % (aEID, sEID)
            (sArea, sNormal, sCentroid) = self.structuralModel.get_element_properties(sEID)
            sNodes = self.structuralModel.get_element_nodes(sEID)
            nNodes = len(sNodes)

            pEnd = pSource + normal * 10.
            #pEnd2 = pSource - normal * 10.
            if nNodes == 3:  # TODO:  is this enough of a breakdown?
                (sA, sB, sC) = sNodes
                #pEnd = pSource+normal*10.
                tuv  = pierce_plane_vector(sA, sB, sC, pSource, pEnd, piercedElements)
                #tuv2= pierce_plane_vector(sA, sB, sC, pSource, pEnd2, piercedElements)
            elif nNodes == 4:
                (sA, sB, sC, sD) = sNodes
                tuv  = pierce_plane_vector(sA, sB, sC, pSource, pEnd,  piercedElements)
                #tuv2= pierce_plane_vector(sA, sB, sC, pSource, pEnd2, piercedElements)
                #self.pierceTriangle(sA, sB, sC, sCentroid, sNormal, piercedElements)
                #self.pierceTriangle(sA, sC, sD, sCentroid, sNormal, piercedElements)
            else:
                raise RuntimeError('invalid element; nNodes=%s' % nNodes)

            t1, u1, v1 = tuv
            #t2, u2, v2 = tuv2

            isInside = False
            #if self.isInside(u1, v1) or self.isInside(u2, v2):
            if self.is_inside(u1, v1):
                isInside = True
                #pIntersect = pSource + (pEnd - pSource) * t1
                pIntersect = pEnd * t1 +pSource * (1 - t1)
                #P = A + (B - A) * t
                tuv  = pierce_plane_vector(sA, sB, sC, pSource, pIntersect, piercedElements)
                #print "t,u,v=", tuv

                piercedElements.append([sEID, pIntersect, u1, v1, sDist])

            #t = min(t1, t2)
            #print "t1=%6.3g t2=%6.3g" % (t1, t2)
            #if isInside:
                #print "*t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %(sEID,t,u1,v1,u2,v2)
            #else:
                #print " t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %(sEID,t,u1,v1,u2,v2)

            #if isInside:
                #print "*t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %(sEID,t1,u1,v1,sDist)
            #else:
                #print " t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %(sEID,t1,u1,v1,sDist)

        log.info("avgDist = %g" % mean(sDists))
        (piercedElements, nPiercings) = self.fix_piercings(sElements, piercedElements)
        distribution = self.distribute_unit_load(aEID, piercedElements, nPiercings)

        return (distribution)

    def fix_piercings(self, sElements, piercedElements):
        if len(piercedElements) == 0:
            piercedElements = sElements
            #for sEID in sElements:
                #piercedElements.append([sEID, None])  # TODO: why a None?
            nPiercings = 0
        else:
            dists = []
            for element in piercedElements:
                log.info("element = %s" % element)
                dist = element[-1]
                log.info("dist = %s\n" % dist)
                dists.append(dist)
            iSort = argsort(dists)
            #print "iSort = ", iSort

            piercedElements2 = []
            for iElement in iSort:
                piercedElements2.append(piercedElements[iElement])
            #piercedElements = piercedElements[iSort]

            #for element in piercedElements:
                #print "element = ",element
                #print "dist = ",dist, '\n'

            nPiercings = len(piercedElements)
        return (piercedElements, nPiercings)

    def is_inside(self, u, v):
        if (0.<=u and u<=1.) and (0.<=v and v<=1.):
            return True
        return False

    def create_distribution(self, nIDs, weights):
        """
        Maps alist of structural nodes, and weights for a given aero element
        Takes the weights that are applied to a node and distributes them to the
        structural nodes
        """
        distribution = {}
        for nid,weight in zip(nIDs, weights):
            distribution[nid] = weight
        return distribution

    def get_weights(self, closePoint, nodes):
        # TODO: new weights?
        #(n1, n2, n3) = list(setNodes)
        #n = piercedPoint
        #(w1, w2, w3) = getTriangleWeights(n, n1, n2, n3)

        weights = shepard_weight(closePoint, nodes)
        return weights

    def distribute_unit_load(self, aEID, piercedElements, nPiercings):
        """
        distribute unit loads to nearby nodes
        piercedElements is a list of piercings
        piercing = [sEID,P,u,v] or [sEID]
        where
          sEID - the structural element ID
          P    - point p was pierced
          u    - u coordinate
          v    - v coordinate
        if nPiercings==0, all the nearby nodes will recieve load
        """
        aModel = self.aeroModel
        sModel = self.structuralModel
        #print("piercedElements = ", piercedElements)
        nIDs = []
        if nPiercings == 0:
            #assert len(nPiercings)==1,'fix me...'
            #print("nPiercings=0 distributing load to closest nodes...u=%g v=%g" %(-1,-1))
            log.debug("nPiercings=0 distributing load to closest nodes...")
            for sEID in piercedElements:
                nIDs += sModel.get_element_node_ids(sEID)
            #print "nIDs1 = ",nIDs
            nIDs = list(set(nIDs))
            log.debug("nIDs2 = %s" % nIDs)
            aCentroid = aModel.Centroid(aEID)
            nodes = sModel.getNodeIDLocations(nIDs)

            #print "nodes = ", nodes
            weights = self.get_weights(aCentroid, nodes)
            distribution = self.create_distribution(nIDs, weights)

            log.debug("element aEID=%s sEID=%s weights=%s" % (aEID, sEID, ListPrint(weights)))
            #print("distribution = ", distribution)
            #print("nIDs         = ", nIDs)
            #print("weights      = ", weights)
            #print("nodes = ", nodes)
            #print("nPiercings = ", nPiercings)
        else:
            log.info("mapping load to actual element...")
            nClose = 3  # number of elements to map to
            closeElements = piercedElements[:nClose]

            setCloseNodes = set([])
            for closeElement in reversed(closeElements):
                log.info("closeElement = %s" % closeElement)
                #sEID, pIntersect, u1, v1, sDist
                (sEID, P, u, v, sDist) = closeElement  # TODO:  bug here...???

                #closePoint = closeElement[1]
                #closeElement = sEID
                closePoint = P

                # get list of nearby structural nodes
                setElementNodes = set(sModel.get_element_node_ids(sEID))
                setCloseNodes = setCloseNodes.union(setElementNodes)

            # setup for weighted average
            nIDs = list(setCloseNodes)
            sNodes = sModel.getNodeIDLocations(nIDs)
            weights = self.get_weights(closePoint, sNodes)
            distribution = self.create_distribution(nIDs, weights)

            log.info("element aEID=%s sEID=%s weights=%s" %(aEID, sEID, ListPrint(weights)))
        log.info("-------------------------\n")
        sys.stdout.flush()
        return (distribution)

    def Normal(self, A, B, C):
        a = B - A
        b = C - A
        normal = Normal(a, b)
        return normal
 def train(self, X, y):
     self.tree = KdTree(X, y)
     self.X = X
     self.y = y
    def setUp(self):
        """This is called immediately before calling every test method"""

        # ODD CASE
        self.points_odd = [[2, 4], [-1, 5], [3, -3], [6, 1], [1, 2]]
        self.points_odd_sorted_x = [[-1, 5], [1, 2], [2, 4], [3, -3], [6, 1]]
        self.points_odd_sorted_y = [[3, -3], [6, 1], [1, 2], [2, 4], [-1, 5]]
        self.kd_tree_odd = KdTree(self.points_odd)

        # EVEN CASE
        self.points_even = [[2, 4], [-1, 5], [3, -3], [1, 2]]
        self.points_even_sorted_x = [[-1, 5], [1, 2], [2, 4], [3, -3]]
        self.points_even_sorted_y = [[3, -3], [1, 2], [2, 4], [-1, 5]]
        self.kd_tree_even = KdTree(self.points_even)

        # QUERY TO SEARCH IN THE KD-TREE
        self.query_x = [1, 3]
        self.query_y = [2, 4]

        # BUILDING A KD-TREE
        # LEVEL 4 KD_TREE
        self.node_level_4_1 = Node()
        self.node_level_4_1.type = NodeType.LEAF
        self.node_level_4_1.level = 4
        self.node_level_4_1.cut = None
        self.node_level_4_1.point = [3, 1]
        self.node_level_4_1.left_child = None
        self.node_level_4_1.right_child = None

        self.node_level_4_2 = Node()
        self.node_level_4_2.type = NodeType.LEAF
        self.node_level_4_2.level = 4
        self.node_level_4_2.cut = None
        self.node_level_4_2.point = [1, 2]
        self.node_level_4_2.left_child = None
        self.node_level_4_2.right_child = None

        # LEVEL 3 KD_TREE
        self.node_level_3_1 = Node()
        self.node_level_3_1.type = NodeType.INTERNAL
        self.node_level_3_1.level = 3
        self.node_level_3_1.cut = 1
        self.node_level_3_1.point = None
        self.node_level_3_1.left_child = self.node_level_4_1
        self.node_level_3_1.right_child = self.node_level_4_2

        self.node_level_3_2 = Node()
        self.node_level_3_2.type = NodeType.LEAF
        self.node_level_3_2.level = 3
        self.node_level_3_2.cut = None
        self.node_level_3_2.point = [4, 5]
        self.node_level_3_2.left_child = None
        self.node_level_3_2.right_child = None

        self.node_level_3_3 = Node()
        self.node_level_3_3.type = NodeType.LEAF
        self.node_level_3_3.level = 3
        self.node_level_3_3.cut = None
        self.node_level_3_3.point = [2, 6]
        self.node_level_3_3.left_child = None
        self.node_level_3_3.right_child = None

        self.node_level_3_4 = Node()
        self.node_level_3_4.type = NodeType.LEAF
        self.node_level_3_4.level = 3
        self.node_level_3_4.cut = None
        self.node_level_3_4.point = [5, 7]
        self.node_level_3_4.left_child = None
        self.node_level_3_4.right_child = None

        self.node_level_3_5 = Node()
        self.node_level_3_5.type = NodeType.LEAF
        self.node_level_3_5.level = 3
        self.node_level_3_5.cut = None
        self.node_level_3_5.point = [6, 3]
        self.node_level_3_5.left_child = None
        self.node_level_3_5.right_child = None

        self.node_level_3_6 = Node()
        self.node_level_3_6.type = NodeType.LEAF
        self.node_level_3_6.level = 3
        self.node_level_3_6.cut = None
        self.node_level_3_6.point = [8, 4]
        self.node_level_3_6.left_child = None
        self.node_level_3_6.right_child = None

        self.node_level_3_7 = Node()
        self.node_level_3_7.type = NodeType.LEAF
        self.node_level_3_7.level = 3
        self.node_level_3_7.cut = None
        self.node_level_3_7.point = [7, 8]
        self.node_level_3_7.left_child = None
        self.node_level_3_7.right_child = None

        self.node_level_3_8 = Node()
        self.node_level_3_8.type = NodeType.LEAF
        self.node_level_3_8.level = 3
        self.node_level_3_8.cut = None
        self.node_level_3_8.point = [9, 9]
        self.node_level_3_8.left_child = None
        self.node_level_3_8.right_child = None

        # LEVEL 2 KD_TREE
        self.node_level_2_1 = Node()
        self.node_level_2_1.type = NodeType.INTERNAL
        self.node_level_2_1.level = 2
        self.node_level_2_1.cut = 3
        self.node_level_2_1.point = None
        self.node_level_2_1.left_child = self.node_level_3_1
        self.node_level_2_1.right_child = self.node_level_3_2

        self.node_level_2_2 = Node()
        self.node_level_2_2.type = NodeType.INTERNAL
        self.node_level_2_2.level = 2
        self.node_level_2_2.cut = 2
        self.node_level_2_2.point = None
        self.node_level_2_2.left_child = self.node_level_3_3
        self.node_level_2_2.right_child = self.node_level_3_4

        self.node_level_2_3 = Node()
        self.node_level_2_3.type = NodeType.INTERNAL
        self.node_level_2_3.level = 2
        self.node_level_2_3.cut = 6
        self.node_level_2_3.point = None
        self.node_level_2_3.left_child = self.node_level_3_5
        self.node_level_2_3.right_child = self.node_level_3_6

        self.node_level_2_4 = Node()
        self.node_level_2_4.type = NodeType.INTERNAL
        self.node_level_2_4.level = 2
        self.node_level_2_4.cut = 7
        self.node_level_2_4.point = None
        self.node_level_2_4.left_child = self.node_level_3_7
        self.node_level_2_4.right_child = self.node_level_3_8

        # LEVEL 1 KD_TREE
        self.node_level_1_1 = Node()
        self.node_level_1_1.type = NodeType.INTERNAL
        self.node_level_1_1.level = 1
        self.node_level_1_1.cut = 5
        self.node_level_1_1.point = None
        self.node_level_1_1.left_child = self.node_level_2_1
        self.node_level_1_1.right_child = self.node_level_2_2

        self.node_level_1_2 = Node()
        self.node_level_1_2.type = NodeType.INTERNAL
        self.node_level_1_2.level = 1
        self.node_level_1_2.cut = 4
        self.node_level_1_2.point = None
        self.node_level_1_2.left_child = self.node_level_2_3
        self.node_level_1_2.right_child = self.node_level_2_4

        # LEVEL 0 KD_TREE
        self.root_node = Node()
        self.root_node.type = NodeType.INTERNAL
        self.root_node.level = 0
        self.root_node.cut = 5
        self.root_node.point = None
        self.root_node.left_child = self.node_level_1_1
        self.root_node.right_child = self.node_level_1_2

        self.points = [[1, 2], [2, 6], [3, 1], [4, 5], [5, 7], [6, 3], [7, 8],
                       [8, 4], [9, 9]]
        self.kd_tree = KdTree(self.points)
        self.kd_tree.root_node = self.root_node