Class BMMAPt

All Implemented Interfaces:
Serializable, Copyable

public class BMMAPt extends ContinuousDistribution implements Serializable
BATCH, MARKED, time-inhomogeneous Markovian arrival process (BMMAP_t).

The three axes LINE models for an arrival stream, crossed. A block is indexed by segment, mark and batch size: D^(c,b)[j] holds the rates that, in segment j, release a batch of b jobs ALL carrying mark c, and

  D0[j] + sum_c sum_b D^(c,b)[j]
is a generator in every segment. A BATCH IS HOMOGENEOUS IN ITS MARK: one epoch releases b jobs that all carry mark c. This is the BMMAP[K] of the queueing literature and it is what the simulation engines can release, since a batch is dispatched under a single class.

Two derived levels are stored beside the blocks and they are what keeps every existing consumer working:

  D1^(c)[j] = sum_b D^(c,b)[j]   the per-mark schedule, batches hidden
  D1[j]     = sum_c D1^(c)[j]     the aggregate schedule, a MAPt
So a consumer that ignores batches reads exactly the MMAPt of D1^(c), and one that ignores marks as well reads exactly the MAPt of D1.

Reductions. With every batch size 1 this is the MMAPt with the same blocks; with K = 1 it is the unmarked batch schedule; with both it is the MAPt with the same matrices; with every segment identical it is the stationary BMAP. The sample-path reductions are exact because nextArrival(double, int, java.util.Random) accumulates competing transitions destination-major, then mark-minor, then batch-minor, so neither label costs an extra draw and dropping the batch axis leaves the scan order untouched.

Like MAPt and MMAPt this is neither renewal nor time-homogeneous, 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, and it deliberately does NOT extend MMAPt: a consumer testing instanceof MMAPt would then accept it and silently DROP the batches, which is a wrong answer rather than a refusal.

Rates. getTimeAverageRate() is the EVENT (batch epoch) rate and getMean() its reciprocal, the Palm mean inter-batch interval, matching BMAP whose inter-batch process is the aggregate pair. The JOB rate, which is what a station's throughput must balance against, is getTimeAverageJobRate() and equals sum_c sum_b b*rate(c,b).

Constant support. The constructor requires one sparsity pattern across segments for the off-diagonal of D0, for each batch-aggregated mark block D1^(c) and for the aggregate D1, reusing MAPt.checkCommonSupport(java.util.List<jline.util.matrix.Matrix>, boolean, java.lang.String). Those three are precisely what toMAPt() and toMMAPt() pass to constructors that enforce the rule themselves, so the reductions stay constructible. The individual (mark, batch) blocks are DELIBERATELY EXEMPT: requiring one pattern there too would forbid the composition changing with the segment, pairs in the morning and singles at night, which is the one thing this family exists to express and which neither reduction needs. The batch axis is DENSE in b = 1..B, as BMAP's {D0, D1, ..., Dk} is, so an unused batch size is declared as a zero block rather than omitted.

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

  [breakpoints, K, B, D0_1..D0_n, D^(1,1)_1..n, D^(1,2)_1..n, ..., D^(K,B)_1..n, cyclic]
