ldivide — Compute element-wise left division in MATLAB and RunMat.
ldivide(A, B) (or A .\ B) divides each element of B by the corresponding element of A. Broadcasting, complex handling, and output-shape behavior follow MATLAB semantics.
Syntax
C = ldivide(A, B)
C = ldivide(A, B, "like", prototype)Inputs
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
A | Any | Yes | — | Left divisor operand. |
B | Any | Yes | — | Right dividend operand. |
like | StringScalar | Yes | — | Literal string "like". |
prototype | LikePrototype | Yes | — | Output class/device prototype. |
Returns
| Name | Type | Description |
|---|---|---|
C | NumericArray | Elementwise left quotient result. |
Errors
| Identifier | When | Message |
|---|---|---|
RunMat:ldivide:InvalidArgument | Optional arguments are malformed or unsupported. | ldivide: invalid argument |
RunMat:ldivide:InvalidInput | Operands or prototypes cannot be converted into supported numeric/logical forms. | ldivide: invalid input |
RunMat:ldivide:SizeMismatch | Operands are not broadcast-compatible. | ldivide: array sizes are not compatible for broadcasting |
RunMat:ldivide:Internal | Provider interaction, gather/upload, or internal tensor construction failed. | ldivide: internal error |
How ldivide works
- Supports real, complex, logical, and character inputs; logical and character data are promoted to double precision before division.
- Implicit expansion follows MATLAB rules: singleton dimensions expand automatically, while mismatched non-singleton extents raise MATLAB-compatible size errors.
- Complex operands use the analytic continuation
B ./ A, propagatingNaNandInfexactly as MATLAB does. - Empty shapes propagate cleanly—if the broadcasted output has a zero dimension, the result is empty with the expected shape.
- Integer inputs promote to double precision, mirroring MATLAB’s numeric tower.
- The optional
'like'prototype makes the result adopt the residency (host or GPU) and numeric flavour of the prototype. Complex prototypes are honoured on the host today; real gpuArray prototypes keep the result on the device.
Does RunMat run ldivide on the GPU?
When a gpuArray provider is active:
1. If both operands are gpuArrays with identical shapes, RunMat calls the provider’s elem_div hook with (B, A) so the division runs entirely on the GPU. 2. If the divisor A is scalar (host or device) and the numerator B is a gpuArray, the runtime uses scalar_div to evaluate B ./ a on device memory. 3. If the numerator B is scalar and the divisor A is a gpuArray, scalar_rdiv performs b ./ A without leaving the GPU. 4. When shapes require implicit expansion—or the provider lacks the necessary kernels—RunMat gathers to the host, computes the MATLAB-accurate result, then reapplies 'like' residency rules (including re-uploading to a gpuArray when requested). 5. The fusion planner treats ldivide as a fusible elementwise node, so adjacent elementwise producers and consumers can execute inside a single GPU pipeline or WGSL kernel, minimising redundant host↔device transfers.
GPU memory and residency
You usually do not need to call gpuArray manually. RunMat’s auto-offload planner keeps tensors on the GPU whenever provider kernels cover the operation. Explicit gpuArray / gather calls remain available for MATLAB compatibility; when a provider fallback happens, the runtime gathers to host, computes the MATLAB-accurate answer, and reapplies 'like' residency requests automatically.
Examples
Left-dividing a vector by a scalar
A = 2;
B = [4 6 8];
Q = ldivide(A, B)Expected output:
Q = [2 3 4]Broadcasting between column divisors and row numerators
A = (1:3)'; % column of divisors
B = [10 20 40]; % row of numerators
M = ldivide(A, B); % implicit expansionExpected output:
M =
10.0000 20.0000 40.0000
5.0000 10.0000 20.0000
3.3333 6.6667 13.3333Element-wise left division of complex values
A = [1+2i, 3-4i];
B = [2-1i, -1+1i];
Z = ldivide(A, B)Expected output:
Z =
0.0000 - 1.0000i -0.2800 - 0.0400iDividing character codes by a scalar
A = 'ABC';
B = 2;
codes = ldivide(A, B)Expected output:
codes = [0.0308 0.0303 0.0301]Computing reciprocals with ldivide
A = [1 2 4 8];
B = 1;
R = ldivide(A, B); % equivalent to 1 ./ AExpected output:
R = [1 0.5 0.25 0.125]Keeping results on the GPU with 'like'
proto = gpuArray.zeros(1, 1);
A = gpuArray([2 4 8 16]);
B = gpuArray([4 8 16 32]);
deviceResult = ldivide(A, B, 'like', proto);
hostCheck = gather(deviceResult)Expected output:
deviceResult =
1x4 gpuArray
2 2 2 2
hostCheck = [2 2 2 2]Using ldivide with coding agents
Open a RunMat example with live inputs, then ask the agent to explain how ldivide changes the result.
Run a small ldivide example, explain the result, then change one input and compare the output.
FAQ
Does ldivide support MATLAB implicit expansion?⌄
Yes. Singleton dimensions expand automatically; otherwise incompatible shapes raise MATLAB-style errors.
What numeric type does ldivide return?⌄
Real inputs return doubles; mixed or complex inputs return complex doubles. Logical and character inputs promote to double before division.
How does ldivide handle division by zero?⌄
finite ./ 0 yields signed infinities, and 0 ./ 0 becomes NaN, matching MATLAB and IEEE-754 behaviour.
Can I divide gpuArrays by host scalars?⌄
Yes. Numeric scalars stay on device through scalar_div/scalar_rdiv. Non-numeric host scalars trigger a gather-then-divide fallback.
Does ldivide preserve gpuArray residency after a fallback?⌄
If the runtime gathers to host (for example, due to implicit expansion), the intermediate stays on the host. Later computations may move it back when auto-offload deems it profitable, or you can request GPU residency explicitly with 'like'.
How do I keep the result on the GPU?⌄
Provide a real gpuArray prototype: ldivide(A, B, 'like', gpuArray.zeros(1,1)). The runtime re-uploads the host result when necessary.
How are empty arrays handled?⌄
Empty operands propagate cleanly—the output shape is the broadcasted shape, and the data vector is empty.
Are integers and logicals supported?⌄
Yes. Both promote to double precision before division so you get MATLAB-compatible numeric results (including Inf when dividing by zero).
Can I mix real and complex operands?⌄
Absolutely. Mixed cases return complex doubles with full MATLAB semantics.
Related Math functions
Elementwise
abs · angle · complex · conj · double · exp · expm1 · factorial · gamma · heaviside · hypot · imag · log · log10 · log1p · log2 · minus · nextpow2 · plus · pow2 · power · rdivide · real · sign · single · sqrt · times
Trigonometry
acos · acosh · asin · asinh · atan · atan2 · atanh · cos · cosd · cosh · deg2rad · rad2deg · sin · sind · sinh · tan · tand · tanh
Reduction
all · any · cummax · cummin · cumprod · cumsum · cumtrapz · diff · gradient · max · mean · median · min · nnz · prod · std · sum · trapz · var
Structure
Open-source implementation
Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how ldivide is executed, line by line, in Rust.
- View the source for ldivide in Rust on GitHub
- Learn how the RunMat runtime works
- Found a bug? Open an issue with a minimal reproduction.
About RunMat
RunMat is an open-source runtime that executes MATLAB-syntax code blazing on any GPU. It is licensed under the Apache 2.0 license.
- RunMat automatically optimizes your math for GPU execution on Apple, Nvidia, and AMD hardware. No code changes needed. Simulations that took hours now take minutes.
- Start running code in seconds. RunMat runs in the browser, on the desktop, or from the CLI. No license server, no IT ticket.