// (c) 2000 Benjamin Fry, MIT Media Laboratory, fry@media.mit.edu
// Aesthetics + Computation Group, Massachussetts Institute of Technology


public class SimilarityMatrixTest extends SimilarityMatrix {
  static int testSeed[][] = {
    { 1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0 },

    { 0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0,  0, 0, 0, 0 },

    { 0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 1, 1,  0, 0, 0, 0 },

    { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 0, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  1, 1, 0, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 1, 0 },
    { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 1 },
  };


  float s_matrix[][];


  public SimilarityMatrixTest(float noiseLevel) {
    gcount = 256;

    s_matrix = new float[gcount][gcount];
    // fill with random-ish test data
    for (int i = 0; i < gcount; i++) {
      for (int j = 0; j < i; j++) {
	s_matrix[i][j] = testSeed[i>>4][j>>4];
      }
    }

    // introduce noise with probability below
    for (int i = 0; i < gcount; i++) {
      for (int j = 0; j < i; j++) {
	if (Math.random() < noiseLevel) {
	  s_matrix[i][j] =
	    (Math.random() < 0.5) ? 1 : 0;
	}
      }
    }

    // matrix is symmetric, flip it over the axis
    for (int i = 0; i < gcount; i++) {
      for (int j = i; j < gcount; j++) {
	s_matrix[i][j] = (i == j) ? 1 : s_matrix[j][i];
      }
    }

    // reorder everything so that it isn't already, uh, finished
    permute();
  }


  public void permute() {
    // permute the matrix before clustering
    int permute[] = new int[gcount];
    for (int i = 0; i < gcount; i++) {
      permute[i] = -1;
    }
    // evenly distribute random numbers
    for (int i = 0; i < gcount; i++) {
      int which = 0;
      do {
	which = (int) (Math.random() * gcount);
      } while (permute[which] != -1);
      permute[which] = i;
    }
    // make a copy of the s_matrix
    float p_matrix[][] = new float[gcount][gcount];
    for (int j = 0; j < gcount; j++) {
      for (int i = 0; i < gcount; i++) {
	p_matrix[i][j] = s_matrix[permute[i]][permute[j]];
      }
    }
    // replace S with permuted matrix
    s_matrix = p_matrix;
  }

  
  public float get(int x, int y) {
    return s_matrix[x][y];
  }
}