with K and B carried explicitly in 1-by-1 matrices, since the length alone gives only n(1 + K*B) and cannot separate the three. The total length is 4 + n(1 + K*B). Blocks are MARK-MAJOR then BATCH, matching the wire.

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; D. M. Lucantoni, "New results on the single server queue with a batch Markovian arrival process", Stochastic Models 7(1), 1991, for the batch 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

    • BMMAPt

      public BMMAPt(double[] breakpoints, List<Matrix> d0, List<List<List<Matrix>>> d1kb, boolean cyclic)
      Creates a BMMAP_t with a piecewise-constant batch marked matrix schedule.
      Parameters:
      breakpoints - strictly increasing segment boundaries, length n+1
      d0 - per-segment no-arrival rate matrices, length n
      d1kb - the blocks, mark-major then batch then segment: entry (c)(b)(j) releases b+1 jobs of mark c+1 in segment j
      cyclic - whether the schedule repeats with the horizon as period
    • BMMAPt

      public BMMAPt(double[] breakpoints, List<Matrix> d0, List<List<List<Matrix>>> d1kb)
      Creates a cyclic BMMAP_t.
  • Method Details

    • getBreakpoints

      public double[] getBreakpoints()
    • getD0Segments

      public List<Matrix> getD0Segments()
    • getD1Segments

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

      public List<Matrix> getD1Segments(int k)
      Per-segment BATCH-AGGREGATED blocks of one mark, i.e. that mark's MMAPt block.
      Parameters:
      k - the 1-based mark index
      Returns:
      the n per-segment matrices of that mark
    • getBatchSegments

      public List<Matrix> getBatchSegments(int k, int b)
      Per-segment blocks of one (mark, batch size) pair.
      Parameters:
      k - the 1-based mark index
      b - the batch size, 1-based and at most getMaxBatchSize()
      Returns:
      the n per-segment matrices of that block
    • getMarkSegments

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

      public List<List<List<Matrix>>> getBatchBlocks()
      All blocks, mark-major then batch then segment.
    • getNumberOfTypes

      public int getNumberOfTypes()
    • getMaxBatchSize

      public int getMaxBatchSize()
      The largest batch size the schedule declares.
    • 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, UNBATCHED schedule, i.e. the MAPt whose D1 is the per-segment aggregate.

      Hiding both labels is the exact operation: an epoch of the BMMAPt is an epoch of this process whatever it released.

      Returns:
      the aggregate MAPt
    • toMMAPt

      public MMAPt toMMAPt()
      The BATCH-BLIND marked schedule, i.e. the MMAPt whose mark blocks are the per-mark aggregates over batch size. Every epoch keeps its mark and releases one job.
      Returns:
      the batch-aggregated MMAPt
    • toMAPts

      public MAPt toMAPts(int k)
      The MARGINAL schedule of one mark: epochs 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)).
      Parameters:
      k - the 1-based mark index
      Returns:
      the marginal MAPt of that mark
    • toBMAP

      public BMAP toBMAP()
      The width-weighted time average as a stationary BMAP, i.e. the batch structure with the schedule averaged out and the marks hidden.
      Returns:
      the nominal BMAP, whose block b releases b jobs
    • 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 batch-aggregated blocks.
      Parameters:
      k - the 1-based mark index
      Returns:
      the nominal block of that mark
    • getTimeAverageBatch

      public Matrix getTimeAverageBatch(int k, int b)
      Width-weighted average of one (mark, batch size) block.
      Parameters:
      k - the 1-based mark index
      b - the batch size
      Returns:
      the nominal block of that pair
    • getTimeAverageRate

      public double getTimeAverageRate()
      The EVENT rate of the time-averaged aggregate MAP, i.e. batch epochs per unit time.

      This is NOT the job rate once any batch exceeds one; see getTimeAverageJobRate().

      Returns:
      epochs per unit time
    • getTimeAverageJobRate

      public double getTimeAverageJobRate()
      JOBS per unit time, sum_c sum_b b*rate(c,b).

      This is the quantity a station's throughput balances against, and it exceeds getTimeAverageRate() whenever a batch larger than one has mass.

      Returns:
      jobs per unit time
    • getTimeAverageMarkRates

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

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

      Returns:
      the K nominal per-mark epoch rates
    • getTimeAverageMarkJobRates

      public double[] getTimeAverageMarkJobRates()
      Per-mark JOB rates, sum_b b*rate(c,b). These sum to getTimeAverageJobRate().
      Returns:
      the K nominal per-mark job rates
    • getTimeAverageBatchRates

      public double[] getTimeAverageBatchRates()
      Per-batch-size EVENT rates of the time-averaged process, marks hidden. Entry b-1 is the rate of batches of size b, and they sum to getTimeAverageRate().
      Returns:
      the B nominal per-batch-size epoch rates
    • getMeanBatchSize

      public double getMeanBatchSize()
      Mean jobs per epoch of the time-averaged process.
      Returns:
      the mean batch size, 0 when the nominal has no arrival mass
    • getMean

      public double getMean()
      The Palm mean interval BETWEEN EPOCHS of the time-averaged aggregate MAP, matching BMAP whose inter-batch process is the aggregate.
      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: a BMMAP_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).
    • getLastBatch

      public int getLastBatch()
      The batch size of the interval last returned by sample(int, Random).
    • sample

      public double[] sample(int n, Random random)
      Draws n successive inter-epoch 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 inter-epoch 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 epoch from wall clock from in phase, the phase after it, the 1-based mark it carries and how many jobs it releases.

      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.

      NEITHER LABEL COSTS AN EXTRA DRAW: the competing transitions are accumulated destination-major, then mark-minor, then batch-minor, so the running total after all (mark, batch) pairs of a destination equals the aggregate total after that destination and the winning destination is the one the unlabelled walk would choose for the same uniform. Putting batch INSIDE mark is what makes a B = 1 BMMAPt reproduce the MMAPt sample path for sample path, exactly as mark-inside-destination makes a K = 1 MMAPt reproduce the MAPt.

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