Class SolverCTMC

Direct Known Subclasses:
CTMC

public class SolverCTMC extends NetworkSolver
Solver for Continuous-Time Markov Chain (CTMC) analysis of queueing networks.

SolverCTMC implements exact numerical analysis of queueing networks by constructing and solving the underlying continuous-time Markov chain. This approach provides exact results for steady-state and transient behavior of networks that may not satisfy product-form assumptions.

Key CTMC solver capabilities:

  • Exact CTMC state space construction and solution
  • Steady-state probability computation
  • Transient analysis with time-dependent solutions
  • Joint and marginal state probability distributions
  • Cache network modeling with exact hit/miss probabilities
  • General service and arrival process support

The solver automatically constructs the infinitesimal generator matrix Q and solves the balance equations πQ = 0 for steady-state analysis, or the differential equation dπ/dt = πQ for transient analysis.

Since:
1.0
See Also:
  • Constructor Details

    • SolverCTMC

      public SolverCTMC(Network model, Object... args)
    • SolverCTMC

      public SolverCTMC(Network model, SolverOptions options)
    • SolverCTMC

      public SolverCTMC(MarkovProcess chain, Object... args)
      Solves a user-supplied CTMC directly, bypassing state-space generation.
      Parameters:
      chain - the continuous-time Markov chain to solve
      args - solver options in key-value form
    • SolverCTMC

      public SolverCTMC(MarkovProcess chain, SolverOptions options)
      Solves a user-supplied CTMC directly, bypassing state-space generation.
      Parameters:
      chain - the continuous-time Markov chain to solve
      options - solver options
    • SolverCTMC

      public SolverCTMC(MarkovChain chain, Object... args)
      Solves a user-supplied DTMC directly, bypassing state-space generation.
      Parameters:
      chain - the discrete-time Markov chain to solve
      args - solver options in key-value form
    • SolverCTMC

      public SolverCTMC(MarkovChain chain, SolverOptions options)
      Solves a user-supplied DTMC directly, bypassing state-space generation.
      Parameters:
      chain - the discrete-time Markov chain to solve
      options - solver options
  • Method Details

    • isChainSolver

      public boolean isChainSolver()
      Returns:
      true when the solver was built from a MarkovProcess or a MarkovChain
    • isDiscreteChain

      public boolean isDiscreteChain()
      Returns:
      true when the solver was built from a MarkovChain (DTMC)
    • getTransMat

      public Matrix getTransMat()
      Returns:
      the transition matrix of the user-supplied DTMC (chain mode only)
    • getProb

      public double getProb(Matrix state)
      Stationary probability of a single state of the user-supplied chain, identified by its row in the chain state space or, when the chain carries none, by its 1-based state index.
      Parameters:
      state - state row or state index
      Returns:
      the stationary probability of that state
    • getAvg

      public SolverResult getAvg()
      Overrides:
      getAvg in class NetworkSolver
    • getAvgTable

      public NetworkAvgTable getAvgTable()
      Description copied from class: NetworkSolver
      Returns a table of average station metrics organized by job classes.
      Overrides:
      getAvgTable in class NetworkSolver
      Returns:
      table containing station-level metrics for each class
    • defaultOptions

      public static SolverOptions defaultOptions()
    • isStateSpaceTractable

      public static MemoryGuard.GateResult isStateSpaceTractable(Network model, SolverOptions options)
      True when the worst-case CTMC state space of the model fits the host memory budget. Same estimator and gate the analyzer runs, exposed so a caller (e.g. SolverAUTO) can rank CTMC out before paying for state-space generation. Mirrors MATLAB SolverCTMC.isStateSpaceTractable.
      Parameters:
      model - the network under analysis
      options - solver options carrying cutoff, force and safety fraction
      Returns:
      the gate decision; ok is true when CTMC is a viable candidate
    • unsupportedMethodReason

      protected String unsupportedMethodReason(String method)
      The forwarding address for the QRF reduction bounds, which are SolverBA's.

      runAnalyzer carried this text and still does, for the enableChecks = false path that skips the gate entirely -- but it sits DOWNSTREAM of NetworkSolver.checkDeclaredMethod(jline.solvers.SolverOptions), which had already reported the flat "the 'qrf.bas' method is unsupported by this solver" and sent the caller looking for SolverBA on their own. That gate asks this method first now, and both sites read the text from here so they cannot drift into two answers.

      Asks nothing of the model, which is what lets the name gate call it.

      Overrides:
      unsupportedMethodReason in class NetworkSolver
      Parameters:
      method - the requested method name
      Returns:
      the forwarding address, or "" when the name is not a QRF one
    • listValidMethods

      public List<String> listValidMethods()
    • getMethodFeatureSet

      public FeatureSet getMethodFeatureSet(String method)
      Per-method feature deltas applied to the base CTMC envelope.

      Four of the six methods share it; "cftp"/"cftp.approx" and "mdd" narrow it, because neither builds the explicit generator that carries the rest of the envelope. Mirrors MATLAB SolverCTMC.getMethodFeatureSet.

      Overrides:
      getMethodFeatureSet in class Solver
      Parameters:
      method - the concrete method name
      Returns:
      the envelope of that method
    • supportsModelMethod

      public String supportsModelMethod(String method)
      The per-method rules the feature registry has no name for, asked of the SAME predicates the analyzers use so that the report and the run cannot answer differently.

      Three of them: the class count and the station count that "cftp" and "mdd" need (a class count is not a model feature), and the state-space size that the explicit-generator methods need. The last one is why "default"/"exact"/"gpu" were offered on models whose chain does not fit memory -- the analyzer priced the state space and refused, and nothing above it had asked.

      THE TWO STRUCTURAL PREDICATES ARE ASKED BEFORE THE FEATURE GATE, which is the reverse of the usual order and deliberate: each is the analyzer's own assert, so it refuses a strict superset of what the per-method feature deltas refuse, and its wording names the offending station or class count instead of a feature. Asking the feature gate first would replace "the cftp method supports closed models only" with "(feature: OpenClass)" on the very run the caller is about to make.

      Overrides:
      supportsModelMethod in class Solver
      Parameters:
      method - the concrete method name
      Returns:
      empty string if supported, else the offending reason
    • getFeatureSet

      public static FeatureSet getFeatureSet()
    • printInfGen

      public static void printInfGen(SolverCTMC.generatorResult infGen, SolverCTMC.StateSpace stateSpace)
    • printInfGen

      public static void printInfGen(Matrix Q, Matrix SS)
    • printEventFilt

      public static void printEventFilt(SolverCTMC.generatorResult infGen, SolverCTMC.StateSpace stateSpace)
    • printEventFilt

      public static void printEventFilt(MatrixCell eventFilt, Matrix SS)
    • getCdfRespT

      public Matrix getCdfRespT(Matrix R)
      Get the cumulative distribution function of response times using tagged job methodology
      Parameters:
      R - Response time matrix or percentile values
      Returns:
      Matrix containing CDF values
    • getCdfRespT

      public Ret.DistributionResult getCdfRespT(AvgHandle R)
      Response-time distribution, as the distribution and not as a summary.

      THIS OVERRIDE IS THE POINT. NetworkSolver.getCdfRespT(AvgHandle) fabricates an exponential law with the right mean, and the only other method here takes a Matrix, so it OVERLOADS rather than overrides: every caller holding a NetworkSolver silently received the fabricated law even though the tagged-chain computation was available. The curves are the ones MATLAB and C++ return, in their column order [F(t) t].

      Overrides:
      getCdfRespT in class NetworkSolver
      Parameters:
      R - response time handles (optional)
      Returns:
      result containing CDFs for response times [stations x classes]
    • getCdfSysRespT

      public List<Matrix> getCdfSysRespT()
      The SYSTEM response-time distribution: one law per CHAIN, not a number.

      Port of matlab/src/solvers/CTMC/@SolverCTMC/getCdfSysRespT.m. Each entry is a (T x 2) matrix of [F(t) t] for one chain, in chain order, as MATLAB's RD{1,c} cell and the C++ sysrespt block are.

      THE QUANTITY IS THE CYCLE TIME. The split is the tagged job's ARRIVAL AT ITS OWN REFERENCE STATION, so a passage runs from one such arrival to the next: the job's whole trip round the network, not its stay at one station. That is why a single MAP suffices here where getCdfRespT(Matrix) needs two -- the arrival that starts the passage and the one that ends it are the same event, so map_pie and the sub-generator come from the same map_normalize({Q - D1, D1}).

      THIS REPLACED A WEIGHTED SCALAR AVERAGE. The old body called getCdfRespT for its per-(station, class) summary values and returned a single population-weighted mean of them in a 1x1 matrix. That is not a distribution, and an average of per-station response-time values is not the system response time even as a mean: the cycle time is their SUM along the job's route, not their average.

      Two constants differ from the per-station getter on purpose, matching the reference: the grid is 10000 intervals rather than 100000, and the truncation is at 1 - FineTol rather than CoarseTol, because a cycle time is longer and its tail matters more.

    • getCdfFirstPassT

      public SolverCTMC.FirstPassageResult getCdfFirstPassT(Matrix A, Matrix B)
      Distribution of the FIRST PASSAGE TIME from state set A into state set B, on the CTMC underlying this model.

      Mirrors @SolverCTMC/getCdfFirstPassT.m. A and B name states either as 1-based ROW INDICES into the state space returned by getStateSpace(), or as matrices of state rows, which are resolved against that space. An empty A starts from the conditional stationary law on the complement of B.

      THIS IS NOT getCdfRespT. That getter times a tagged job between an arrival at a station and its departure, through the event filtration; this one times the chain between two sets of states the caller names, and answers questions the filtration cannot express -- the writer cycle time of a readers-writers model, the time to fill a buffer, the time to leave a degraded region.

      Reference: P. G. Harrison and W. J. Knottenbelt, "Passage Time Distributions in Large Markov Chains", 2002.

      Parameters:
      A - source state set, or null/empty for the conditional stationary law
      B - target state set, which may not be empty
      Returns:
      the [F(t), t] curve and its supporting data
    • getFirstPassTMoments

      public SolverCTMC.FirstPassageMomentsResult getFirstPassTMoments(Matrix A, Matrix B, int nmax)
      Moments of order 1..nmax of the first passage time from state set A into state set B.

      Mirrors @SolverCTMC/getFirstPassTMoments.m. NO TRANSFORM INVERSION AND NO TIME GRID ARE INVOLVED: the moments come from Eq. 3 of Harrison and Knottenbelt (2002), one linear solve per order, so they are EXACT and are not limited by the horizon a CDF would have to be truncated at. That is why this getter exists beside getCdfFirstPassT(jline.util.matrix.Matrix, jline.util.matrix.Matrix): the variance or the skewness of a passage time costs nmax solves here and a numerical integration of a truncated curve there.

      A and B name states as in getCdfFirstPassT(jline.util.matrix.Matrix, jline.util.matrix.Matrix).

      Parameters:
      A - source state set, or null/empty for the conditional stationary law
      B - target state set, which may not be empty
      nmax - highest moment order
      Returns:
      the moment vector, the per-source moments and the resolved state sets
    • getFirstPassTMoments

      public SolverCTMC.FirstPassageMomentsResult getFirstPassTMoments(Matrix A, Matrix B)
      Moments of order 1..3, the reference's default.
    • getGenerator

      public SolverCTMC.generatorResult getGenerator()
    • getAsymptoticVariance

      public Map<String,Double> getAsymptoticVariance(double[] f)
      The asymptotic variance of the time-average of a reward along a sample path of this model's CTMC.

      WHAT IT IS FOR. A simulation estimate of a steady-state mean has a standard error that shrinks like sqrt(sigma^2/t), where sigma^2 is NOT the stationary variance of the reward but its ASYMPTOTIC variance, which also carries the autocorrelation of the path. That number is what says how long a run has to be, and SimRunlength.sim_runlength(double, double, double, double, double) turns it into a run length for a target precision. It cannot be guessed from the stationary variance: on M/M/1 the two differ by a factor that blows up like (1-rho)^-2.

      Parameters:
      f - one reward value per CTMC state, in the state order getGenerator() returns
      Returns:
      the map of sim_asymvar_ctmc: mean, variance, asymptoticVariance
      See Also:
    • getAsymptoticVariance

      public Map<String,Double> getAsymptoticVariance(Function<double[],Double> f)
      The same, with the reward given as a function of the STATE ROW rather than as a vector; the state space is the one the generator was built from.
      Parameters:
      f - the reward, applied to each row of the state space
      Returns:
      the map of sim_asymvar_ctmc
    • generator

      public SolverCTMC.generatorResult generator()
      Alias of getGenerator().
    • getGenerator

      public SolverCTMC.generatorResult getGenerator(SolverOptions options)
    • getMarkedCTMC

      public MarkedMarkovProcess getMarkedCTMC()
      Get the MarkedCTMC representation of the model
      Returns:
      MarkedCTMC with generator and event filters
    • getMarkedCTMC

      public MarkedMarkovProcess getMarkedCTMC(SolverOptions options)
      Get the MarkedCTMC representation of the model with specified options
      Parameters:
      options - solver options
      Returns:
      MarkedCTMC with generator and event filters
    • getInfGen

      public SolverCTMC.generatorResult getInfGen()
    • getInfGen

      public SolverCTMC.generatorResult getInfGen(SolverOptions options)
    • getSymbolicGenerator

      public SolverCTMC.symbolicGeneratorResult getSymbolicGenerator()
      Symbolic infinitesimal generator with each event filtration normalized by its minimum positive rate and scaled by a symbolic variable x1, ..., xE.

      Java has no symbolic algebra engine, but the symbolic generator is linear in the event symbols, so it is represented exactly by one numeric coefficient matrix per event. The result can be evaluated at any symbol assignment via SolverCTMC.symbolicGeneratorResult.evalInfGen(double[]) and inspected entry-wise via SolverCTMC.symbolicGeneratorResult.getSymbolicEntry(int, int). The MATLAB and Python wrappers rebuild native symbolic objects from the coefficient matrices.

      Returns:
      symbolic generator decomposition
    • getSymbolicGenerator

      public SolverCTMC.symbolicGeneratorResult getSymbolicGenerator(boolean invertSymbol)
      Symbolic infinitesimal generator.
      Parameters:
      invertSymbol - if true, each event filtration is divided by its symbol instead of multiplied
      Returns:
      symbolic generator decomposition
    • assertPhaseTypeStates

      protected void assertPhaseTypeStates(String what)
      Refuses a query whose answer is a per-state probability under an ME. A matrix-exponential service embeds in the generator with negative off-diagonal entries, so the stationary vector is a SIGNED measure: only its aggregates over each phase block are probabilities. Mean measures stay exact (they are linear in that vector), but a per-state or transient answer is not a probability at all, and uniformization -- a Poisson mixture of powers of I + Q/lambda -- diverges on a signed generator. Such queries are refused rather than answered with a number that looks like a probability. Mirrors MATLAB @SolverCTMC/assertPhaseTypeStates.m and the native Python SolverCTMC._assert_phasetype_states.
      Parameters:
      what - name of the query, used in the error message
    • getSymbolicSolution

      public SymEngine.CTMCSolution getSymbolicSolution()
      Symbolic stationary distribution of the CTMC, as a function of the event rate symbols x1, ..., xE.

      The generator is built here from getSymbolicGenerator(), which needs no computer algebra because it is linear in the symbols; solving pi Q = 0 over the rational function field does, and is delegated to the backend resolved by SymEngines (SageMath in a container by default, see options.config.symbolic).

      The returned expressions are not comparable with another codebase's by text: symbol numbering follows event enumeration order and the printed normal form depends on the engine version. Substitute rates and compare numbers instead, as SymEngine.eval(java.util.List<java.lang.String>, java.util.Map<java.lang.String, java.lang.Double>) does.

      Returns:
      the stationary distribution, one expression per state
      Throws:
      RuntimeException - if no symbolic backend is available or the solve fails
    • getSymbolicSolution

      public SymEngine.CTMCSolution getSymbolicSolution(SymEngine engine)
      Symbolic stationary distribution, computed by a given backend.
      Parameters:
      engine - the computer algebra backend
      Returns:
      the stationary distribution, one expression per state
      Throws:
      RuntimeException - if the solve fails
    • getProb

      public Ret.ProbabilityResult getProb(int node, Matrix state)
      Description copied from class: NetworkSolver
      Returns marginal state probabilities for a specific node and state. This is an abstract method that must be implemented by concrete solver subclasses.
      Overrides:
      getProb in class NetworkSolver
      Parameters:
      node - the node index for which to compute probabilities
      state - the state vector to query (optional, null for all states)
      Returns:
      result containing marginal state probabilities
    • getProb

      public Ret.ProbabilityResult getProb(StatefulNode node, Matrix state)
    • getProb

      public Ret.ProbabilityResult getProb(StatefulNode node)
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(int node, Matrix state_a)
      Description copied from class: NetworkSolver
      Probability of a SPECIFIC per-class job distribution at a station. Returns P(n1 jobs of class 1, n2 jobs of class 2, ...) for given state.

      Compare with NetworkSolver.getProbMarg(int, int, jline.util.matrix.Matrix): returns queue-length distribution for a single class, i.e., P(n jobs of class r) for n=0,1,...,N(r).

      Overrides:
      getProbAggr in class NetworkSolver
      Parameters:
      node - the node index for which to compute probabilities
      state_a - per-class job counts, e.g., [2,1] = 2 class-1, 1 class-2
      Returns:
      scalar probability in [0,1]
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(StatefulNode node, Matrix state_a)
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(StatefulNode node)
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(Node node, Matrix state_a)
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(Node node)
    • getProbSys

      public Ret.ProbabilityResult getProbSys()
      Description copied from class: NetworkSolver
      Returns joint state probabilities for the entire system. This is an abstract method that must be implemented by concrete solver subclasses.
      Overrides:
      getProbSys in class NetworkSolver
      Returns:
      result containing joint state probabilities
    • getProbSysAggr

      public Ret.ProbabilityResult getProbSysAggr(Matrix sysState)
      getProbSysAggr for a caller-named system state, given as one row of per-class job counts per STATION, station-major. The model interchange carries no per-station initial state, so a delegated query -- the CLI's -a prob-sys-aggr, and through it lang='java' -- would otherwise be answered at the JAR's own default initialization: on statepr_sys_aggr_large that reported 0.0941, the probability of all four jobs at Queue1, where the caller asked about all four at Queue3 (0.000348). Naming the state here is what makes the delegated getter answer the caller's question.
      Parameters:
      sysState - (nstations x nclasses) per-class counts, or null for the model's own state
    • getProbSys

      public Ret.ProbabilityResult getProbSys(Matrix sysState)
      getProbSysAggr(Matrix) for the joint (non-aggregated) getter.
    • getProbSysAggr

      public Ret.ProbabilityResult getProbSysAggr()
      Description copied from class: NetworkSolver
      Returns aggregated joint state probabilities for the entire system. This is an abstract method that must be implemented by concrete solver subclasses.
      Overrides:
      getProbSysAggr in class NetworkSolver
      Returns:
      result containing aggregated joint state probabilities
    • getStartRate

      public Matrix getStartRate()
      (stations x classes) rate at which a class-r job BEGINS or RESUMES holding a server at station i, i.e. pi*F*e over the START filtration.

      At a lossless station with no in-service abandonment getStartRate == getAvgTput + getPreemptRate, because every job starts service once per entry into a server and every preemption is followed by exactly one later resume or restart. At a non-preemptive station this collapses to startRate == throughput.

      An accessor, not a MetricType: it adds no getAvgTable column.

    • getPreemptRate

      public Matrix getPreemptRate()
      (stations x classes) rate at which a class-r job HOLDING A SERVER at station i is pushed back into the buffer. Identically zero at a non-preemptive station. Preempt-resume and preempt-independent stations report the SAME rate: which phase the displaced job resumes in is not a property of how often it is displaced.
    • getEventFiltration

      public Matrix[][] getEventFiltration(EventType eventType)
      Filtration of a DERIVED event type, indexed [station][class]: the (s,ns) entry is the rate at which the transition s -> ns carries one such event at that station for that class.

      EVENTTYPE must be EventType.START or EventType.PREEMPT. The two are not synchronizations: they are tags on the ARV and DEP arcs that cause them, so they are NOT part of the event filtration getGenerator returns (which pairs one-to-one with sn.sync and is summed as D1) and are kept here instead.

    • getStateSpace

      public SolverCTMC.StateSpace getStateSpace()
    • stateSpace

      public SolverCTMC.StateSpace stateSpace()
      Alias of getStateSpace().
    • getStateSpace

      public SolverCTMC.StateSpace getStateSpace(SolverOptions options)
    • getStateSpaceAggr

      public Matrix getStateSpaceAggr()
    • getStruct

      public NetworkStruct getStruct(SolverCTMC solverCTMC)
    • getTranProb

      public Ret.ProbabilityResult getTranProb(StatefulNode node)
    • getTranProbAggr

      public Ret.ProbabilityResult getTranProbAggr(StatefulNode node)
    • getTranProbSys

      public Ret.ProbabilityResult getTranProbSys()
    • getTranProbSysAggr

      public Ret.ProbabilityResult getTranProbSysAggr()
    • supportsTransientAnalysis

      public boolean supportsTransientAnalysis()
      Description copied from class: Solver
      Does this solver produce transient averages, i.e. does getTranAvg return trajectories on a finite options.timespan? Declared false here and overridden by the solvers that populate result.Tran (Fluid, CTMC, LDES, JMT). It is a capability claim, not a state test: it must answer before any run has taken place, because the MAP/MMPP random-environment fallback uses it to decide whether the environment stages can be coupled by the mean-field analyzer (which needs getTranAvg) or only by the two steady-state limits.
      Overrides:
      supportsTransientAnalysis in class Solver
      Returns:
      true if the solver can return transient averages
    • runAnalyzer

      Description copied from class: Solver
      Executes the solver algorithm to analyze the model. This abstract method must be implemented by concrete solver classes.
      Specified by:
      runAnalyzer in class Solver
      Throws:
      IllegalAccessException - if access to required resources is denied
      ParserConfigurationException - if XML parsing configuration fails
      IOException - if I/O operations fail
    • sample

      public SolverCTMC.SampleResult sample(StatefulNode node, int numEvents)
    • sampleSys

      public Ret.SampleResult sampleSys(int numEvents)
      Description copied from class: NetworkSolver
      Samples joint system state trajectories. This is an abstract method that must be implemented by concrete solver subclasses.
      Overrides:
      sampleSys in class NetworkSolver
      Parameters:
      numEvents - the number of events to sample
      Returns:
      result containing sampled joint system state trajectories
    • supports

      public boolean supports(Network model)
      Description copied from class: Solver
      Checks if this solver supports the given network model. Default implementation returns true; subclasses should override to provide specific feature validation.
      Overrides:
      supports in class Solver
      Parameters:
      model - the network model to check
      Returns:
      true if the model is supported, false otherwise
    • sampleAggr

      public SolverCTMC.SampleResult sampleAggr(StatefulNode node, int numEvents)
    • sampleSysAggr

      public Ret.SampleResult sampleSysAggr(int numEvents)
      Description copied from class: NetworkSolver
      Samples aggregated joint system state trajectories. This is an abstract method that must be implemented by concrete solver subclasses.
      Overrides:
      sampleSysAggr in class NetworkSolver
      Parameters:
      numEvents - the number of events to sample
      Returns:
      result containing sampled aggregated joint system state trajectories
    • getRewardResult

      public RewardResult getRewardResult()
      Get reward computation results via value iteration. Computes cumulative rewards for all defined reward functions using value iteration on the uniformized CTMC.
      Returns:
      RewardResult containing value functions and steady-state rewards
      Throws:
      IllegalStateException - if no rewards are defined on the model
    • getRewardValueFunction

      public Matrix getRewardValueFunction(String rewardName)
      Get the value function for a specific reward.
      Parameters:
      rewardName - The name of the reward
      Returns:
      Matrix of size [Tmax+1 x nStates] containing V^k(s) values
      Throws:
      IllegalArgumentException - if reward name not found
    • getRewardTimeVector

      public double[] getRewardTimeVector()
      Get the time vector for reward computation.
      Returns:
      Time vector scaled by uniformization rate
    • getAvgReward

      public Map<String,Double> getAvgReward()
      Get steady-state expected reward for all rewards.
      Returns:
      Map from reward name to expected reward value
    • getAvgReward

      public double getAvgReward(String rewardName)
      Get steady-state expected reward for a specific reward.
      Parameters:
      rewardName - The name of the reward
      Returns:
      Expected reward value in steady state
      Throws:
      IllegalArgumentException - if reward name not found
    • getRewardNames

      public List<String> getRewardNames()
      Get the list of defined reward names.
      Returns:
      List of reward names
    • clearRewardResult

      public void clearRewardResult()
      Clear cached reward results to force recomputation.
    • runRewardAnalyzer

      public RewardResult runRewardAnalyzer()
      Run the reward analyzer and cache results. Convenience wrapper calling solver_ctmc_reward and storing results.
      Returns:
      RewardResult containing value functions, time vector, names, and steady-state rewards
    • getReward

      public RewardResult getReward(String rewardName)
      Get reward value function and state space, with optional filtering by reward name. Alias matching MATLAB getReward() signature.
      Parameters:
      rewardName - Optional reward name to filter. If null, returns all rewards.
      Returns:
      RewardResult containing value functions, time vector, names, state space
    • getReward

      public RewardResult getReward()
      Get reward value function and state space for all rewards.
      Returns:
      RewardResult containing all rewards
    • getTranReward

      public Map<String,double[]> getTranReward(String rewardName)
      Get transient expected reward E[r(X(t))] over time. Computes transient expected rewards using: E[r(X(t))] = sum_s pi_t(s) * r(s) where pi_t is the transient probability distribution at time t. Requires a finite timespan set via SolverCTMC(model, options.timespan([0,T])).
      Parameters:
      rewardName - Optional reward name to filter. If null, returns all rewards.
      Returns:
      Map from reward name to double[] of expected reward values at each time point. Use getRewardTimeVector() or the result's time field to get the corresponding time points.
    • getTranReward

      public Map<String,double[]> getTranReward()
      Get transient expected reward for all rewards.
      Returns:
      Map from reward name to transient expected reward time series