SipMath 3.1 library

Revision as of 19:03, 21 October 2026 by Lchrisman (talk | contribs) (New page: SipMath 3.1 library)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


The SipMath 3.1 library lets you read and use uncertainty information that's stored in the SIPmath 3.1 Standard format, published by ProbabilityManagement.org. A SIPmath file is a JSON document holding a library of named uncertain quantities (SIPs) and the relationships between them. With this library, you can bring those quantities into an Analytica model as ordinary uncertain values, evaluate specific numbered trials, and export Metalog distributions as SIPmath JSON.

Download

Download all three files and save them in the same folder:

If Analytica asks you to locate a library file when you open the model, point it to the file you downloaded. (Your browser might replace the spaces in the file names with underscores.)

Requires Analytica 7.2 or later.

Getting started

This section helps you start using the SipMath 3.1 library. You don't need to understand how the library works internally. Begin with the example model, then follow the same pattern with your own SIPmath file.

By the end, you'll be able to:

  • Explore a supplied uncertainty library.
  • Bring its uncertain quantities into your model.
  • Calculate outcomes and view their uncertainty.
  • Repeat an analysis using the same underlying trials.

When would I use this library?

Use the library when you have uncertainty information in SIPmath format and want to make it part of an Analytica model. For example, a colleague might supply uncertain demand, costs or delivery times. Instead of replacing that information with a single estimate, you can use the supplied distributions in your calculations.

The library is particularly helpful when:

  • Someone has shared a SIPmath file with you. You want to use its uncertain quantities without recreating them manually.
  • Several uncertain quantities belong together. You want to retain their supplied relationships when combining them.
  • You need repeatable scenarios. You want to compare decisions using the same underlying uncertain conditions.
  • You already have Metalog coefficients. You want to turn those into uncertain values in Analytica, or prepare a single-distribution SIPmath document to share.

If you're simply assessing a new uncertainty directly in Analytica, you can continue using Analytica's usual probability distributions. This library is most useful when sharing, reusing or reproducing SIPmath uncertainty information.

Three terms you'll encounter

  • SIP: an uncertain quantity packaged for reuse.
  • Library: a collection of named SIPs, potentially with relationships between them.
  • Trial: one simulated realization. When quantities belong to the same simulation, trial 1 of each quantity belongs together, trial 2 belongs together, and so on. Think of each trial as one possible version of events.

Explore the example model

Open the Test SipMath 3.1 model. The SipMath library is already included, so you can begin immediately.

Step 1 — Look at the trial values

  1. Select Example Trials on the main diagram.
  2. Press Ctrl+R to open its result window.
  3. Choose Table if a graph appears.

You'll see named quantities and numbered trials. Each value is one realization of one quantity. Read across the quantities for a single trial to see one shared scenario. Read through the trials for one quantity to see how its value varies.

Try this: Note the value of Accounts at trial 1. It should be approximately 5.910648. Reopening the same result reproduces that value.

Step 2 — Look at the uncertainty rather than individual trials

  1. Return to the main diagram and select Example Sample.
  2. Press Ctrl+R.
  3. Choose Statistics from the uncertainty view selector in the result window.
  4. Use the SIP Name selector to choose a quantity if needed.

Statistics gives you a more useful overview than inspecting trials one by one. Start by comparing the mean and median, then look at the spread of outcomes. Next, choose PDF and Graph to explore the distribution's shape. Choose CDF when you want to read the probability of an outcome being at or below a threshold.

Viewing tip: For quantities created with SIP_Sample, the Mid value shows trial 1, not a mean or median. Use Mean value or Statistics when you want a summary of the uncertainty.

Step 3 — See the simple pattern behind the example

The example uses three pieces:

Piece What it does
Example Library Holds the imported SIPmath information
SIP Name Lists the quantities available in that library
Example Sample Makes those quantities available as uncertain inputs

You can use the same pattern in your own model.

Bring in your own SIPmath file

For your first import, work in the example model, where the library is already available. Keep the original examples so you can return to them. The following steps describe new nodes for you to create. Copy the Definitions exactly, changing only the file path where indicated.

Step 1 — Read your file

Create a Variable titled My SIP Library, with identifier My_SIP_Library, and give it this Definition:

