예제 #1
0
  /** Performs symbolic mix of fluids in given target ratios. */
  Fluid mix(Fluid[] fluid, double[] target) {
    assert fluid.length == target.length;

    // prune out zero-weights
    int numZeros = 0;
    for (int i = 0; i < fluid.length; i++) {
      if (target[i] == 0) {
        numZeros++;
      }
    }
    if (numZeros > 0) {
      Fluid[] _fluid = new Fluid[fluid.length - numZeros];
      double[] _target = new double[fluid.length - numZeros];
      int pos = 0;
      for (int i = 0; i < fluid.length; i++) {
        if (target[i] != 0) {
          _fluid[pos] = fluid[i];
          _target[pos] = target[i];
          pos++;
        }
      }
      fluid = _fluid;
      target = _target;
    }

    // if we're down to one fluid, return it
    if (fluid.length == 1) {
      return fluid[0];
    }

    // normalize the targets
    double sum = 0;
    for (int i = 0; i < target.length; i++) {
      sum += target[i];
    }
    for (int i = 0; i < target.length; i++) {
      target[i] /= sum;
    }

    // find depth of mixing tree that is needed to obtain
    // precision
    int depth = 0;
    int[] ratios = null;
    do {
      depth++;
      ratios = getRatios(depth, target);
    } while (ratios == null);
    assert depth < 32 : "Depth is " + depth + ", bigger than 32:  bit-width issues.";

    // System.out.println("ratio (" + ratios.length + "): " + ratios[0] + ":" + ratios[1] + ";
    // depth=" + depth);

    // break up ratios into bins
    Stack[] bins = new Stack[depth + 1];
    for (int i = 0; i < bins.length; i++) {
      bins[i] = new Stack();
    }
    for (int i = 0; i < target.length; i++) {
      int mask = 1;
      for (int j = 0; j < depth; j++) {
        if ((mask & ratios[i]) != 0) {
          bins[j].push(fluid[i]);
        }
        mask = mask << 1;
      }
    }

    BasicFluid result = buildMixingTree(bins, depth);

    // this toggles a greedy evaluation instead of demand-driven
    result.ensureAvail();

    return result;
  }
예제 #2
0
 /** Dump dependency dot-graph to <filename>. */
 public void dumpGraph(String filename) {
   BasicFluid.dumpGraph(filename);
 }