Using Integrals and Sums in MML
Introduction
This document describes using JSim MML's built-in integral() and sum() functions. These functions are available in JSim versions 1.6.31 and above, however versions 1.6.60 and above offer significant extensions and improvements. If you use pre-1.6.60 versions, or share models with those who do, you should pay particular attention to legacy support comments.
Prerequisites:
- Introductory Survey of MML (required)
- Introduction to the JSim GUI (recommended)
Contents:
Integrals
There are two basic forms for integral(), which represents standard Reimann integration:
integral(t=min to max, expr)
integral(expr@t)
where t is a realDomain, expr is the expression to be integrated, and min and max are the bounds of integration. Description of the latter form may be found in the legacy support section of this document.
Two common uses of first integral() form are demonstrated below:
// 2 examples of integral() operator
unit conversion on;
import nsrunit;
math integral1 {
realDomain t sec; t.min=0; t.max=5; t.delta=1; // time (seconds)
real u(t) = t^2 * (1 m/sec^2); // u (meters)
real v(t) = integral(t=t.min to t, u); // v (meter*sec)
real w = integral(t=t.min to t.max, u); // w (meter*sec)
}
(Java plugin required)
Here v(t) represents the integral of u up to the current time. w represents the integral u over all time. Both v(t) and w will be assigned units m*sec, since an integral's units are the product of the units of the integrated quantity and the units of the variable of integration. Like other MML functions, integral() will generate unit conversion errors if it is used in an inappropriate context.
While integrating from t.min to t.max or from t.min to t are the most common uses, the integrals may be between any two values to t. Also, the expression integrated need not be a simple variable:
integral(t=t.min+1 to t/2, u^2*exp(-v))
Another common usage is to "integrate out" one domain of a multi-dimensional variable:
// "integrating out" one variable domain
unit conversion on;
import nsrunit;
math integral2 {
realDomain t sec; t.min=0; t.max=6; t.delta=1; // time (seconds)
realDomain x m; x.min=0; x.max=1; x.delta=0.1; // space (meters)
real u(t,x) = t^2*(1 mole/sec^2) + x^2*(1 mole/m^2); // u (mole)
real v(t) = integral(x=x.min to x.max, u); // v (mole*meters)
}
(Java plugin required)
The standard integral function above is calculated internally by creating a private ODE variable and equation that uses JSim's internal ODE solvers. This calculation is thus somewhat dependent upon run-time ODE configuration. Under the default ODE configuration, an adaptive ODE solver is uses, so this calculation is largely independent of grid resolution. The legacy integral function uses a different (trapezoidal) calculation, see below for details.
Sums
The basic form for sum(), which represents series summation of a variable over points of its domain, is similar to integral():
sum(t=min to max, expr)
where t is a realDomain, expr is the expression to be summed, and min and max are the limits of the sum. This function is currently limited to summing from t.min to t.max, and other requests will generate MML compilation errors. This limitation will be addressed in the near future.
A common use of sum() is as follows:
// simple use of sum() operator
unit conversion on;
import nsrunit;
math sum1 {
realDomain t sec; t.min=0; t.max=5; t.delta=1; // time in seconds
real u(t) = t * (3 m/sec); // u in meters
real w = sum(t=t.min to t.max, u); // w in meters
}
(Java plugin required)
Note that, in contrast with integral(), the unit of a sum is the same as the expression being summed. As with integral(), sum() will generate unit conversion errors if it is used in an inappropriate context.
"Summing out" one domain of a multi-dimensional variable is a common usage:
// "summing out" one variable domain
unit conversion on;
import nsrunit;
math sum2 {
realDomain t sec; t.min=0; t.max=6; t.delta=1;
realDomain x m; x.min=0; x.max=1; x.delta=0.1;
real u(t,x) = t^2*(1 mole/sec^2) + x^2*(1 mole/m^2); // u in mole
real v(t) = sum(x=x.min to x.max, u); // v in mole
}
(Java plugin required)
Legacy Support
IMPORTANT NOTE: As of 1.6.62, the legacy form integral(expr@t) functions in a manner compatible with pre-1.6.60 version (i.e. the trapezoidal rule) due to unresolved JSim planner issues. This means that the standard form and the legacy form will calculate different numerical results in situations where they both work. This admittedly regrettable situation is hoped to be rectified in the near future. In the meantime, however, different models may need to use different forms to achieve best results.
The following applies to JSim version 1.6.31 to 1.6.59 and to models written for users of these older versions.
integral() and sum() were implemented as JSim class functions , and thus used the @ operator. The following are equivalent statements:
sum(u@t) sum(t=t.min to t.max, u)
integral(u@t) integral(t=t.min to t.max, u)
Integration and summation over sub-ranges of a domain was not supported. The @ syntax will supported in post 1.6.60 releases for compatibility sake. At some later time, this "compatibility mode" will be deprecated and eventually phased out. There is no compatibility support for nested @'s or @less arguments, e.g. sum(u@t@x) or sum(u).
The legacy integral() form is computed via trapezoidal approximation rather than via JSim's internal ODE solvers (as it is in the standard form above). This results in accuraccy that varies with grid resolution and (if a large number of intergrals are calcuated) slower performance. The formula used here is as follows:
integral(u@t) = (u(t.min)/2 + u(t.min+t.delta) + u(t.min+2*t.delta) + ... +
u(t.max-t.delta) + u(t.max)/2) * t.delta;
Unit correction is not supported for integral and sum operators. You should use these integral and sum only to calculate variables whose units are explicitly declared. Note that sum(u@x) returns a value with the same units as u, while integral(u@x) returns a value with the units the product of u and x:
// use of legacy sum() and integral() operators
unit conversion on;
import nsrunit;
math legacy {
realDomain x sec; x.min=0; x.max=1; x.delta=.1;
real u(x) = x * (5 kg/sec); // u will have units kg
real usum;
usum = sum(u@x); // sum() has save units as u
real uint;
uint = integral(u@x); // integral() has product of u & x units
}
(Java plugin required)
Limitations
The variable of integration must be a declared realDomain. In the future, it is hoped that the variable of integration may be dynamically created, allowing line integrals, surface integrals, convolution and other goodies.
Currently, sum() support summation only over the entire domain range. The following construction will generate a compilation error:
sum(t=t.min to t, u)
Integration/summation limits outside the domain range are not calculated. Therefore, is is always true that:
integral(t=t.min-1 to t.max+1, u) = integral(t=t.min to t.max, u)
Integrals with limits other than t.min, t and t.max are calculated via variable interpolation and are subject to the same accuraccy and planning limitations.
[This page was last modified 03Mar08, 3:11 pm.]
Model development and archiving support at physiome.org provided by the following grants: NIH/NHLBI T15 HL88516-01 Modeling for Heart, Lung and Blood: From Cell to Organ, 4/1/07-3/31/11; NSF BES-0506477 Adaptive Multi-Scale Model Simulation, 8/15/05-7/31/08; NIH/NHLBI R01 HL073598 Core 3: 3D Imaging and Computer Modeling of the Respiratory Tract, 9/1/04-8/31/09; as well as prior support from NIH/NCRR P41 RR01243 Simulation Resource in Circulatory Mass Transport and Exchange, 12/1/1980-11/30/01 and NIH/NIBIB R01 EB001973 JSim: A Simulation Analysis Platform, 3/1/02-2/28/07.
