> ## Documentation Index
> Fetch the complete documentation index at: https://calcs.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Equation Functions

> Custom functions available in Calcs Builder for equation writing, widget references, iteration, and solvers

Calcs Builder uses **[Math.js](https://mathjs.org/docs/index.html)** as the core engine for writing equations. You can use the full Math.js library for standard math, units, matrices, and more:

* [Basic syntax](https://mathjs.org/docs/expressions/syntax.html): similar to MATLAB and other computer-algebra languages
* [Function reference](https://mathjs.org/docs/reference/functions.html): trig, logarithms, matrix ops, and more
* [Units reference](https://mathjs.org/docs/datatypes/units.html): all listed units are supported in the platform

<Warning>
  Do **not** use the `math.` prefix. Write `gcd(6, 15)`, not `math.gcd(6, 15)`.
</Warning>

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.

<Tip>
  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](#deprecated-functions) at the bottom.
</Tip>

***

## Pulling data from other widgets

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.

```
T(rowIndex, columnIndex)
```

* 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))
```

***

### matrixSubset(): Extract from a matrix

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))
```

***

### vectorSubset(): Extract from a vector

Extract a single element from a vector.

```
vectorSubset(vector, elementIndex)
```

* **elementIndex** is **1-based**

**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.

```
col(matrix, columnIndex)
```

* **columnIndex** is **1-based**

Math.js also has [`column()`](https://mathjs.org/docs/reference/functions/column.html) 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 |

<Warning>
  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`.
</Warning>

**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

#### [column()](https://mathjs.org/docs/reference/functions/column.html)

```
column(matrix, colNum)
```

Extracts a column as a column matrix.

#### [row()](https://mathjs.org/docs/reference/functions/row.html)

```
row(matrix, rowNum)
```

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:

```python theme={null}
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()`](https://mathjs.org/docs/reference/functions/map.html), 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})
```

***

### Related Math.js functions

#### 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.

#### map()

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](https://en.wikipedia.org/wiki/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               |

<Warning>
  Choose `maxIters` high enough to converge reliably, but low enough to avoid excessive computation.
</Warning>

#### 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`                                             |

<Tip>
  For a full walkthrough of `solveSecant()` applied to a demand-vs-capacity problem, see [Example: Using solveSecant()](/calcs_builder/solvesecant_example).
</Tip>

***

## Sheet state

### presetCode()

Returns the preset code used to open the sheet, as a string.

```
presetCode()
```

### unitSystem()

Returns the current unit system as a string (`"FPS"` or `"MKS"`).

```
unitSystem()
```

***

## Formatting strings

### defaultFormat(): Standard number format

Applies the Calcs.com standard number format so templates round consistently.

```
defaultFormat(number)
```

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:

```
ln(x)
log(x, e)
```

<Warning>
  Never use `log(x)` without an explicit base. Always write `log(x, base)` to avoid ambiguity.
</Warning>

### 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.

<Warning>
  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](/calcs_builder/widgets/equation_widget#conditional-logic) for the recommended pattern.
</Warning>

**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)
```

***

## Checks

### I(): Indicator function

Returns `1` if the condition is true, `0` if false. Useful as an on/off switch inside equations.

```
I(condition)
```

**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

<Warning>
  Do not use these in new templates.
</Warning>

### 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*` ``

### x(, true): Inputs-only table reference (deprecated)

Previously returned only input columns from a table to avoid circular references. Better reference patterns are now available.

### isNumber() (deprecated)

Use Math.js [`isNumeric()`](https://mathjs.org/docs/reference/functions/isNumeric.html) instead.
