runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "exp",
  "category": "math/elementwise",
  "keywords": [
    "exp",
    "exponential",
    "elementwise",
    "gpu",
    "complex"
  ],
  "summary": "Element-wise exponential of scalars, vectors, matrices, or N-D tensors.",
  "references": [],
  "gpu_support": {
    "elementwise": true,
    "reduction": false,
    "precisions": [
      "f32",
      "f64"
    ],
    "broadcasting": "matlab",
    "notes": "Falls back to the host implementation when the active provider lacks unary_exp."
  },
  "fusion": {
    "elementwise": true,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::math::elementwise::exp::tests",
    "integration": "builtins::math::elementwise::exp::tests::exp_gpu_provider_roundtrip"
  },
  "description": "`Y = exp(X)` raises *e* to the power of every element in `X`. Results follow MATLAB semantics for scalars, vectors, matrices, logical arrays, character arrays, and complex inputs.",
  "behaviors": [
    "`exp(X)` applies the exponential element-by-element with MATLAB broadcasting rules.",
    "Logical inputs convert to double (`true → 1.0`, `false → 0.0`) before exponentiation.",
    "Character arrays are treated as their numeric code points and return dense double tensors.",
    "Complex values follow MATLAB's definition: `exp(a + bi) = exp(a) * (cos(b) + i·sin(b))`.",
    "Inputs already living on the GPU stay there when the provider implements `unary_exp`; otherwise RunMat gathers the data, computes on the host, and returns the correct residency."
  ],
  "examples": [
    {
      "description": "Calculate the exponential of a scalar value",
      "input": "y = exp(1)",
      "output": "y = 2.7183"
    },
    {
      "description": "Apply the exponential function to a vector of growth rates",
      "input": "rates = [-1 -0.5 0 0.5 1];\nfactor = exp(rates)",
      "output": "factor = [0.3679 0.6065 1 1.6487 2.7183]"
    },
    {
      "description": "Exponentiate every element of a matrix",
      "input": "A = [0 1 2; 3 4 5];\nB = exp(A)",
      "output": "B = [1.0000 2.7183 7.3891; 20.0855 54.5982 148.4132]"
    },
    {
      "description": "Compute the exponential of complex numbers",
      "input": "z = [1+2i, -1+pi*i];\nw = exp(z)",
      "output": "w = [-1.1312 + 2.4717i, -0.3679 + 0.0000i]"
    },
    {
      "description": "Run element-wise exponential on GPU data",
      "input": "G = gpuArray([0 1; 2 3]);\nout = exp(G);\nresult = gather(out)",
      "output": "result = [1.0000 2.7183; 7.3891 20.0855]"
    },
    {
      "description": "Convert character codes to exponentials",
      "input": "C = 'ABC';\nY = exp(C)",
      "output": "Y = [1.6949e+28 4.6072e+28 1.2524e+29]"
    }
  ],
  "faqs": [
    {
      "question": "When should I use the `exp` function?",
      "answer": "Use `exp` whenever you need the natural exponential of a value or array, such as modelling growth, discounting continuous compounding, or preparing inputs for activation functions."
    },
    {
      "question": "Does `exp` preserve tensor shapes?",
      "answer": "Yes. `exp` returns a tensor with the same shape as the input, applying broadcasting rules where applicable."
    },
    {
      "question": "How are logical arrays handled?",
      "answer": "Logical arrays convert to doubles before exponentiation, matching MATLAB behavior: `exp([true false])` returns `[e 1]`."
    },
    {
      "question": "What about complex inputs?",
      "answer": "Complex scalars and tensors use MATLAB's complex exponential formula, producing complex outputs."
    },
    {
      "question": "What happens when the GPU provider lacks `unary_exp`?",
      "answer": "RunMat automatically gathers the data to the host, computes the result, and returns a dense tensor. Future GPU operations can still fuse because residency metadata is updated accordingly."
    },
    {
      "question": "Can I expect double precision?",
      "answer": "Yes. RunMat stores dense numeric tensors as double precision (`f64`). Providers may internally use single precision when configured, but results are converted back to double."
    }
  ],
  "links": [
    {
      "label": "logspace",
      "url": "./logspace"
    },
    {
      "label": "abs",
      "url": "./abs"
    },
    {
      "label": "sin",
      "url": "./sin"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "gather",
      "url": "./gather"
    },
    {
      "label": "angle",
      "url": "./angle"
    },
    {
      "label": "conj",
      "url": "./conj"
    },
    {
      "label": "double",
      "url": "./double"
    },
    {
      "label": "expm1",
      "url": "./expm1"
    },
    {
      "label": "factorial",
      "url": "./factorial"
    },
    {
      "label": "gamma",
      "url": "./gamma"
    },
    {
      "label": "hypot",
      "url": "./hypot"
    },
    {
      "label": "imag",
      "url": "./imag"
    },
    {
      "label": "ldivide",
      "url": "./ldivide"
    },
    {
      "label": "log",
      "url": "./log"
    },
    {
      "label": "log10",
      "url": "./log10"
    },
    {
      "label": "log1p",
      "url": "./log1p"
    },
    {
      "label": "log2",
      "url": "./log2"
    },
    {
      "label": "minus",
      "url": "./minus"
    },
    {
      "label": "plus",
      "url": "./plus"
    },
    {
      "label": "pow2",
      "url": "./pow2"
    },
    {
      "label": "power",
      "url": "./power"
    },
    {
      "label": "rdivide",
      "url": "./rdivide"
    },
    {
      "label": "real",
      "url": "./real"
    },
    {
      "label": "sign",
      "url": "./sign"
    },
    {
      "label": "single",
      "url": "./single"
    },
    {
      "label": "sqrt",
      "url": "./sqrt"
    },
    {
      "label": "times",
      "url": "./times"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/math/elementwise/exp.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/math/elementwise/exp.rs"
  },
  "gpu_residency": "You typically do **not** need to call `gpuArray` manually in RunMat. The acceleration planner and fusion engine keep tensors on the GPU automatically when profitable. Users can still call `gpuArray` for explicit residency or to mirror MathWorks MATLAB workflows.",
  "gpu_behavior": [
    "RunMat Accelerate keeps GPU tensors resident whenever the selected provider implements `unary_exp`. When the hook is missing or returns an error, RunMat automatically gathers the tensor, computes on the CPU, and re-wraps the result, ensuring correctness without surprising users."
  ]
}