Interoperability
LINE supports multiple interoperability features, enabling model exchange across different languages (MATLAB, Java/Kotlin, Python), transformation between queueing model formalisms, and import/export of models from external tools.
Cross-Language Execution
LINE solvers can execute using either native implementations or Java/Kotlin backend implementations via the lang option. This allows MATLAB and Python users to leverage fast Java solver implementations when needed.
% MATLAB Example: Force Java backend execution
model = Network('MyModel');
% ... define model ...
% Use MATLAB native implementation (default)
solver = MVA(model, 'lang','matlab');
% Use Java backend implementation
solver = MVA(model, 'lang','java');
# Python: Force Java backend execution
from line_solver import Network, MVA
model = Network('MyModel')
# ... define model ...
# Use Python native implementation (default)
solver = MVA(model, lang='python')
# Use Java backend implementation
solver = MVA(model, lang='java')
Model Transformations and Formats
LINE supports bidirectional transformations between different queueing model representations, import from external tools, and export to various formats:
| Type | Function/Format | Direction | Description |
|---|---|---|---|
| Transform | LINE2JLINE | MATLAB → Java | Convert MATLAB objects to Java/Kotlin objects |
| Transform | JLINE2LINE | Java → MATLAB | Convert Java/Kotlin objects to MATLAB objects |
| Transform | QN2LQN | Network → LQN | Convert queueing networks to layered queueing networks |
| Import | JSIM2LINE(filename) | JSIM/JSIMG → LINE | Import JMT simulation models with full node, distribution, and routing definitions |
| Import | LayeredNetwork.parseXML(file) | LQNX → LINE | Import layered queueing network models from LQNS XML format |
| Import | WfCommonsLoader.load(file) | WfCommons → LINE | Import scientific workflow traces (JSON format, schemas 1.3-1.5) |
| Export | QN2JSIMG() | LINE → JSIMG | Export to JMT graphical simulator format for visualization and simulation |
| Export | LayeredNetwork.writeXML(file) | LINE → LQNX | Export layered networks to LQNX format for LQNS solver |
| Export | QN2MATLAB | Network → Code | Generate MATLAB script for queueing networks |
| Export | LQN2MATLAB | LayeredNetwork → Code | Generate MATLAB script for layered queueing networks |
| Export | QN2JAVA | Network → Code | Generate Java code for programmatic model definition |
% MATLAB: Model transformations
matlab_model = Network('Example');
% ... build model ...
% Transform to Java backend
java_model = JLINE.line_to_jline(matlab_model);
recovered_model = JLINE.jline_to_line(java_model);
% Import a JMT model
model = JSIM2LINE('mymodel.jsimg');
solver = MVA(model);
results = solver.avgTable();
% Import LQNS model
lqn_model = LQN2MATLAB('system.lqnx');
solver = LN(lqn_model);
% Export model to JMT format
QN2JSIMG(model, 'exported_model.jsimg');
% Export LayeredNetwork to LQNX
lqn = LayeredNetwork('WebService');
% ... build layered model ...
lqn.writeXML('webservice.lqnx');
# Python: Model transformations
from line_solver import Network, Source, Queue, Sink
from line_solver import SchedStrategy, Exp, OpenClass
from line_solver import JLINE, JSIM2LINE, MVA, QN2JSIMG, M2M, SolverLN
# Build and transform model
model = Network('Example')
source = Source(model, 'Source')
queue = Queue(model, 'Queue', SchedStrategy.FCFS)
sink = Sink(model, 'Sink')
jobclass = OpenClass(model, 'Class1')
source.setArrival(jobclass, Exp(1.0))
queue.setService(jobclass, Exp(2.0))
model.link(Network.serialRouting(source, queue, sink))
# Transform to/from Java backend
java_model = JLINE.line_to_jline(model)
recovered_model = JLINE.jline_to_line(java_model)
# Import JMT model
model = JSIM2LINE('mymodel.jsimg')
solver = MVA(model)
results = solver.avg_table()
# Import LQNS model
m2m = M2M()
lqn_model = m2m.LQN2PYTHON('system.lqnx')
solver = SolverLN(lqn_model)
# Export to JMT format
QN2JSIMG(model, 'exported_model.jsimg')
MAP/PH Distribution Format Conversion
LINE uses the BUTools representation format natively for Markovian Arrival Processes (MAPs) and Phase-Type (PH) distributions. MAPs are represented by two matrices (D0, D1), and PH distributions by an initial probability vector (alpha) and subgenerator matrix (T). This format is directly compatible with the BUTools library and other tools using this standard representation.
Native BUTools Format
LINE MAP and PH objects directly expose their internal representation matrices, which are in BUTools format:
% MATLAB: Accessing MAP matrices (BUTools format)
map = MAP.rand(3); % Create random 3-phase MAP
% Extract D0 and D1 matrices (BUTools format)
D0 = map.D(0); % Generator matrix for transitions without arrivals
D1 = map.D(1); % Rate matrix for transitions with arrivals
% These matrices can be used directly with BUTools functions
% e.g., matlab/lib/thirdparty/BUTools/map/*
% For PH distributions:
ph = PH.fit(2.0, 1.5, 2.0); % Fit from moments
alpha = ph.getInitProb(); % Initial probability vector
T = ph.getSubgenerator(); % Subgenerator matrix
// Java: Accessing MAP matrices (BUTools format)
import jline.lang.processes.MAP;
import jline.lang.processes.PH;
import jline.util.matrix.Matrix;
MAP map = MAP.rand(3); // Create random 3-phase MAP
// Extract D0 and D1 matrices (BUTools format)
Matrix D0 = map.D(0); // Generator matrix for transitions without arrivals
Matrix D1 = map.D(1); // Rate matrix for transitions with arrivals
// For PH distributions:
PH ph = PH.fit(2.0, 1.5, 2.0); // Fit from moments
Matrix alpha = ph.getInitProb(); // Initial probability vector
Matrix T = ph.getSubgenerator(); // Subgenerator matrix
# Python: Accessing MAP matrices (BUTools format)
from line_solver import MAP, PH
map_proc = MAP.rand(3) # Create random 3-phase MAP
# Extract D0 and D1 matrices (BUTools format)
D0 = map_proc.D(0) # Generator matrix for transitions without arrivals
D1 = map_proc.D(1) # Rate matrix for transitions with arrivals
# For PH distributions:
ph = PH.fit(2.0, 1.5, 2.0) # Fit from moments
alpha = ph.getInitProb() # Initial probability vector
T = ph.getSubgenerator() # Subgenerator matrix
MAP Representation Conversions
LINE provides methods to convert MAPs between different representations for analysis and compatibility with other tools:
| Method | Description | Use Case |
|---|---|---|
map.D(i) | Access Di matrix (i=0,1 for MAP) | Extract BUTools-compatible matrices for external analysis |
map.toTimeReversed() | Compute time-reversed MAP | Queue analysis requiring reversed processes |
map.toMMDP() | Convert MAP to Markov-Modulated Deterministic Process | Fluid queue analysis and matrix-analytic methods |
map.getRenewalProcess() | Remove temporal dependence to get renewal PH process | Simplify analysis by removing correlation structure |
ph.getInitProb() | Extract initial probability vector (alpha) | Access PH representation for BUTools PH functions |
ph.getSubgenerator() | Extract subgenerator matrix (T) | Access PH representation for matrix operations |
% MATLAB: MAP representation conversions
map = MAP.rand(3);
% Get time-reversed MAP (useful for queue analysis)
map_reversed = map.toTimeReversed();
% Convert to MMDP for fluid queue analysis
mmdp = map.toMMDP();
% Get renewal process (removes temporal correlation)
renewal_process = map.getRenewalProcess(); % Returns {T, t} cell array
% Extract moments and statistics
mean_interarrival = map.getMean();
scv = map.getIDC(); % Index of dispersion for counts
acf = map.getACF([1,2,3]); % Autocorrelation function at lags 1,2,3
// Java: MAP representation conversions
import jline.lang.processes.MAP;
import jline.lang.processes.MMDP;
import jline.util.matrix.MatrixCell;
MAP map = MAP.rand(3);
// Get time-reversed MAP (useful for queue analysis)
MAP mapReversed = map.toTimeReversed();
// Convert to MMDP for fluid queue analysis
MMDP mmdp = MMDP.fromMAP(map);
// Get renewal process (removes temporal correlation)
MatrixCell renewalProcess = map.getRenewalProcess();
// Extract moments and statistics
double meanInterarrival = map.getMean();
double scv = map.getSCV();
double skewness = map.getSkewness();
Compatibility Notes
LINE's MAP/PH format is compatible with:
- BUTools - Direct compatibility with D0/D1 matrices for MAPs and alpha/T for PH distributions
- M3A toolbox - LINE includes M3A for fitting Markovian Arrival Processes from traces
- KPC Toolbox - LINE includes KPC for Kronecker product composition and fitting
- QMAM Toolbox - Queueing and Matrix-Analytic Methods using MAP/PH inputs
- External tools - Export D0/D1 matrices as standard arrays for use in other software
REST API Interface
LINE provides a RESTful API for solving queueing models programmatically over HTTP. This enables integration with web applications, microservices, and any language that can make HTTP requests.
Starting the REST API Server
# Start REST API server on default port (8080)
python line.py rest
# Start on custom port
python line.py rest -p 9000
# Using the JAR directly
java -jar jline.jar -r 8080
// Start REST server programmatically
import jline.api.REST;
// Start server on port 8080
REST.start(8080);
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/solve | POST | Solve a queueing model. Accepts model in request body with solver options as query parameters. |
/health | GET | Health check endpoint. Returns server status. |
Solve Endpoint Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
solver | Query | auto | Solver algorithm: auto, ctmc, des, fld, jmt, ln, lqns, mam, mva, nc, qns, ssa |
format | Query | jsimg | Input format: jsim, jsimg, jsimw, lqnx, xml |
analysis | Query | all | Analysis type: all, avg, sys, etc. |
| Body | Request | - | Model content (XML for JSIM/JSIMG, or JSON) |
Example Request
# Solve a JSIMG model using MVA solver
curl -X POST "http://localhost:8080/solve?solver=mva&format=jsimg" \
-H "Content-Type: application/xml" \
-d @mymodel.jsimg
# Health check
curl http://localhost:8080/health
import requests
# Read model file
with open('mymodel.jsimg', 'r') as f:
model_content = f.read()
# Solve using REST API
response = requests.post(
'http://localhost:8080/solve',
params={'solver': 'mva', 'format': 'jsimg'},
headers={'Content-Type': 'application/xml'},
data=model_content
)
# Parse results
results = response.json()
print(results)
// Solve a model using fetch API
async function solveModel(modelContent) {
const response = await fetch(
'http://localhost:8080/solve?solver=mva&format=jsimg',
{
method: 'POST',
headers: { 'Content-Type': 'application/xml' },
body: modelContent
}
);
const results = await response.json();
console.log(results);
return results;
}
// Health check
fetch('http://localhost:8080/health')
.then(r => r.json())
.then(console.log);
Response Format
The REST API returns JSON responses with the following structure:
{
"success": true,
"execution_time": 0.123,
"avgTable": [
{"station": "Queue1", "class": "Class1", "metric": "QLen", "value": 2.5, "unit": ""},
{"station": "Queue1", "class": "Class1", "metric": "Tput", "value": 0.8, "unit": ""}
],
"sysTable": [
{"station": "Chain1", "class": "Class1", "metric": "SysRespT", "value": 3.125, "unit": ""}
]
}