     // divide column by resulting vector
     Broadcast::broadcast_matrix_vector(pij, sums, K, N, thrust::divides<float>(), 1, 1.0f);
 }
+
+struct saxpy_functor : public thrust::binary_function<float,float,float>
+{
+    const float a;
+
+    saxpy_functor(float _a) : a(_a) {}
+    __host__ __device__
+        float operator()(const float& x, const float& y) const { 
+            return a * x + y;
+        }
+};
 
 thrust::device_vector<float> BHTSNE::tsne(cublasHandle_t &dense_handle, 
                                           cusparseHandle_t &sparse_handle,

      CudaTest("kernel 4 launch failed");

      cudaEventRecord(start, 0);
      ForceCalculationKernel<<<blocks * FACTOR5, THREADS5>>>(nnodes, nbodies, errl, dthf, itolsq, epssq, sortl, childl, massl, posxl, posyl, velxl, velyl, norml);
      cudaEventRecord(stop, 0);  cudaEventSynchronize(stop);  cudaEventElapsedTime(&time, start, stop);
      timing[5] += time;
      CudaTest("kernel 5 launch failed");

                                                          thrust::raw_pointer_cast(maxyl.data()), 
                                                          thrust::raw_pointer_cast(minxl.data()), 
                                                          thrust::raw_pointer_cast(minyl.data()));
        ClearKernel1<<<blocks * 1, 1024>>>(nnodes, N_POINTS, thrust::raw_pointer_cast(childl.data()));
        TreeBuildingKernel<<<blocks * FACTOR2, THREADS2>>>(nnodes, N_POINTS, thrust::raw_pointer_cast(errl.data()), 
                                                                             thrust::raw_pointer_cast(childl.data()), 
                                                                             thrust::raw_pointer_cast(pts.data()), 
                                                                             thrust::raw_pointer_cast(pts.data() + N_POINTS));
        ClearKernel2<<<blocks * 1, 1024>>>(nnodes, thrust::raw_pointer_cast(startl.data()), thrust::raw_pointer_cast(massl.data()));
        SummarizationKernel<<<blocks * FACTOR3, THREADS3>>>(nnodes, N_POINTS, thrust::raw_pointer_cast(countl.data()), 
                                                                                      thrust::raw_pointer_cast(childl.data()), 
                                                                                      thrust::raw_pointer_cast(massl.data()),
                                                                                      thrust::raw_pointer_cast(pts.data()),
                                                                                      thrust::raw_pointer_cast(pts.data() + N_POINTS));
        SortKernel<<<blocks * FACTOR4, THREADS4>>>(nnodes, N_POINTS, thrust::raw_pointer_cast(sortl.data()), 
                                                                     thrust::raw_pointer_cast(countl.data()), 
                                                                     thrust::raw_pointer_cast(startl.data()), 
                                                                     thrust::raw_pointer_cast(childl.data()));
        ForceCalculationKernel<<<blocks * FACTOR5, THREADS5>>>(nnodes, N_POINTS, thrust::raw_pointer_cast(errl.data()), 
                                                                    itolsq, epssq, // Should these by changed? 
                                                                    thrust::raw_pointer_cast(sortl.data()), 
                                                                    thrust::raw_pointer_cast(childl.data()), 
                                                                    thrust::raw_pointer_cast(massl.data()), 
                                                                    thrust::raw_pointer_cast(pts.data()),
                                                                    thrust::raw_pointer_cast(pts.data() + N_POINTS),
                                                                    thrust::raw_pointer_cast(forces.data()),
                                                                    thrust::raw_pointer_cast(forces.data() + N_POINTS),
                                                                    thrust::raw_pointer_cast(norml.data()));
        // non-normalized xrep stored in velxl, yrep stored in velyl, norm_i stored in norml
        norm = thrust::reduce(norml.begin(), norml.end(), 0.0f, thrust::plus<float>());
         
        // Add resulting force vector to positions w/ normalization, mul by 4 and learning rate
        thrust::transform(forces.begin(), forces.end(), pts.begin(), pts.begin(), saxpy_functor(eta * 4.0f / norm));

        // Done (check progress, etc.)


    }
}
