Start Here — Price, Then Differentiate

The Scalar Type Behind Every Recorded Trade

Java records each ADouble operation into NablaTensor's tape, then displays the tape's forward values and reverse adjoints.

Formula

Difference of squares, recorded as binary operations.

InputsOptional
Java source
AdoubleRiskStudio.java

This exact source runs in TeaVM. Form changes update its Java literals and reset manual edits.

import com.nablatensor.engine.ADouble;
import com.nablatensor.engine.AadOpEnum;
import com.nablatensor.engine.AadRecorder;
import com.nablatensor.engine.AadTape;

public final class AdoubleRiskStudio {
  private AdoubleRiskStudio() {}

  public static void main(String[] args) {
    AadTape tape = AadRecorder.record(rec -> {
      ADouble x = rec.input("x", 5); ADouble y = rec.input("y", 3); rec.output(x.add(y)
          .mul(x.sub(y)));
    });
    int n = tape.size();
    double[] value = new double[n], adjoint = new double[n];
    double[] input = tape.recordedInputs();
    for (int i = 0; i < n; i++) {
      int a = tape.argA(i), b = tape.argB(i);
      AadOpEnum op = tape.op(i);
      double va = a >= 0 ? value[a] : 0.0, vb = b >= 0 ? value[b] : 0.0;
      double external = op == AadOpEnum.CONST ? tape.constant(i) : op == AadOpEnum.INPUT ? input[a] : 0.0;
      value[i] = op.apply(va, vb, external);
    }
    adjoint[tape.outputNode()] = 1.0;
    for (int i = n - 1; i >= 0; i--) {
      final int a = tape.argA(i), b = tape.argB(i);
      final double g = adjoint[i], va = a >= 0 ? value[a] : 0.0, vb = b >= 0 ? value[b] : 0.0, vi = value[i];
      tape.op(i)
          .propagate(va, vb, vi, g, new AadOpEnum.GradientSink() {
        public void addA(double contribution) {
          if (a >= 0) adjoint[a] += contribution;
        }
        public void addB(double contribution) {
          if (b >= 0) adjoint[b] += contribution;
        }
      });
    }
    for (int i = 0; i < n; i++) {
      String name = "";
      if (tape.op(i) == AadOpEnum.INPUT) name = tape.inputName(tape.argA(i));
      System.out.println("NODE|" + i + "|" + tape.op(i) + "|" + tape.argA(i) + "|" + tape.argB(i)
          + "|" + value[i] + "|" + adjoint[i] + "|" + tape.isActive(i) + "|" + name + "|" + tape.constant(i));
    }
    System.out.println("OUT|" + value[tape.outputNode()]);
  }
}
TeaVM compiles and runs the Java source above in this browser.
Implementation guide

The active scalar behind a differentiated trade

ADouble is the bridge between ordinary valuation arithmetic and a graph that can later produce sensitivities.

Core mechanism

An active scalar stores its numerical value and a tape-node identity. Operators create new nodes, while the recorder retains enough dependency information to push output adjoints back into the input vector.

Practical workflow

Use active values where market inputs enter a payoff or model. Leave fixed configuration and non-risk-bearing control values as ordinary Java values so the graph contains only economically meaningful differentiation paths.

Scope and review point

Making every value active enlarges the tape and can create meaningless gradients. Factor naming and input selection remain a modelling decision.