Class JacobianChainGraph<T>

java.lang.Object
org.ddogleg.chainrule.JacobianChainGraph<T>
All Implemented Interfaces:
VerbosePrint

public class JacobianChainGraph<T> extends Object implements VerbosePrint

Computes Jacobians for a graph of JacobianSerialChain chains. Each chain is built there as usual, then a dependency is declared for each value passed from a block in one chain to an input of a block in another. Blocks are the nodes of the graph, so a chain is a path through it.

The graph is acyclic with a single output. A value may be read in more than one place, including twice inside one chain, so it is not a tree: the derivatives arriving from every consumer of a value are summed before being propagated further, which a graph without that fan out never has to do.

Two chains can depend on each other, so there is not always an order in which whole chains can run. Blocks are interleaved instead: a chain advances until it reaches a block whose inputs are not ready, then another chain runs, and so on. That order is worked out once by JacobianChainGraph.GraphConstructor.fixate() and replayed afterwards, so the optimization loop pays nothing for it, and a graph that cannot be ordered is rejected where it is defined rather than where it is used. The backwards pass walks the same order in reverse.

Usage:

  1. Build the chains on
invalid reference
#getChains
as normal, including
invalid reference
JacobianSerialChain#setPublishJac
  1. Call graph() and declare a dependency for every value crossing between chains
  2. Call JacobianChainGraph.GraphConstructor.fixate() to check the graph and work out the order
  3. Call forward then backwards(int), neither of which allocates

A chain whose first block no dependency feeds is given its input by the caller, by name, through JacobianChainGraph.Forward.input(int, CRArray). There is always at least one and there can be several, so which chain a value belongs to is stated rather than worked out.

A graph can hold a single chain, declared with JacobianChainGraph.GraphConstructor.chain(int) since no dependency names it. It computes what the chain does on its own, so a caller with a mix of the two does not have to move between the two APIs depending on whether a particular calculation needed a graph.

Rejected when the graph is defined, since each one is a silent wrong answer otherwise: a cycle, more than one unread output, no output at all, an operator used by two blocks, a dependency arriving at a chain input anywhere but the start of a chain, two dependencies arriving at one input, and a chain already belonging to another graph.

  • Constructor Details

    • JacobianChainGraph

      public JacobianChainGraph(MathCRMatrix<T> math)
  • Method Details

    • graph

      Used to construct a new graph
    • forward

      public JacobianChainGraph<T>.Forward forward(int graphID)
      Used to run the graph in forward direction. Returns a helper that lets you specify block[0] inputs for chains that require them
      Parameters:
      graphID - Which graph is going to be run.
    • getOutputSize

      public int getOutputSize(int graphID)
      Size of the graph's output, which the last block of the root chain produces
    • backwards

      public void backwards(int graphID)
      Computes the Jacobian of every parameter in the graph. forward must have run first
    • setVerbose

      public void setVerbose(@Nullable @Nullable PrintStream out, @Nullable @Nullable Set<String> configuration)
      Description copied from interface: VerbosePrint
      If set to a non-null output then extra information will be printed to the specified stream.
      Specified by:
      setVerbose in interface VerbosePrint
      Parameters:
      out - Stream that is printed to. Set to null to disable
      configuration - (Future use) Set which specifies flags that can be used to turn on and off different output