Skip to main content

Unary Mathematical Functions

HelixQL provides a rich set of single-argument mathematical functions for transforming numeric values, including absolute values, roots, logarithms, exponentials, and rounding operations.

Available Functions

ABS - Absolute Value

ABS(x)  // Returns |x|
Returns the absolute value of a number.

SQRT - Square Root

SQRT(x)  // Returns √x
Returns the square root of a non-negative number.

LN - Natural Logarithm

LN(x)  // Returns ln(x)
Returns the natural logarithm (base e) of a positive number.

LOG10 - Base-10 Logarithm

LOG10(x)  // Returns log₁₀(x)
Returns the base-10 logarithm of a positive number.

LOG - Custom Base Logarithm

LOG(x, base)  // Returns log_base(x)
Returns the logarithm of x with a custom base.

EXP - Exponential

EXP(x)  // Returns e^x
Returns e raised to the power of x.

CEIL - Ceiling

CEIL(x)  // Returns ⌈x⌉
Rounds up to the nearest integer.

FLOOR - Floor

FLOOR(x)  // Returns ⌊x⌋
Rounds down to the nearest integer.

ROUND - Round

ROUND(x)  // Returns round(x)
Rounds to the nearest integer.
When using the SDKs or curling the endpoint, the query name must match what is defined in the queries.hx file exactly.

Example 1: Distance calculations with SQRT

Calculate Euclidean distances between points:
QUERY CalculateDistances() =>
    points <- N::Point
        ::{
            x, y,
            distance_from_origin: SQRT(ADD(POW(_::{x}, 2.0), POW(_::{y}, 2.0))),
            rounded_distance: ROUND(SQRT(ADD(POW(_::{x}, 2.0), POW(_::{y}, 2.0))))
        }
    RETURN points

QUERY CreatePoint(x: F64, y: F64) =>
    point <- AddN<Point>({ x: x, y: y })
    RETURN point
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create points
points = [
    {"x": 3.0, "y": 4.0},
    {"x": 5.0, "y": 12.0},
    {"x": 8.0, "y": 15.0},
]

for point in points:
    client.query("CreatePoint", point)

result = client.query("CalculateDistances", {})
print("Point distances:", result)

Example 2: Logarithmic scaling with LN and LOG10

Use logarithms for normalization and scaling:
QUERY NormalizeMetrics() =>
    metrics <- N::Metric
        ::{
            value,
            log_scale: LN(_::{value}),
            log10_scale: LOG10(_::{value}),
            custom_log: LOG(_::{value}, 2.0)
        }
    RETURN metrics

QUERY CreateMetric(value: F64) =>
    metric <- AddN<Metric>({ value: value })
    RETURN metric
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create metrics with various scales
values = [1.0, 10.0, 100.0, 1000.0, 10000.0]

for value in values:
    client.query("CreateMetric", {"value": value})

result = client.query("NormalizeMetrics", {})
print("Normalized metrics:", result)

Example 3: Exponential decay with EXP

Model time-based decay using exponential functions:
QUERY CalculateDecayFactors(decay_rate: F64) =>
    items <- N::Item
        ::{
            name, age_days,
            decay_factor: EXP(MUL(decay_rate, _::{age_days})),
            relevance_score: MUL(_::{base_score}, EXP(MUL(decay_rate, _::{age_days})))
        }
    RETURN items

QUERY CreateItem(name: String, age_days: F64, base_score: F64) =>
    item <- AddN<Item>({ name: name, age_days: age_days, base_score: base_score })
    RETURN item
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create items with different ages
items = [
    {"name": "Recent Post", "age_days": 1.0, "base_score": 100.0},
    {"name": "Week Old Post", "age_days": 7.0, "base_score": 100.0},
    {"name": "Month Old Post", "age_days": 30.0, "base_score": 100.0},
]

for item in items:
    client.query("CreateItem", item)

# Apply decay rate of -0.1 per day
result = client.query("CalculateDecayFactors", {
    "decay_rate": -0.1
})

print("Decay factors:", result)

Rounding Functions

CEIL, FLOOR, and ROUND provide different rounding behaviors:
CEIL(3.2)   // Returns 4.0
FLOOR(3.8)  // Returns 3.0
ROUND(3.5)  // Returns 4.0
ROUND(3.4)  // Returns 3.0
Use rounding for display formatting or bucketing:
QUERY BucketScores() =>
    items <- N::Item
        ::{
            raw_score,
            bucket: MUL(FLOOR(DIV(_::{raw_score}, 10.0)), 10.0)
        }
    RETURN items

Domain Restrictions

Some functions have domain restrictions:
  • SQRT(x): x must be non-negative
  • LN(x), LOG10(x), LOG(x, base): x must be positive
  • LOG(x, base): base must be positive and not equal to 1

Use in Weight Calculations

Unary math functions are powerful in shortest path weight calculations:
// Exponential time decay
::ShortestPathDijkstras<Route>(
    MUL(_::{distance}, EXP(MUL(-0.05, _::{days_old})))
)

// Logarithmic scaling for large values
::ShortestPathDijkstras<Connection>(
    LOG10(ADD(_::{traffic}, 1.0))
)