SIP_Parse(ReadTextFile('MyLibrary.SIPmath'))

Replace MyLibrary.SIPmath with your file's name or full path. Use a full path if the file isn't in the model's folder. This node holds the imported information. You don't have to open or edit the JSON yourself to use the quantities it contains.

Step 2 — Discover the available quantities

Create an Index titled My SIP Names, with identifier My_SIP_Names, and Definition:

SIP_Names(My_SIP_Library)

Open its result to see the names in your file. These are the names you'll use when choosing individual quantities.

Step 3 — Make the quantities available for simulation

Create a Chance variable titled My SIP Sample, with identifier My_SIP_Sample, and Definition:

SIP_Sample(My_SIP_Library, My_SIP_Names)

Open the result and select Statistics. You now have the library's quantities available as uncertain values in Analytica.

Pause here: check that you recognize the quantity names and understand their units. These values will become inputs to your model, so treat them with the same care as any other supplied data.

Use one quantity in a calculation

You'll often want a separate node for a quantity such as demand, cost or duration. This makes the rest of your diagram easier to read.

Step 1 — Select a named quantity

For a practice exercise using the example, create a Chance variable titled Accounts Sample, with identifier Accounts_Sample:

SIP_Sample(Example_Library, 'Accounts')

For your own file, replace Example_Library with My_SIP_Library and replace 'Accounts' with a name from My SIP Names. Keep the name inside quotes.

Step 2 — Calculate an outcome

For this exercise only, suppose Accounts represents account count and each account earns a fixed fee of 100 currency units. Create a Variable titled Fee Revenue, with identifier Fee_Revenue:

100 * Accounts_Sample

Open Fee Revenue and choose Statistics. Revenue is now uncertain because its input is uncertain. You didn't have to write a loop or calculate each trial separately. In a real model, replace the fixed fee with a decision or input node and continue building your model normally.

Step 3 — Compare a decision

Try a fee of 120 instead of 100, assuming account count is unaffected by price for this exercise. Recalculate and compare the mean and range of revenue.

The underlying Accounts scenarios remain the same. You're comparing two decisions under the same uncertain conditions, rather than changing both the decision and the scenarios at once.

Keep related quantities together

If your library supplies related quantities, use them from the same imported library without rearranging their trial order. For example, if your file contains Revenue and Cost, create separate Chance variables:

Revenue Sample (Revenue_Sample):

SIP_Sample(My_SIP_Library, 'Revenue')

Cost Sample (Cost_Sample):

SIP_Sample(My_SIP_Library, 'Cost')

Then define Profit:

Revenue_Sample - Cost_Sample

Substitute the actual names from your file. Analytica combines corresponding simulated outcomes, keeping the supplied scenarios aligned.

Good habit: Combine the uncertain values first, then inspect the outcome's Statistics or graph. Don't replace each input with its mean before calculating an uncertain outcome.

Choose the view that answers your question

Your question Start with
What is the expected outcome? Mean Value
What are the typical outcome and spread? Statistics
What shape does the uncertainty have? PDF
How likely is an outcome at or below a threshold? CDF
How likely is an outcome above a threshold? Exceedance Probability
What happened in individual scenarios? Sample

Use Table for precise values and Graph for patterns. Changing the view doesn't change the underlying SIP definitions.

Inspect a few repeatable trials

Sometimes you want a small table you can discuss with a colleague or compare across tools. Create an Index titled My Trials, with identifier My_Trials:

1..10

Then create a Variable titled My Trial Values, with identifier My_Trial_Values:

SIP_Evaluate(My_SIP_Library, My_SIP_Names, My_Trials)

Open its result as a table. This shows the first ten trials explicitly. Use SIP_Sample for everyday uncertainty analysis. Use SIP_Evaluate when you want particular numbered trials.

Explore the native-array example when you're ready

Open Native Array Examples in the example model. Start with Product Trials, then open Product Sample in Statistics view. These demonstrate several product distributions calculated together.

This route is useful when you already have Metalog coefficients in Analytica rather than a SIPmath file. Treat it as a second learning step: get comfortable importing and using named SIPs first, then explore the coefficient-based example if your work needs it.

