5#ifndef LINE_IO_JMT_DIST_H
6#define LINE_IO_JMT_DIST_H
55 std::snprintf(buf,
sizeof(buf),
"%.12f", x);
56 return std::string(buf);
62 std::snprintf(buf,
sizeof(buf),
"%.0f", x);
63 return std::string(buf);
69 std::snprintf(buf,
sizeof(buf),
"%.5g", x);
70 return std::string(buf);
76 std::snprintf(buf,
sizeof(buf),
"%.2g", x);
77 return std::string(buf);
82 const std::string& value) {
126 v.
type = ProcessType::DISABLED;
129 if (d.
type == ProcessType::IMMEDIATE)
return v;
131 v.
rate = mean > 0.0 ? 1.0 / mean : 0.0;
134 if (d.
type == ProcessType::REPLAYER) {
147 case ProcessType::PH:
148 case ProcessType::APH:
149 case ProcessType::COXIAN:
150 case ProcessType::COX2:
151 case ProcessType::ERLANG:
152 case ProcessType::HYPEREXP:
153 case ProcessType::MAP:
154 case ProcessType::MMPP2: {
158 for (std::size_t a = 0; a < m.
D0.rows(); ++a)
159 for (std::size_t b = 0; b < m.
D0.cols(); ++b) {
164 v.
pie.resize(pie.size());
188 return t == ProcessType::PH || t == ProcessType::APH || t == ProcessType::COXIAN ||
189 t == ProcessType::COX2 || (phases > 2 && t == ProcessType::HYPEREXP);
196 e.
set_attr(
"classPath",
"java.lang.Object");
203 std::size_t n,
bool negate_diagonal) {
205 for (std::size_t j = 0; j < n; ++j) {
206 const double raw = M(row, j);
207 const double v = negate_diagonal ? (row == j ? -std::fabs(raw) : std::fabs(raw)) : raw;
229 dist.
set_attr(
"classPath",
"jmt.engine.random.PhaseTypeDistr");
230 dist.
set_attr(
"name",
"Phase-Type");
232 par.
set_attr(
"classPath",
"jmt.engine.random.PhaseTypePar");
237 for (std::size_t k = 0; k < v.
phases; ++k) {
238 const double a = k < v.
pie.size() ? std::fabs(v.
pie[k]) : 0.0;
246 if (v.
type == ProcessType::MAP || v.
type == ProcessType::MMPP2) {
254 dist.
set_attr(
"classPath",
"jmt.engine.random.MAPDistr");
255 dist.
set_attr(
"name",
"Burst (MAP)");
257 par.
set_attr(
"classPath",
"jmt.engine.random.MAPPar");
266 const char* java_class =
nullptr;
267 const char* java_par_class =
nullptr;
268 const char* display = process_to_text(v.
type);
270 case ProcessType::DET:
271 java_class =
"jmt.engine.random.DeterministicDistr";
272 java_par_class =
"jmt.engine.random.DeterministicDistrPar";
274 case ProcessType::ERLANG:
275 java_class =
"jmt.engine.random.Erlang";
276 java_par_class =
"jmt.engine.random.ErlangPar";
278 case ProcessType::EXP:
279 java_class =
"jmt.engine.random.Exponential";
280 java_par_class =
"jmt.engine.random.ExponentialPar";
281 display =
"Exponential";
283 case ProcessType::GAMMA:
284 java_class =
"jmt.engine.random.GammaDistr";
285 java_par_class =
"jmt.engine.random.GammaDistrPar";
287 case ProcessType::HYPEREXP:
288 java_class =
"jmt.engine.random.HyperExp";
289 java_par_class =
"jmt.engine.random.HyperExpPar";
290 display =
"Hyperexponential";
292 case ProcessType::PARETO:
293 java_class =
"jmt.engine.random.Pareto";
294 java_par_class =
"jmt.engine.random.ParetoPar";
296 case ProcessType::WEIBULL:
297 java_class =
"jmt.engine.random.Weibull";
298 java_par_class =
"jmt.engine.random.WeibullPar";
300 case ProcessType::LOGNORMAL:
301 java_class =
"jmt.engine.random.Lognormal";
302 java_par_class =
"jmt.engine.random.LognormalPar";
304 case ProcessType::UNIFORM:
305 java_class =
"jmt.engine.random.Uniform";
306 java_par_class =
"jmt.engine.random.UniformPar";
308 case ProcessType::REPLAYER:
309 java_class =
"jmt.engine.random.Replayer";
310 java_par_class =
"jmt.engine.random.ReplayerPar";
311 display =
"Replayer";
314 throw UnsupportedError(std::string(who) +
": JMT has no distribution for '" +
315 process_to_text(v.
type) +
"'");
319 dist.
set_attr(
"classPath", java_class);
322 par.
set_attr(
"classPath", java_par_class);
326 case ProcessType::DET:
329 case ProcessType::EXP:
332 case ProcessType::HYPEREXP:
337 case ProcessType::ERLANG:
341 case ProcessType::GAMMA:
345 case ProcessType::PARETO: {
346 const double shape = std::sqrt(1.0 + 1.0 / v.
scv) + 1.0;
347 const double scale = (1.0 / v.
rate) * (shape - 1.0) / shape;
352 case ProcessType::WEIBULL: {
355 const double c = std::sqrt(v.
scv);
356 const double rval = std::pow(c, -1.086);
357 const double alpha = (1.0 / v.
rate) / std::tgamma(1.0 + 1.0 / rval);
362 case ProcessType::LOGNORMAL: {
363 const double c = std::sqrt(v.
scv);
364 const double mu = std::log((1.0 / v.
rate) / std::sqrt(c * c + 1.0));
365 const double sigma = std::sqrt(std::log(c * c + 1.0));
370 case ProcessType::UNIFORM: {
371 const double maxVal =
373 const double minVal = 2.0 / v.
rate - maxVal;
378 case ProcessType::REPLAYER:
381 ": a Replayer must name the trace file JMT is to read; "
382 "this port carries the samples on the distribution and the "
383 "caller has not staged them beside the model");
UnsupportedError(const std::string &what)
What refreshProcessRepresentations and refreshLST compute FROM a distribution: the (D0,...
The exception types the port throws.
Enumerations and the minimal distribution descriptor shared by the model layer of the C++ port.
Dense matrix and non-owning view.
void jmt_append_distribution(xml::Element &wrapper, const JmtDistView< T > &v, const char *who)
Append the distribution and distrPar pair for one process.
std::string jmt_fmt(double x)
sprintf('%.12f', x), the numeric format of every JMT <value> body.
xml::Element & jmt_object_array(xml::Element &parent, const char *name)
<subParameter array="true" classPath="java.lang.Object" name="NAME">
bool jmt_is_phase_type(ProcessType t, std::size_t phases)
True when the reference routes the process through JMT's PhaseTypeDistr rather than through a named a...
xml::Element & jmt_scalar(xml::Element &parent, const char *class_path, const char *name, const std::string &value)
<subParameter classPath="java.lang.Double" name="NAME"><value>V</value>
void jmt_append_row(xml::Element &parent, const Matrix< double > &M, std::size_t row, std::size_t n, bool negate_diagonal)
One vector of entry doubles, the JMT encoding of a matrix row.
xml::Element & jmt_double(xml::Element &parent, const char *name, double v)
A java.lang.Double scalar subparameter.
JmtDistView< T > jmt_dist_view(const Distrib< T > &d)
Lower a Distrib to the view above.
std::string jmt_int(double x)
int2str(x): round to nearest, print as a decimal integer.
std::string jmt_num(double x)
num2str(x): MATLAB's default five-significant-digit form.
std::string jmt_sig2(double x)
num2str(x, 2): the two-significant-digit form used for alpha/precision.
mam::Map< T > dist_to_map(const Distrib< T > &d)
std::vector< T > dist_pie(const Distrib< T > &d)
sn.pie: the phase distribution seen by an arriving job.
ProcessType
Distribution kinds, with the values of MATLAB ProcessType.
Number-type abstraction for the templated API port.
The (D0, D1) pair a JMT MAP or phase-type parameter block is built from, plus the moments the analyti...
std::string trace_file
Replayer / Trace file name, empty otherwise.
std::vector< double > pie
std::string trace_file
The trace FILE a Replayer was read from, when there was one.
std::size_t phases() const
The order of the representation, MATLAB's sn.phases.
A MAP as the pair of matrices (D0, D1).
Element & add_child(const std::string &tag)
createElement + appendChild in one step; the child is owned here.
Element & set_attr(const std::string &key, const std::string &value)
setAttribute: replace the value in place when the key already exists, otherwise append.
Element & add_text_child(const std::string &tag, const std::string &value)
The common shape <tag>value</tag>.
A minimal XML DOM: read for the .lqnx interchange format, write for the JMT .jsimg and ....