Exemplo n.º 1
0
 knn: function(points, queries, repeat) {
   //Use ndarray-select to partially sort elements
   var m = queries.length
   var d = points[0].length
   var n = points.length
   var sel = ndselect.compile([1,0], false, "float64")
   var pointArray = ndscratch.malloc([n, 2])
   var weight = 0
   var start = Date.now()
   for(var i=0; i<repeat; ++i) {
     for(var j=0; j<m; ++j) {
       var q = queries[j]
       var p = q[0]
       var k = q[1]
       for(var l=0; l<n; ++l) {
         var d2 = 0.0
         for(var a=0; a<d; ++a) {
           d2 += Math.pow(p[a] - points[l][a], 2)
         }
         pointArray.set(l, 0, d2)
         pointArray.set(l, 1, l)
       }
       sel(pointArray, k)
       for(var l=0; l<k; ++l) {
         weight += pointArray.get(l, 1)
       }
     }
   }
   var end = Date.now()
   ndscratch.free(pointArray)
   return [end-start, weight]
 },
Exemplo n.º 2
0
function createKDTree(points) {
  var n, d, indexed
  if(Array.isArray(points)) {
    n = points.length
    if(n === 0) {
      return new KDTree(null, null, 0, 0)
    }
    d = points[0].length
    indexed = ndarray(pool.mallocDouble(n*(d+1)), [n, d+1])
    pack(points, indexed.hi(n, d))
  } else {
    n = points.shape[0]
    d = points.shape[1]

    //Round up data type size
    var type = points.dtype
    if(type === "int8" ||
       type === "int16" ||
       type === "int32" ) {
      type = "int32"
    } else if(type === "uint8" ||
      type === "uint8_clamped" ||
      type === "buffer" ||
      type === "uint16" ||
      type === "uint32") {
      type = "uint32"
    } else if(type === "float32") {
      type = "float32"
    } else {
      type = "float64"
    }
    indexed = ndarray(pool.malloc(n*(d+1)), [n, d+1])
    ops.assign(indexed.hi(n,d), points)
  }
  for(var i=0; i<n; ++i) {
    indexed.set(i, d, i)
  }

  var pointArray = ndscratch.malloc([n, d], points.dtype)
  var indexArray = pool.mallocInt32(n)
  var pointer = 0
  var pointData = pointArray.data
  var arrayData = indexed.data
  var l2_n = bits.log2(bits.nextPow2(n))

  var sel_cmp = ndselect.compile(indexed.order, true, indexed.dtype)

  //Walk tree in level order
  var toVisit = [indexed]
  while(pointer < n) {
    var head = toVisit.shift()
    var array = head
    var nn = array.shape[0]|0
    
    //Find median
    if(nn > 1) {
      var k = bits.log2(pointer+1)%d
      var median
      var n_2 = inorderTree.root(nn)
      median = sel_cmp(array, n_2, function(a,b) {
        return a.get(k) - b.get(k)
      })

      //Copy into new array
      var pptr = pointArray.index(pointer, 0)
      var mptr = median.offset
      for(var i=0; i<d; ++i) {
        pointData[pptr++] = arrayData[mptr++]
      }
      indexArray[pointer] = arrayData[mptr]
      pointer += 1

      //Queue new items
      toVisit.push(array.hi(n_2))
      if(nn > 2) {
        toVisit.push(array.lo(n_2+1))
      }
    } else {
      //Copy into new array
      var mptr = array.offset
      var pptr = pointArray.index(pointer, 0)
      for(var i=0; i<d; ++i) {
        pointData[pptr+i] = arrayData[mptr++]
      }
      indexArray[pointer] = arrayData[mptr]
      pointer += 1
    }
  }

  //Release indexed
  pool.free(indexed.data)

  return new KDTree(pointArray, indexArray, n, d)
}