Your everyday workflow

  1. Import once: Create a node holding the parsed library.
  2. Find the names: Inspect the available quantities.
  3. Choose your inputs: Create Chance variables with SIP_Sample.
  4. Build your calculations: Use those variables like other uncertain inputs.
  5. Read the outcome: Start with Statistics, then use graphs for the questions you care about.
  6. Compare decisions: Retain the same library and scenarios while changing your decision inputs.
  7. Save your work: Save the model and keep the source SIPmath file with the project.

For a first successful session, aim to import one library, use one named quantity in a calculation, and explain the resulting uncertainty to someone else.

Reference

Library organization

The library has two parts:

  • SIP JSON: Functions that read SIPmath JSON documents and evaluate the SIPs they contain, including parameters, environment alternatives and calibration metadata.
  • SIP Numeric: Array-based building blocks for working directly with uniforms, Metalog quantiles, copulas, discrete lookup tables, stored trials and rounding.

A parsed SIPmath document is held as a parsed JSON struct, which keeps the metadata and variable-length definitions together. Simulation values are ordinary Analytica arrays. The numerical functions use only their declared coefficient, category or matrix indexes; any other indexes, such as trial, product or scenario indexes, pass through by array abstraction.

You control the important output dimensions. For example,

SIP_Evaluate(Example_Library, SIP_Name, Trial)

returns a result indexed by exactly SIP_Name and Trial.

Trials and coherence

Trial numbers are explicit, positive and 1-based. Equal seeds and trial numbers always reproduce the same values, and different SIPs are never independently permuted, recycled or resampled. This is what keeps the trials of related SIPs coherent: trial n of every SIP in a library belongs to the same scenario.

SIP_Sample connects SIPs to Analytica's uncertainty evaluation:

  • In Sample mode, it uses Run as the trial number, so the sample size determines how many trials are used.
  • In Mid mode, it returns trial 1, not a mean or median. Use Mean, Median, etc. for summaries.

Increasing the sample size preserves the existing trials of a virtual SIP and adds new ones at the end. The HDR stream values are governed by their own seeds, not by Analytica's random seed or sampling method. Stored SIPs (those containing a fixed array of trials) can't be extended: requesting more trials than are stored is an error.

Reading SIPmath JSON

Parse a document once, in a variable:

SIP_Parse(ReadTextFile('MyLibrary.SIPmath'))

Use the names as an Index Definition to create a stable output dimension:

SIP_Names(My_SIP_Library)

Evaluate a named SIP at a particular trial:

SIP_Evaluate(Example_Library, 'Accounts', 1) → 5.91064824323855

Evaluate indexed names and trials:

SIP_Evaluate(Example_Library, SIP_Name, Trial)

Define a Chance variable using:

SIP_Sample(Example_Library, SIP_Name)

Supported SIPmath features

Feature Behavior
HDR_2_0 The Hubbard HDR generator
Index generator Explicit trial counter, including PM_Index
Metalog_1_0 Legacy Metalog coefficients, 2 to 16 terms
Metalog_2_0 Metalog 2.0 coefficients, 2 to 16 terms
Bounds Unbounded, lower-bounded, upper-bounded and doubly bounded Metalogs
Integer rounding none, down, up and nearest
Lookup_Table Discrete distributions given by cumulative-probability/value pairs
GaussianCopula Correlated uniforms from a correlation matrix or its lower Cholesky factor
Matrices Named rows/columns with sparse row/col/value entries; a missing triangle of a correlation matrix is filled in symmetrically
SIP_Array Inline lists of trials, or columns of external data that you preload
multiDimSIP_Array Inline rectangular nested arrays, where the last dimension is trials
Stored copulas Inline layer-by-trial arrays, or preloaded named columns of uniforms
DIST Complete XML DIST strings, decoded using SipDecode
Environment alternatives Uses the entry for the requested environment if present, otherwise the environment-independent entry
Normal distributions Normal, CumNormalInv, PsiNormal and RiskNormal, using the specified uniform source
Calibration TrialN and calibrationTrials metadata
Metadata Retained, and accessible as struct members

Parameters

Some SIPmath libraries declare parameters, such as a user-entered seed. Supply their values as a struct whose member names match the declared parameter names:

SIP_Evaluate(
    SIP_Parse(Canonical_Parameters_JSON),
    'Variable2_seed3_param',
    Trial,
    parameters: ParseJSON('{"User-entered Seed3":1}')
)

