class iint
The iint class is AADC’s active integer type for tracking integer operations in computational graphs, particularly for array indexing and mathematical operations that involve integer calculations.
Overview
iint is defined in aadc/iint.h and serves as a drop-in replacement for native int64_t when integer expressions depend on kernel inputs and need to be tracked in the valuation graph. This enables AADC to handle complex mathematical models involving array lookups, interpolation, and other operations that require integer indices computed from active random variables.
assert(sizeof(int64_t) == sizeof(iint)); // Always trueWhen to Use iint vs int64_t
Understanding when to use iint versus native integer types is crucial for correct AADC implementation:
| Scenario | Use Type | Reason |
|---|---|---|
| Dynamic indices | iint |
Index computed from kernel inputs or derived values |
| Static indices | int64_t |
Fixed array indices or loop counters |
Dynamic vs Static Integer Operations
Dynamic integer operations involve calculations that depend on kernel inputs and can vary between evaluations:
// Dynamic - index depends on kernel input
idouble x(2.5); // marked as input
iint index = aadc::toInt(x); // Convert to integer index
idouble result = aadcArrayOps::get(lookup_table, index);Static integer operations don’t depend on kernel inputs:
// Static - fixed array operations
for (int i = 0; i < array_size; ++i) { // Loop counter
process_element(array[i]);
}Internal State Flags
Similar to idouble, iint objects maintain internal flag IsRandom to indicate if they depend on stochastic inputs. This flag is managed automatically by AADC Core and propagates through operations.
Core Operations
Arithmetic Operations
iint supports standard integer arithmetic:
iint a(10), b(3);
iint sum = a + b; // Addition
iint diff = a - b; // Subtraction
iint product = a * b; // Multiplication
iint negative = -a; // Unary minusAssignment Operations
iint result;
result = a; // Assignment
result += b; // Add-assign
result -= b; // Subtract-assign
result *= b; // Multiply-assignComparison Operations
All comparison operations return ibool:
iint x(5), y(10);
ibool less = (x < y); // Less than
ibool equal = (x == y); // Equal
ibool greater = (x > y); // Greater than
ibool not_equal = (x != y); // Not equal
ibool less_eq = (x <= y); // Less than or equal
ibool greater_eq = (x >= y); // Greater than or equalArray Operations
Array Element Access
The aadcArrayOps::get() function provides safe array access with active indices:
#include <aadc/iint.h>
using namespace aadcArrayOps;
std::vector<idouble> data = {1.0, 2.5, 3.7, 4.2};
iint index(2);
idouble value = get(data, index); // Returns data[2] = 3.7
// Also works with raw arrays
idouble array[4] = {1.0, 2.5, 3.7, 4.2};
idouble value2 = get(array, 4, index); // Specify size explicitlyInteger Array Access
For arrays of integer-like types:
std::vector<int64_t> int_data = {10, 20, 30, 40};
iint index(1);
iint value = getInt(int_data, index); // Returns 20Type Conversion
From idouble to iint
Use aadc::toInt() for converting floating-point values to integers:
idouble x(3.7);
iint int_x = aadc::toInt(x); // Truncates to 3This conversion is tracked in the computational graph, enabling differentiation through the conversion.
Conditional Operations
Functional Form: iIf()
For conditional integer expressions:
iint value_a(100), value_b(200);
ibool condition = (x > threshold);
iint result = iIf(condition, value_a, value_b);Mathematical Functions
namespace std {
iint max(const iint& a, const iint& b);
iint min(const iint& a, const iint& b);
iint abs(const iint& x);
}Search and Lookup Operations
Lower Bound Search
The aadc::lower_bound() function performs binary search with active variables:
std::vector<double> breakpoints = {1.0, 3.0, 5.0, 7.0};
idouble x(4.2); // Search value
iint position = aadc::lower_bound(breakpoints, x); // Returns 2This is particularly useful for:
- Interpolation schemes: Finding intervals for piecewise functions
- Lookup tables: Locating appropriate table entries
- Bucketing operations: Assigning values to discrete categories
Practical Example: Piecewise Constant Interpolation
template<typename mdouble>
class PiecewiseConst {
std::vector<double> x_points;
std::vector<mdouble> y_values;
public:
PiecewiseConst(const std::vector<double>& x_pts) : x_points(x_pts) {}
void setValues(const std::vector<double>& y_vals) {
assert(y_vals.size() == x_points.size());
y_values.resize(y_vals.size());
for (size_t i = 0; i < y_vals.size(); ++i) {
y_values[i] = y_vals[i];
}
}
mdouble interpolate(const mdouble& x) {
// Find the interval containing x
iint index = std::min(aadc::lower_bound(x_points, x), iint(x_points.size() - 1));
// Get the corresponding y-value
return aadcArrayOps::get(y_values, index);
}
};
// Usage in AADC recording
idouble x(2.5);
PiecewiseConst<idouble> interpolator({1.0, 2.0, 3.0, 4.0});
interpolator.setValues({10.0, 20.0, 30.0, 40.0});
auto x_arg = x.markAsInput();
std::vector<aadc::AADCArgument> y_args;
for (size_t i = 0; i < interpolator.y_values.size(); ++i) {
y_args.push_back(interpolator.y_values[i].markAsDiff());
}
idouble result = interpolator.interpolate(x);
auto result_out = result.markAsOutput();Integration Notes
- Memory layout:
iintmaintains the same memory footprint asint64_t - Vector operations: Can be used in
std::vector<iint>and other containers
Common Use Cases
- Array indexing with computed indices: When array positions depend on input variables
- Lookup table operations: For fast function approximation and interpolation
- Categorization: Assigning continuous inputs to discrete buckets
- Search operations: Binary search and related algorithms
- Integer arithmetic in mathematical models: When calculations naturally involve integer operations
Best Practices
- Use for truly dynamic indices: Only when the index depends on kernel inputs
- Prefer static indexing for fixed operations: Use native integers for loop counters and fixed array access
- Combine with array operations: Use the provided
aadcArrayOpsfunctions for safe access - Test boundary conditions: Ensure array bounds are respected in your logic
- Document integer semantics: Make clear when truncation or rounding behavior is important
See Also
- idouble Class Reference - For the underlying floating-point active type
- ibool Class Reference - For boolean operations and conditionals
- Array Operations Tutorial - For practical interpolation examples