@Override
 public double[] applyAll(VariableArray valAry, Map<Object, Object> cache) {
   int len = valAry.length();
   double[] r = valAry.get("r");
   double[] s = valAry.get("s");
   double[] t = valAry.get("t");
   double[] rlt = new double[len];
   double cr = vt[funIndex][0];
   double cs = vt[funIndex][1];
   double ct = vt[funIndex][2];
   for (int i = 0; i < len; i++)
     rlt[i] = (cr * r[i] + 1.0) * (cs * s[i] + 1.0) * (ct * t[i] + 1.0) / 8.0;
   return rlt;
 }
 @Override
 public double[] applyAll(VariableArray valAry, Map<Object, Object> cache) {
   int len = valAry.length();
   double[] r = valAry.get("r");
   double[] s = valAry.get("s");
   double[] t = valAry.get("t");
   double[] rlt = new double[len];
   double cr = vt[funIndex][0];
   double cs = vt[funIndex][1];
   double ct = vt[funIndex][2];
   if ("r".equals(var))
     for (int i = 0; i < len; i++) rlt[i] = cr * (cs * s[i] + 1.0) * (ct * t[i] + 1.0) / 8.0;
   else if ("s".equals(var))
     for (int i = 0; i < len; i++) rlt[i] = (cr * r[i] + 1.0) * cs * (ct * t[i] + 1.0) / 8.0;
   else if ("t".equals(var))
     for (int i = 0; i < len; i++) rlt[i] = (cr * r[i] + 1.0) * (cs * s[i] + 1.0) * ct / 8.0;
   else throw new FutureyeException();
   return rlt;
 }
    @Override
    public double[] applyAll(VariableArray valAry, Map<Object, Object> cache) {
      double[] detJ = null;
      double[][][] J = null;
      int len = valAry.length();
      double[] rlt = new double[len];
      if (cache != null) {
        detJ = (double[]) cache.get(1);
        J = (double[][][]) cache.get(2);
      }
      if (detJ == null || J == null) {
        J = new double[3][3][len];
        J[0][0] = x_r.applyAll(valAry, cache);
        J[0][1] = x_s.applyAll(valAry, cache);
        J[0][2] = x_t.applyAll(valAry, cache);
        J[1][0] = y_r.applyAll(valAry, cache);
        J[1][1] = y_s.applyAll(valAry, cache);
        J[1][2] = y_t.applyAll(valAry, cache);
        J[2][0] = z_r.applyAll(valAry, cache);
        J[2][1] = z_s.applyAll(valAry, cache);
        J[2][2] = z_t.applyAll(valAry, cache);
        // @see ./doc/invA33.png
        detJ = Utils.determinant(J);
        if (cache != null) {
          cache.put(1, detJ);
          cache.put(2, J);
        }
      }

      if ("r".equals(rst)) {
        if ("x".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[1][1][i] * J[2][2][i] - J[1][2][i] * J[2][1][i]) / detJ[i];
        else if ("y".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][2][i] * J[2][1][i] - J[0][1][i] * J[2][2][i]) / detJ[i];
        else if ("z".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][1][i] * J[1][2][i] - J[0][2][i] * J[1][1][i]) / detJ[i];
      } else if ("s".equals(rst)) {
        if ("x".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[1][2][i] * J[2][0][i] - J[1][0][i] * J[2][2][i]) / detJ[i];
        else if ("y".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][0][i] * J[2][2][i] - J[0][2][i] * J[2][0][i]) / detJ[i];
        else if ("z".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][2][i] * J[1][0][i] - J[0][0][i] * J[1][2][i]) / detJ[i];
      } else if ("t".equals(rst)) {
        if ("x".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[1][0][i] * J[2][1][i] - J[1][1][i] * J[2][0][i]) / detJ[i];
        else if ("y".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][1][i] * J[2][0][i] - J[0][0][i] * J[2][1][i]) / detJ[i];
        else if ("z".equals(xyz))
          for (int i = 0; i < len; i++)
            rlt[i] = (J[0][0][i] * J[1][1][i] - J[0][1][i] * J[1][0][i]) / detJ[i];
      } else {
        throw new FutureyeException();
      }
      return rlt;
    }