{
"title": "polyint",
"category": "math/poly",
"keywords": [
"polyint",
"polynomial integral",
"antiderivative",
"integration constant",
"gpu"
],
"summary": "Integrate polynomial coefficient vectors and append a constant of integration.",
"references": [
"title: \"MATLAB polyint documentation\""
],
"gpu_support": {
"elementwise": false,
"reduction": false,
"precisions": [
"f32",
"f64"
],
"broadcasting": "none",
"notes": "Real-valued coefficient vectors stay on the GPU when the provider exposes the polyint hook; complex outputs fall back to the host."
},
"fusion": {
"elementwise": false,
"reduction": false,
"max_inputs": 1,
"constants": "inline"
},
"requires_feature": null,
"tested": {
"unit": "builtins::math::poly::polyint::tests",
"integration": "builtins::math::poly::polyint::tests::polyint_gpu_roundtrip"
},
"description": "`polyint(p)` returns the polynomial that integrates the coefficient vector `p` once, appending the constant of integration at the end of the coefficient list. Coefficients follow MATLAB's descending power convention: `p(1)` multiplies the highest power of `x`, and `p(end)` is the constant term.",
"behaviors": [
"Accepts real or complex scalars, row vectors, column vectors, or empty vectors. Inputs with more than one non-singleton dimension raise MATLAB-compatible errors.",
"Logical and integer coefficients are promoted to double precision before integration.",
"The optional second argument supplies the constant of integration. It must be a scalar (real or complex). When omitted, the constant defaults to `0`.",
"Leading zeros are preserved. Integrating `[0 0 5]` produces `[0 0 5 0]`, matching MATLAB.",
"Empty inputs integrate to the constant of integration (default `0`). Specifying a constant `k` yields `[k]`.",
"The orientation of the input vector is preserved: row vectors stay row vectors, column vectors stay column vectors, and scalars return a row vector.",
"When coefficients reside on the GPU, RunMat gathers them to the host, performs the integration, and re-uploads real-valued results so downstream kernels retain residency."
],
"examples": [
{
"description": "Integrating a cubic polynomial",
"input": "p = [3 -2 5 7]; % 3x^3 - 2x^2 + 5x + 7\nq = polyint(p)",
"output": "q = [0.75 -0.6667 2.5 7 0]"
},
{
"description": "Supplying a constant of integration",
"input": "p = [4 0 -8];\nq = polyint(p, 3)",
"output": "q = [1.3333 0 -8 3]"
},
{
"description": "Preserving column-vector orientation",
"input": "p = [2; 0; -6];\nq = polyint(p)",
"output": "q =\n 0.6667\n 0\n -6.0000\n 0"
},
{
"description": "Integrating the zero polynomial",
"input": "q = polyint([])",
"output": "q = 0"
},
{
"description": "Integrating complex coefficients",
"input": "p = [1+2i -3 4i];\nq = polyint(p, -1i)",
"output": "q = [(1+2i)/3 -1.5 4i -1i]"
},
{
"description": "Working with gpuArray inputs",
"input": "g = gpuArray([1 -4 6]);\nq = polyint(g); % Gathered to host, integrated, and re-uploaded\nresult = gather(q)",
"output": "result = [0.3333 -2 6 0]"
}
],
"faqs": [
{
"question": "Does `polyint` change the orientation of my coefficients?",
"answer": "No. Row vectors stay row vectors, column vectors stay column vectors, and scalars return a row vector with two elements after integration."
},
{
"question": "What happens when I pass an empty vector?",
"answer": "An empty vector represents the zero polynomial. `polyint([])` returns the constant of integration, so the default result is `0` and `polyint([], k)` returns `k`."
},
{
"question": "Can the constant of integration be complex?",
"answer": "Yes. Provide any scalar numeric value (real or complex). The constant is appended to the integrated polynomial exactly as MATLAB does."
},
{
"question": "Are logical or integer coefficients supported?",
"answer": "Yes. They are promoted to double precision before integration, ensuring identical behaviour to MATLAB."
},
{
"question": "Will the result stay on the GPU?",
"answer": "Real-valued outputs are re-uploaded to the GPU when a provider is available. Complex outputs remain on the host because current providers do not expose complex tensor handles."
},
{
"question": "How precise is the computation?",
"answer": "All arithmetic uses IEEE 754 double precision (`f64`), mirroring MATLAB's default numeric type."
}
],
"links": [
{
"label": "polyder",
"url": "./polyder"
},
{
"label": "polyval",
"url": "./polyval"
},
{
"label": "polyfit",
"url": "./polyfit"
},
{
"label": "gpuArray",
"url": "./gpuarray"
},
{
"label": "gather",
"url": "./gather"
},
{
"label": "roots",
"url": "./roots"
}
],
"source": {
"label": "`crates/runmat-runtime/src/builtins/math/poly/polyint.rs`",
"url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/poly/polyint.rs"
},
"gpu_residency": "You usually do **not** need to call `gpuArray` just for `polyint`. When inputs already live on the GPU and a provider is active, RunMat keeps the data on the device and executes the integration there for real-valued coefficients. For complex inputs, or when no provider hook is available, the runtime falls back to the host implementation transparently.",
"gpu_behavior": [
"When a GPU provider is registered and the coefficient vector is real-valued, RunMat calls the provider's dedicated `polyint` kernel. The input stays on the device, the kernel divides each coefficient by the appropriate power, and the supplied constant of integration is written directly into device memory. If the coefficients or the constant are complex, or if the provider reports that the hook is unavailable, the runtime gathers data back to the host, performs the integration in double precision, and re-uploads the result when it is purely real."
]
}