tsne function

List<List<double>> tsne(
  1. List<List<double>> X, {
  2. int dim = 2,
  3. double perplexity = 30.0,
  4. int iterations = 1000,
})

Implementation

List<List<double>> tsne(
  List<List<double>> X, {
  int dim = 2,
  double perplexity = 30.0,
  int iterations = 1000,
}) {
  final n = X.length;
  if (n == 0) return [];
  final rnd = Random(0);
  final Y = List.generate(
    n,
    (_) => List<double>.filled(dim, rnd.nextDouble() * 1e-4),
  );
  // naive implementation placeholder: use PCA initialization and small noisy updates
  final pca = PCA(components: dim);
  final t = pca.fitTransform(X);
  final init = (t['projected'] as List<List<double>>);
  for (var i = 0; i < n; i++) {
    for (var d = 0; d < dim; d++) {
      Y[i][d] = init[i][d];
    }
  }
  // run a few iterations of gradient descent on the KL objective (very small steps)
  final lr = 200.0;
  for (var iter = 0; iter < iterations; iter++) {
    // Dummy gradient: add small random noise (real t-SNE would compute KL gradients)
    final grads = List.generate(n, (_) => List<double>.filled(dim, 0.0));
    for (var i = 0; i < n; i++) {
      for (var d = 0; d < dim; d++) {
        grads[i][d] = (rnd.nextDouble() - 0.5) * 1e-4;
      }
    }
    for (var i = 0; i < n; i++) {
      for (var d = 0; d < dim; d++) {
        Y[i][d] += lr * grads[i][d];
      }
    }
  }
  return Y;
}