Calcs Builder uses Math.js as the core engine for writing equations. You can use the full Math.js library for standard math, units, matrices, and more:
Do not use the math. prefix. Write gcd(6, 15), not math.gcd(6, 15).
On top of Math.js, Calcs Builder adds custom functions to help you reference other widgets, iterate over data, interpolate, format output, and run numerical solvers. The sections below cover those custom functions.
To reference another widget by its reference ID, use the ID directly (for example L, M_u, or `M*`). The older x() wrapper is deprecated. See Deprecated functions at the bottom.
These functions let you read values from lookup widgets, tables, and other fields.
L(): Lookup reference
Use L() to read a value from a lookup or shared lookup widget.
L(referenceId, columnIndex)
- columnIndex is 0-based (left-most column =
0)
- The row comes from the userβs selection, or the lookupβs default row (also 0-based from the top)
Example: Read column 7 from a shared lookup called member, and multiply by elastic modulus E:
E * L("member", 7) * 10 ^ (-3)
T(): Internal table reference
Use T() inside a table widget to reference cells in that same table, typically in a computed column.
- Row and column indices are 0-based
rowIndex() and colIndex() are built-in properties of each cell and can be used on their own or inside T()
Examples:
T(rowIndex(), 0) // first column of the current row
T(0, 1) // cell at row 0, column 1
Computed column example: allowable deflection is the minimum of span-ratio limit and a fixed mm limit:
min(L / T(rowIndex(), 0), T(rowIndex(), 1))
Extract one or more elements from a matrix (table or computed field).
matrixSubset(target_matrix, rowIndex, columnIndex)
- rowIndex and columnIndex are 1-based (unlike
L() and T())
Example: Read row 1, column 3 from a load-case matrix LC_str:
abs(matrixSubset(LC_str, 1, 3))
Extract a single element from a vector.
vectorSubset(vector, elementIndex)
Example: Read the 2nd element of a remote vector firstQuarterBM:
vectorSubset(remote.firstQuarterBM, 2)
col(): Extract a column (as a row matrix)
Returns an entire column as a row matrix [[a, b, c]]. Useful for server-returned data.
Math.js also has column() with the same syntax, but it returns a column matrix [[a], [b], [c]] instead.
Example: Find the maximum value in column 6 of a remote result:
max(col(matrix(remote.member), 6))
interpolate(): Interpolate from 2D or 3D data
Interpolate a value from tabulated data. X-coordinates (and Y-coordinates for 3D) must be in ascending order.
2D data
interpolate(xMatrix, xLoc, xCoords [, "log"])
| Argument | Description |
|---|
xMatrix | 1ΓN matrix of values to interpolate between |
xLoc | Scalar. The x-position at which to interpolate |
xCoords | N-length array of x-coordinates (ascending) |
"log" | Optional. Use logarithmic instead of linear interpolation |
If xLoc is outside the range of xCoords, the function returns the value at the nearest edge. For example, with xCoords = [1, 2, 3] and xMatrix = [0, 5, 10], evaluating at xLoc = 4 returns 10.
Example:
interpolate([0, 5, 10], 1.5, [1, 2, 3])
3D data
interpolate(xyMatrix, xLoc, xCoords, yLoc, yCoords [, "log"])
| Argument | Description |
|---|
xyMatrix | MΓN matrix of values |
xLoc, xCoords | Interpolation along the x-axis |
yLoc, yCoords | Interpolation along the y-axis |
"log" | Optional. Logarithmic interpolation |
Built-in Math.js matrix helpers
Extracts a column as a column matrix.
Extracts a row as a row matrix.
Iterating over a set of data
setSum(): Summation over a range
Sum an expression over an integer range, like Ξ£ in mathematics.
setSum(from, to, expression, "variable")
from and to are inclusive
- The last argument is the loop variable name (as a string)
Example: Sum column 2 of table PL across all rows:
setSum(1, vectorSubset(size(PL), 1), matrixSubset(PL, j, 2), "j")
Here vectorSubset(size(PL), 1) gives the number of rows, and j steps from 1 to that count.
iterate(): Build an array by looping
Like setSum, but returns an array of results instead of a single sum. You control the step size.
iterate(from, to, step, expression, variable)
from and to are inclusive
Equivalent Python logic:
results = []
for variable in range(from, to + 1, step):
results.append(expression)
Number sequence example: list support numbers from 1 to the row count of matrix r:
iterate(1, vectorSubset(size(r), 1), 1, n_supp, n_supp)
Conditional string example:
iterate(1, 10, 1, num <= 5 ? "small number" : "big number", num)
deepReplace(): Find-and-replace inside a structure
Performs a string find-replace deep inside a matrix, object, or other nested structure. Commonly used in upgrade mappings.
deepReplace(dataStructure, findString, replaceString)
Example: Rename key L to L_total inside a supports table:
deepReplace(input("supports"), "L", "L_total")
mapObject(): Map over object entries
Works like Math.js map(), but iterates over object key-value pairs instead of matrix rows.
mapObject(object, function)
Example:
mapObject(myObj, f(key, value) = {key: concat(key, "_2"), value: 2 * value})
matrixFromFunction()
Generate a matrix by evaluating a function at each coordinate:
matrixFromFunction([2, 3], f(i) = i[1] + i[2])
// β [[0, 1, 2], [1, 2, 3]]
Similar to iterate(), but the loop variable i is a coordinate array, not a simple integer.
Apply a function to every element of a matrix (same size in, same size out):
map([[1, 2], [3, 4]], f(value) = value^2)
// β [[1, 4], [9, 16]]
toArray()
Convert a matrix to a plain array:
col(perStory, 1).toArray()
Solvers
solveSecant(): Secant method root finder
Finds the root of a single-variable equation using the secant method. Provide two initial guesses and the solver iterates until convergence or until it hits the iteration limit.
solveSecant(guess0, guess1, convergenceCriterion, maxIters, fnEquation)
| Argument | Description |
|---|
guess0, guess1 | Two starting guesses for the unknown (same units as the variable) |
convergenceCriterion | Stop when successive iterations differ by less than this value (same units) |
maxIters | Maximum iterations (unitless integer). Exceeding this throws an error |
fnEquation | The equation as a function of one variable, set equal to zero |
Choose maxIters high enough to converge reliably, but low enough to avoid excessive computation.
Example 1: Neutral axis location
Find kd where force equilibrium equals zero:
solveSecant(
k_ub * d_x,
d_x,
0.0001 mm,
100,
f(kd) = B * gamma * alpha2_fc * kd
+ setSum(1, n_lr,
matrixSubset(reo_x, i, 4)
* max(-f_sy, min(f_sy, e_cu * (kd - matrixSubset(reo_x, i, 2)) / kd * E_s)),
"i")
)
Example 2: Shortest unbraced length
When moment capacity equals a target value, rearrange to f(x) = 0 and solve for x (representing unbraced length L_yr):
// Target: M_u(L_yr) - M_yr = 0
// M_yr = 0.7 * M_yx
solveSecant(
L_u_pos,
L,
0.0001 mm,
100,
f(x) = omega_3 * pi^2 * E * I_y / (2 * x^2)
* (beta_x_pos + sqrt(beta_x_pos^2 + 4 * (G * J * x^2 / (pi^2 * E * I_y) + C_w / I_y)))
- M_yr
)
| Parameter | Typical choice |
|---|
guess0 | L_u_pos, a value close to the expected root |
guess1 | L, a second guess near the expected root |
convergenceCriterion | 0.0001 mm, accurate to ~3 decimal places in mm |
maxIters | 100 |
Sheet state
presetCode()
Returns the preset code used to open the sheet, as a string.
unitSystem()
Returns the current unit system as a string ("FPS" or "MKS").
Applies the Calcs.com standard number format so templates round consistently.
Advanced options (use only when well justified):
defaultFormat(number, sigFigs, intRange)
| Argument | Default | Description |
|---|
sigFigs | 3 | Significant figures |
intRange | [0, 1000] | Range within which to show exact integers. Use null for infinity (e.g. [1000, null] shows exact integers above 1000) |
print(): String templates
Concatenate a formatted string with variable substitution. Useful for export labels and diagram text.
print('Vert: $v_t x $v_w x $v_y MPa',
{v_t: matrixSubset(T, 1, 2),
v_w: matrixSubset(T, 1, 3),
v_y: matrixSubset(T, 1, 4)})
// β "Vert:10x200x250MPa"
Miscellaneous
maxIndex() / minIndex()
Return the 1-based index of the maximum or minimum value in an array.
maxIndex(array)
minIndex(array)
ln(): Natural logarithm
Math.js renders natural logs as ln() but does not provide an ln() function. Use either:
Never use log(x) without an explicit base. Always write log(x, base) to avoid ambiguity.
isIncluded()
Check whether a value exists in an array.
isIncluded(1, [1, 2, 3, 4, 5]) // β true
Conditional logic in equations
Math.js supports the ternary operator ? : for inline conditionals inside a single expression:
condition ? valueIfTrue : valueIfFalse
Examples:
loadType == "tension" ? 0.9 : 0.75
panel_ornt == "Landscape Vert. Rails" ? pnlX : pnlY
num <= 5 ? "small number" : "big number"
You can nest ternaries to handle multiple cases in one line, but expressions get hard to read and maintain quickly.
We do not recommend relying on ? : for most equation widgets. Prefer the If interface in the equation widget instead: add separate rows with a condition and result, and use @default as the fallback. It keeps logic easier to read, debug, and update.See Equation Widget: Conditional Logic for the recommended pattern.
Recommended approach (If interface):
// Row 1: condition = loadType == "tension", result = 0.9
// Row 2: condition = loadType == "compression", result = 0.85
// Row 3: condition = @default, result = 0.75
Inline alternative (works, but use sparingly):
loadType == "tension" ? 0.9 : (loadType == "compression" ? 0.85 : 0.75)
I(): Indicator function
Returns 1 if the condition is true, 0 if false. Useful as an on/off switch inside equations.
Example: Conditionally add an angle leg height depending on a lookup selection:
d_b <= L("memberPFC", 2)
- (I(L("Angle Vertical Leg", 1) == 0) * L("memberAngle", 1)
+ I(L("Angle Vertical Leg", 1) == 1) * L("memberAngle", 2))
When multiplied by a value, I() acts like a conditional gate. The term only contributes when its condition is true.
Deprecated functions
Do not use these in new templates.
x(): Field reference (deprecated)
Previously required to reference another widget. Now use the reference ID directly:
// Old
x("L")
// Current
L
For string IDs with special characters, use backticks: `M*`
Previously returned only input columns from a table to avoid circular references. Better reference patterns are now available.
isNumber() (deprecated)
Use Math.js isNumeric() instead.