Y_costs = {
let iters = 0
const costs = [];
const Y_new = initialize_points({n: num_points, dim: map_dims}),
Y_step = initialize_points({n:num_points, dim: map_dims, fill:0}),
Y_gains = initialize_points({n: num_points, dim: map_dims, fill: 1});
let average_y = make_array(map_dims);
while(iters < num_itterations){
iters++
average_y = average_y.map(() => 0)
let {cost, grad} = calc_cost_grad(Y_new, iters),
momentum = momentums[iters > momentum_switch ? 1: 0],
grad_id,
step_id,
gain_id,
gain_id_new,
step_id_new;
costs.push(cost);
for(let i=0; i<num_points; i++){
for(let d=0; d<map_dims; d++){
grad_id = grad[i][d];
step_id = Y_step[i][d];
gain_id = Y_gains[i][d];
gain_id_new = max(
sign(gain_id) === sign(step_id) ?
gain_id * gain_scales_same:
gain_id + gain_scales_diff,
gain_clamp
)
Y_gains[i][d] = gain_id_new;
step_id_new = momentum*step_id - learning_rate*gain_id_new*grad_id;
Y_step[i][d] = step_id_new
Y_new[i][d] += step_id_new;
average_y[d] += Y_new[i][d];
}
}
for(let i=0; i<num_points; i++){
for(let d=0; d<map_dims; d++){
Y_new[i][d] -= average_y[d]/num_points
}
}
if(iters % 5) yield {Y:Y_new, costs}
}
}