Class MMAPt

All Implemented Interfaces:
Serializable, Copyable

public class MMAPt extends ContinuousDistribution implements Serializable
Time-inhomogeneous MARKED Markovian arrival process (MMAP_t).

The two axes of MAPt and MarkedMAP crossed: arrivals are labelled with one of K marks, AND the matrices that generate them are functions of the wall clock. A segment k covers [breakpoints[k], breakpoints[k+1]) and carries D0[k] together with the K blocks D1^(1)[k], ..., D1^(K)[k]; D0 holds transition rates without an arrival, D1^(c) the rates that generate an arrival of mark c, and

  D0[k] + sum_c D1^(c)[k]
is a generator in every segment. The aggregate sum_c D1^(c)[k] is the D1 of the underlying MAPt, so hiding the marks recovers exactly that process.

Two horizon conventions, as for MAPt and NHPP: a cyclic schedule repeats with period breakpoints[n]-breakpoints[0]; a non-cyclic one is silent outside its horizon and is therefore a transient construct.

Reductions. With K = 1 this is exactly the MAPt with the same matrices, and it is held to the same constructor rules so the reduction is exact rather than merely close. With one segment, or with every segment identical, it is exactly the stationary MMAP.

Like MAPt this is neither a renewal process nor a time-homogeneous one, so getSCV, getSkewness, evalCDF and evalLST return NaN rather than a value that would misreport the process as stationary. It deliberately does NOT extend Markovian or MarkedMAP: code gated on isMarkovian reads getProcess as a single stationary pair and would silently drop the schedule.

Constant support. The constructor requires one sparsity pattern across segments, per mark block and for the off-diagonal of D0, reusing MAPt.checkCommonSupport(java.util.List<jline.util.matrix.Matrix>, boolean, java.lang.String). The rule is what keeps the K = 1 reduction to MAPt exact, and it leaves the fluid path open: a segment is expressed there as a per-entry multiplier on a nominal, which is undefined where the nominal entry is zero.

At a Source the mark selects the class of the arriving job (Source.setMarkedArrival, sn.markidx). As a SERVICE process it is sampled for its duration and the mark is discarded, exactly as an MMAP is.

The MatrixCell layout is flat, because a MatrixCell cannot nest:

  [breakpoints, K, D0_1..D0_n, D1^(1)_1..D1^(1)_n, ..., D1^(K)_1..D1^(K)_n, cyclic]
with K carried explicitly in a 1-by-1 matrix, since the length alone gives only n(K+1) and cannot separate the two. The total length is 3 + n(K+1).

References: Q.-M. He, "The versatility of MMAP[K] and the MMAP[K]/G[K]/1 queue", Queueing Systems 38(4), 2001, for the marked structure; Y. M. Ko and J. Pender, "Diffusion limits for the (MAP_t/Ph_t/inf)^N queueing network", Oper. Res. Lett. 45(3), 2017, for the time-inhomogeneous one.

