function autoSmap(dataEmbed, t, vField, args = {}) {
args = {
zField: null,
tp: 1,
E: null,
theta: null,
nn: null,
...args
}
const {zField, tp, E, theta, nn} = args
const trainPoints = dataEmbed.filter(d => d.t < t - (tp - 1))
const nowRow = get(dataEmbed, t)
const dims = Array.from({length: E}, (_,i) => `${vField}_t-${i}`)
dims.push("point")
const tree = new kdTree.kdTree([...trainPoints], (a, b) => math.distance(a["point"], b["point"]), dims)
const neighbors = tree.nearest(nowRow, nn)
const meanDistance = d3.mean(neighbors, d => d[1])
let A = []
let b = []
for (const nearest of neighbors.map(d => d[0])) {
const dist = math.distance(nearest.point, nowRow.point)
const w = Math.exp(-theta * dist / meanDistance)
const p = nearest.point
A.push(math.multiply(w, [1].concat(p)))
b.push(w * get(dataEmbed, nearest.t + tp)[vField])
}
const C = leastSquares(A, b)
const yh = math.multiply([[1].concat(get(dataEmbed, t).point)], math.transpose([C]))[0][0]
return {
baseT: t,
baseVal: nowRow[vField],
t: t + tp,
pred: yh,
neighbors: neighbors,
params: {E: E, theta: theta, nn: nn}
}
}