예제 #1
0
 /**
  * Multiply by Hessian <code> H = F'NF + M </code>
  *
  * @param x Vector to be multiplied and modified
  */
 public void multiplyHessian(Vect x) {
   Vect data = _data.clone();
   _transform.forwardLinearized(data, x, _referenceModel); // data is Fx
   data.multiplyInverseCovariance(); // data is NFx
   x.multiplyInverseCovariance(); // x is Mx
   _transform.addTranspose(data, x, _referenceModel); // x is (F'NF +M)x
   data.dispose();
 }
예제 #2
0
  /**
   * Run a few tests to ensure that transpose satisfies definition. This is expensive and intended
   * only for test code.
   *
   * @return number of sigficant digits of precision in transpose. Expect 5 or 6. Unacceptable if
   *     not 3 or more. A value of 3 or 4 probably indicates a subtle error.
   */
  public int getTransposePrecision() {
    VectConst d = _data; // arbitrary nonzero data
    Vect b = this.getB(); // arbitrary nonzero model
    double bb = b.dot(b);
    checkNaN(bb);
    assert !Almost.FLOAT.zero(bb) : "Cannot test with zero-magnitude b";

    // Get forward transform of b
    Vect Fb = VectUtil.cloneZero(d);
    Vect bSave = b.clone();
    _transform.forwardLinearized(Fb, b, _referenceModel);

    // make sure didn't step on wrong vector
    assert VectUtil.areSame(b, bSave) : "model was changed by forward model";
    bSave.dispose();

    // check that forward zeros output data.
    Vect test = d.clone();
    _transform.forwardLinearized(test, b, _referenceModel);
    assert VectUtil.areSame(test, Fb) : "forwardLinearized should zero data";
    test.dispose();

    // Get transpose of d
    Vect Ad = VectUtil.cloneZero(b);
    Vect dSave = d.clone();
    _transform.addTranspose(d, Ad, _referenceModel);
    double transposeMagnitude = Ad.dot(Ad);
    checkNaN(transposeMagnitude);

    // make sure didn't step on wrong vector
    assert VectUtil.areSame(d, dSave) : "data was changed by transpose";
    dSave.dispose();

    // ensure that transpose adds to existing model
    test = b.clone(); // make initial size comparable to transpose
    double scaleTest = 1.1 * Math.sqrt(transposeMagnitude / bb);
    VectUtil.scale(test, scaleTest);
    _transform.addTranspose(d, test, _referenceModel);
    assert !VectUtil.areSame(Ad, test)
        : "Transpose should not zero model.  "
            + "Magnitude: b="
            + bb
            + "trans="
            + transposeMagnitude
            + " test="
            + test.dot(test);
    test.add(1., -1., Ad);
    VectUtil.scale(test, 1. / scaleTest);
    assert VectUtil.areSame(test, b) : "Transpose did not add to model vector";
    test.dispose();

    // get dot products that should be equal
    double dFb = d.dot(Fb);
    double Adb = Ad.dot(b);
    assert !Almost.FLOAT.zero(dFb) : "zero magnitude test: dFb is zero";
    assert !Almost.FLOAT.zero(Adb) : "zero magnitude test: Adb is zero";
    checkNaN(dFb);
    checkNaN(Adb);

    int significantDigits = 10;
    boolean matches = false;
    while (!matches && significantDigits > 0) {
      Almost almost = new Almost(significantDigits);
      matches = almost.equal(dFb, Adb);
      if (!matches) {
        --significantDigits;
      }
    }
    if (significantDigits < 3) {
      LOG.severe("Transpose precision is unacceptable: dFb=" + dFb + " Adb=" + Adb);
    }
    Ad.dispose();
    Fb.dispose();
    b.dispose();
    return significantDigits;
  }