double[] lineMinimize(DiffFunction function, double[] initial, double[] direction) {
    // make a 1-dim function along the direction line
    // THIS IS A HACK (but it's the NRiC peoples' hack)
    OneDimDiffFunction oneDim = new OneDimDiffFunction(function, initial, direction);
    // do a 1-dim line min on this function
    //Double Ax = new Double(0.0);
    //Double Xx = new Double(1.0);
    //Double Bx = new Double(0.0);
    // bracket the extreme pt
    double guess = 0.01;
    //System.err.println("Current "+oneDim.valueAt(0)+" nudge "+(oneDim.smallestZeroPositiveLocation()*1e-2)+" "+oneDim.valueAt(oneDim.smallestZeroPositiveLocation()*1e-5));
    if (!silent) {
      System.err.print("[");
    }
    Triple bracketing = mnbrak(new Triple(0, guess, 0), oneDim);
    if (!silent) {
      System.err.print("]");
    }
    double ax = bracketing.a;
    double xx = bracketing.b;
    double bx = bracketing.c;
    //lastXx = xx;
    // CHECK FOR END OF WORLD
    if (!(ax <= xx && xx <= bx) && !(bx <= xx && xx <= ax)) {
      System.err.println("Bad bracket order!");
    }
    if (verbose) {
      System.err.println("Bracketing found: " + ax + " " + xx + " " + bx);
      System.err.println("Bracketing found: " + oneDim.valueAt(ax) + " " + oneDim.valueAt(xx) + " " + oneDim.valueAt(bx));
      //System.err.println("Bracketing found: "+arrayToString(oneDim.vectorOf(ax),3)+" "+arrayToString(oneDim.vectorOf(xx),3)+" "+arrayToString(oneDim.vectorOf(bx),3));
    }
    // find the extreme pt
    if (!silent) {
      System.err.print("<");
    }
    double xmin = dbrent(oneDim, ax, xx, bx);
    if (!silent) {
      System.err.print(">");
    }
    // return the full vector
    //System.err.println("Went "+xmin+" during lineMinimize");
    return oneDim.vectorOf(xmin);
  }