References of type parameter resolve by name, and references of type globalVariables resolve to the library's named global-variable entries. A missing parameter is an error.

External resources and stored copulas

Importing a SIPmath document never starts a download, opens a workbook or runs code from the document. When a SIP refers to external csv or xlsx data, load that data into your model yourself (for example, with ReadTextFile or spreadsheet functions), and pass it in the «resources» parameter. «resources» is a struct whose members are named by the declared URLs; each member maps column names to lists of trials, in trial order. For example:

LocalIndex T := 1..3;
SIP_Evaluate(
    SIP_Parse(Synthetic_Stored_JSON),
    'External', T,
    resources: ParseJSON('{"fixture:data":{"X":[4,5,6]}}')
)

A missing resource is an error. Stored copulas work the same way: provide named columns of uniforms in shared trial order.

Functions

Optional parameters are shown in italics and the defaults are given in the description. Pass indexes as index identifiers, not as text.

SIP JSON functions

SIP_Parse(json)

Parses the SIPmath JSON text «json» and returns a parsed library, as a struct. Typically you'll use it with ReadTextFile:

SIP_Parse(ReadTextFile('MyLibrary.SIPmath'))

It checks that objectType is sipModel, that every SIP has a name, and that each name/environment pair is unique. The original metadata is preserved. Place the parsed library in a variable so the document is parsed only once.

SIP_Names(library)

Returns the unique SIP names in a parsed «library» as a list. When a SIP has alternatives for different environments, its name appears once. Use this as an Index Definition to give your model a stable index of SIP names.

SIP_Select(library, name, environment)

Returns the definition of the SIP named «name» from «library». If «library» has an entry for «environment» (default 'Analytica'), it returns that entry; otherwise it returns the environment-independent entry. It never substitutes an entry for a different environment. A missing or ambiguous name is an error.

SIP_Evaluate(library, name, trial, parameters, resources, environment)

Returns the value of the SIP named «name» from the parsed «library» at the trial number(s) «trial», which must be positive integers. «name» and «trial» can be indexed, and the result has their indexes.

  • «parameters»: A struct of parameter values (see Parameters).
  • «resources»: A struct of preloaded external data (see External resources).
  • «environment»: Which environment alternative to use. Default 'Analytica'.

Examples:

SIP_Evaluate(Example_Library, 'Accounts', 1) → 5.91064824323855
SIP_Evaluate(Example_Library, SIP_Name, Trial)

SIP_Sample(library, name, parameters, resources, environment)

The usual way to bring a SIP into a model as an uncertain quantity, typically used as the Definition of a Chance variable. In Sample mode, it returns the trials 1 to SampleSize, indexed by Run. In Mid mode it returns trial 1 (not a mean or median). The other parameters are as for SIP_Evaluate.

SIP_Sample(Example_Library, SIP_Name)

For a stored SIP, it is an error when the sample size is larger than the number of stored trials.

SIP_Calibration(library, name, trial, parameters, resources, atol, rtol, environment)

Checks the value of a SIP at «trial» against the expected value recorded in the library's metadata, taken from metadata.TrialN or else from metadata.calibrationTrials. It returns a struct with members name, trial, actual, expected, absoluteError and passed. It passes when

absoluteError <= atol + rtol * Abs(expected)

The defaults are «atol»=1e-6 and «rtol»=1e-8. When the library contains no expected value, passed is Null. It array-abstracts over «name» and «trial».

SIP_Export_Metalog(name, a, K, entity, varId, seed3, seed4, lowerBound, upperBound, version)

Creates SIPmath JSON text for a single virtual SIP named «name», from Metalog coefficients «a» indexed by «K». It uses the coefficients as they are, without fitting or refitting them. «entity», «varId», «seed3» and «seed4» are the HDR seeds, as for SIP_Uniform; «lowerBound», «upperBound» and «version» are as for SIP_Metalog. When «a» has other indexes, such as scenarios, you get a separate JSON document for each.

SIP_Export_Metalog(
    'Product A',
    Product_Coefficients[Product1 = 'A'],
    Metalog_Term,
    entity: 9039920, varId: 1
)

You can save the result to a file using WriteTextFile.

Lower-level JSON functions

