public static double noise(double x, double y) {

      int bx0, bx1, by0, by1, b00, b10, b01, b11;
      double rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v, q[];
      int i, j;

      t = x + N;
      bx0 = ((int) t) & M;
      bx1 = (bx0 + 1) & M;
      rx0 = t - (int) t;
      rx1 = rx0 - 1;

      t = y + N;
      by0 = ((int) t) & M;
      by1 = (by0 + 1) & M;
      ry0 = t - (int) t;
      ry1 = ry0 - 1;

      i = p[bx0];
      j = p[bx1];

      b00 = p[i + by0];
      b10 = p[j + by0];
      b01 = p[i + by1];
      b11 = p[j + by1];

      sx = s_curve(rx0);
      sy = s_curve(ry0);

      q = g2[b00];
      u = rx0 * q[0] + ry0 * q[1];
      q = g2[b10];
      v = rx1 * q[0] + ry0 * q[1];
      a = lerp(sx, u, v);

      q = g2[b01];
      u = rx0 * q[0] + ry1 * q[1];
      q = g2[b11];
      v = rx1 * q[0] + ry1 * q[1];
      b = lerp(sx, u, v);

      return lerp(sy, a, b);
   }