See Also:
  • Constructor Details

    • MMAPt

      public MMAPt(double[] breakpoints, List<Matrix> d0, List<List<Matrix>> d1k, boolean cyclic)
      Creates an MMAP_t with a piecewise-constant marked matrix schedule.
      Parameters:
      breakpoints - strictly increasing segment boundaries, length n+1
      d0 - per-segment no-arrival rate matrices, length n
      d1k - the K mark blocks, each a list of n per-segment matrices
      cyclic - whether the schedule repeats with the horizon as period
    • MMAPt

      public MMAPt(double[] breakpoints, List<Matrix> d0, List<List<Matrix>> d1k)
      Creates a cyclic MMAP_t.
  • Method Details

    • getBreakpoints

      public double[] getBreakpoints()
    • getD0Segments

      public List<Matrix> getD0Segments()
    • getD1Segments

      public List<Matrix> getD1Segments()
      Per-segment aggregate sum_c D1^(c), i.e. the D1 of the underlying MAPt.
    • getD1Segments

      public List<Matrix> getD1Segments(int k)
      Per-segment blocks of one mark.
      Parameters:
      k - the 1-based mark index
      Returns:
      the n per-segment matrices of that mark
    • getMarkSegments

      public List<List<Matrix>> getMarkSegments()
      All mark blocks, mark-major: get(c).get(j) is mark c+1 in segment j.
    • getNumberOfTypes

      public int getNumberOfTypes()
    • isCyclic

      public boolean isCyclic()
    • getNumSegments

      public int getNumSegments()
    • getNumberOfPhases

      public int getNumberOfPhases()
    • getPeriod

      public double getPeriod()
      Horizon length, which is the period when cyclic.
    • getSegmentIndexAt

      public int getSegmentIndexAt(double t)
      Index of the segment in force at t, or -1 past a non-cyclic horizon.
    • toMAPt

      public MAPt toMAPt()
      The UNMARKED schedule, i.e. the MAPt whose D1 is the per-segment aggregate.

      Hiding the marks is the exact operation: an arrival of the MMAPt is an arrival of this process regardless of its label.

      Returns:
      the aggregate MAPt
    • toMAPts

      public MAPt toMAPts(int k)
      The MARGINAL schedule of one mark: arrivals fire only on that mark's blocks, while the other marks' transitions become hidden phase changes. Segment by segment this is MAPt(D0 + D1_agg - D1^(k), D1^(k)), the time-varying analogue of MarkedMAP.toMAPs(int).
      Parameters:
      k - the 1-based mark index
      Returns:
      the marginal MAPt of that mark
    • getTimeAverageProcess

      public MatrixCell getTimeAverageProcess()
      Width-weighted average pair over the horizon, {D0bar, D1bar}.

      This is the stationary carrier of the phase structure where a solver needs a time-homogeneous one; a convex combination of generators is a generator, so it is itself a valid MAP.

      Returns:
      the nominal (D0, D1) pair
    • getTimeAverageMark

      public Matrix getTimeAverageMark(int k)
      Width-weighted average of one mark's blocks, which is the D1 of that mark in the nominal marked process.
      Parameters:
      k - the 1-based mark index
      Returns:
      the nominal block of that mark
    • getTimeAverageRate

      public double getTimeAverageRate()
      Arrival rate of the time-averaged aggregate MAP.
    • getTimeAverageMarkRates

      public double[] getTimeAverageMarkRates()
      Per-mark arrival rates of the time-averaged process.

      These sum to getTimeAverageRate(), which is the identity a marked stream has to satisfy: labelling the arrivals cannot change how many there are.

      Returns:
      the K nominal per-mark rates
    • getMean

      public double getMean()
      Description copied from class: Distribution
      Gets the mean (expected value) of this distribution.
      Specified by:
      getMean in class Distribution
      Returns:
      the mean value
    • getRate

      public double getRate()
      Description copied from class: Distribution
      Gets the rate of this distribution (inverse of mean).
      Overrides:
      getRate in class Distribution
      Returns:
      the rate value (1/mean)
    • getSCV

      public double getSCV()
      NaN: an MMAP_t is neither renewal nor time-homogeneous, so there is no i.i.d. interval distribution for an SCV to summarise. Returning the SCV of the time-averaged process would report a time-varying one as stationary to every consumer of sn.scv.
      Specified by:
      getSCV in class Distribution
      Returns:
      the squared coefficient of variation
    • getSkewness

      public double getSkewness()
      NaN; see getSCV().
      Specified by:
      getSkewness in class Distribution
      Returns:
      the skewness value
    • evalCDF

      public double evalCDF(double t)
      NaN; see getSCV().
      Specified by:
      evalCDF in class Distribution
      Parameters:
      t - the point at which to evaluate the CDF
      Returns:
      the CDF value at point t
    • evalLST

      public double evalLST(double s)
      NaN; see getSCV().
      Specified by:
      evalLST in class ContinuousDistribution
      Parameters:
      s - the Laplace domain variable
      Returns:
      the LST value at s
    • getProcess

      public MatrixCell getProcess()
      Description copied from class: ContinuousDistribution
      Gets the process representation with actual distribution parameters. Returns a MatrixCell containing the distribution parameters.
      Specified by:
      getProcess in class ContinuousDistribution
      Returns:
      MatrixCell with distribution-specific parameters
    • resetSampleClock

      public void resetSampleClock()
      Restarts the sample path at the schedule start.
    • getLastMark

      public int getLastMark()
      The 1-based mark of the interval last returned by sample(int, Random).
    • sample

      public double[] sample(int n, Random random)
      Draws n successive interarrival times along ONE sample path.

      Both the intensity and the phase depend on absolute time, so this advances an internal clock and phase across calls; use resetSampleClock() to restart. A non-cyclic schedule that runs out returns 0 for every remaining sample.

      Specified by:
      sample in class Distribution
      Parameters:
      n - the number of samples
      random - the generator
      Returns:
      the n interarrival times
    • sample

      public double[] sample(int n)
      Description copied from class: Distribution
      Generates random samples from this distribution using default random generator.
      Overrides:
      sample in class Distribution
      Parameters:
      n - the number of samples to generate
      Returns:
      array of random samples
    • nextArrival

      public double[] nextArrival(double from, int phase, Random random)
      Time to the next arrival from wall clock from in phase, the phase after it and the 1-based mark it carries.

      Exact: within a segment the phase process is a homogeneous CTMC, and by the memoryless property the residual holding time may be redrawn at a breakpoint, so the boundary is crossed by advancing the clock and resampling under the new matrices. The mark is decided by WHICH block's transition fired, in the same competing-transitions draw that ends the interval, so it is not an extra layer on top of an unmarked walk.

      Parameters:
      from - the wall-clock start
      phase - the current phase
      random - the generator
      Returns:
      {interval, next phase, mark}; the interval is 0 once a non-cyclic horizon is exhausted