layout method

List<Offset> layout()

Implementation

List<Offset> layout() {
  try {
    Matrix matrix = Matrix.fromList(distances).pow(2);
    matrix = matrix * 2;

    var rowMeans = matrix.mean(Axis.rows); // M.mean('row');
    var colMeans = matrix.mean(Axis.columns); // M.mean('column');
    var totalMean = matrix.toVector(); // M.mean();
    matrix += totalMean;
    matrix = matrix.mapRows((row) => row - rowMeans);
    matrix = matrix.mapColumns((column) => column - colMeans);

    List<Array> arrayList = [];
    for (var element in matrix.rows) {
      arrayList.add(Array(element.toList()));
    }

    var ret = SVD(Array2d(arrayList));

    Array2d diagonalMatrix = ret.S();
    List<List<double>> dl = [];
    diagonalMatrix.toList().forEach((element) {
      dl.add(element.toList());
    });
    Matrix matrix2 = Matrix.fromList(dl);
    matrix2 = matrix2.pow(0.5);
    List<double> eigenValues = [];
    for (int i = 0; i < matrix2.rowCount; i++) {
      eigenValues.add(matrix2.getRow(i).elementAt(i));
    }

    Array2d u = ret.U();
    List<Offset> ol = [];
    for (var row in u) {
      List<double> l = List.from(Matrix.fromList([row.toList()]) * Vector.fromList(eigenValues).toList());
      ol.add(Offset(l[0], l[1]));
    }
    return ol;
  } catch (e) {
    List<Offset> res = [];
    Random random = Random();
    for (int i = 0; i < distances.length; i++) {
      var x = random.nextDouble() * linkDistance;
      var y = random.nextDouble() * linkDistance;
      res.add(Offset(x, y));
    }
    return res;
  }
}