Most models can use SIP_Evaluate instead of these.

  • SIP_Rng(library, name, trial, parameters): Evaluates the named HDR_2_0 or Index generator from U01.rng.
  • SIP_Copula(library, name, layer, trial, parameters, resources): Evaluates the named Gaussian or stored copula layer from U01.copula.
  • SIP_Source(library, ref, trial, parameters, resources): Evaluates the generator or copula layer that a SIP's ref refers to.

SIP Numeric functions

These work directly with Analytica arrays and don't need a SIPmath document.

SIP_Uniform(trial, entity, varId, seed3, seed4)

Returns the HDR_2_0 uniform values for the positive integer trial numbers «trial». The result is the same in Mid and Sample modes. «trial» and the seeds can have additional indexes. The SIPmath seeds correspond to the parameters of the Hubbard_HDR function as follows:

SIPmath field Hubbard_HDR parameter Default Range
«varId» seed1 1 1 to 100,000,000
«entity» seed2 1 0 to 100,000,000
«seed3» seed3 0 0 to 10,000,000
«seed4» seed4 0 0 to 10,000,000

So

SIP_Uniform(Trial, entity: 17, varId: 23, seed3: 4, seed4: 8)

is the same as

Hubbard_HDR(Trial, 23, 17, 4, 8)

Note that array abstraction alone doesn't make streams with identical seeds independent. When you want independent streams across, say, a product or scenario index, vary «varId» or another seed along that index.

SIP_Metalog(p, a, K, lowerBound, upperBound, version)

Returns the quantile at probability «p» of the Metalog distribution with coefficients «a», indexed by «K». «a» must have 2 to 16 coefficients, and «p» must be strictly between 0 and 1. The result has the indexes of «p» and «a» except «K».

  • «version»: 2 (the default) for Metalog 2.0 coefficients, or 1 for legacy Metalog coefficients.
  • «lowerBound», «upperBound»: Optional bounds. When both are given, «lowerBound» must be less than «upperBound».

With q the unbounded Metalog quantile, the bounds are applied as follows:

Bounds Result
None q
Lower only LB + exp(q)
Upper only UB − exp(−q)
Both LB + (UB − LB) / (1 + exp(−q))

Example from the example model:

SIP_Metalog(
    SIP_Uniform(Trial, entity: 9039920, varId: @Product1),
    Product_Coefficients, Metalog_Term
)

The result is indexed by Trial and Product1, but not Metalog_Term.

SIP_Gaussian_Copula(u, matrix, I, J, isCholesky)

Transforms independent uniforms «u», indexed by «I», into correlated uniforms using a Gaussian copula. «matrix» is indexed by «I» and «J», which must have the same length. Rows and columns are matched by position, so «I» and «J» can have different labels. The result is indexed by «I» and any other indexes of «u», such as trial or scenario.

Normally «matrix» is the correlation matrix of the latent normal variables, which must be positive definite. With «isCholesky»=True, «matrix» is instead a lower-triangular matrix L, where the correlation matrix is C = L LT, with unit row variances.

The correlation applies to the latent normal variables, so the correlation between the final (e.g., Metalog) values generally differs from it. The function transforms the uniforms you give it; it doesn't draw new samples or reorder them.

SIP_Lookup(p, cumulative, values, I)

Returns the first element of «values» whose «cumulative» probability is at least «p». This is the inverse CDF of a discrete distribution. «cumulative» and «values» are indexed by «I», which the result doesn't have; other indexes are kept. «cumulative» must be nondecreasing, between 0 and 1, have no missing values, and end at 1. «values» can be numbers or text.

SIP_Array_At(data, T, trial)

Returns the stored trials of «data» at the 1-based positions «trial» along index «T», regardless of «T»'s labels. Other indexes of «data» are kept. A fractional trial or a position beyond the stored data is an error; trials are never recycled or permuted.

SIP_Round(x, rounding)

Rounds «x» to an integer following the SIPmath convention, which matches Excel's rounding functions. «rounding» is one of:

«rounding» Meaning Result for −2.8
'none' (default) Unchanged −2.8
'down' Toward zero −2
'up' Away from zero −3
'nearest' Nearest integer; ties round away from zero −3

Note that 'down' differs from Floor for negative values.

See also

Comments
Loading comments...