RunMat
GitHub

conj — Compute the complex conjugate of scalars, vectors, matrices, or N-D tensors.

conj(x) negates the imaginary component of every element in x; real values are returned unchanged. The builtin mirrors MathWorks MATLAB semantics for scalars, vectors, matrices, and N-D tensors.

How conj works in RunMat

  • Complex scalars and arrays have their imaginary components multiplied by -1; when a result has no imaginary part it collapses to a real scalar or tensor just like MATLAB.
  • Purely real numeric inputs (double, single, integer) are returned unchanged.
  • Logical arrays are promoted to double precision with true → 1.0 and false → 0.0.
  • Character arrays are promoted to double precision containing their Unicode code points; the Conjugate operation does not alter the codes because they are real-valued.
  • String arrays are not supported and raise an error.

How conj runs on the GPU

**Hook available:** Real tensors stay on the GPU and are processed in-place (both the in-process provider used for tests and the WGPU provider expose this path).

**Fusion and auto-offload:** Because conj is tagged as an elementwise unary builtin, the fusion planner treats it as a pass-through for real-valued kernels. Native auto-offload therefore keeps fused expressions resident on the GPU whenever the surrounding ops are profitable.

**Hook missing or complex input:** RunMat gathers the data to host memory, applies the CPU semantics (including complex negation and type promotion), and returns the result. The planner may re-upload tensors later if profitable.

Complex tensors are currently materialised on the host because GPU-side complex layouts are still under development. Providers can add native complex kernels later without changing this builtin.

GPU memory and residency

You usually do **not** need to call gpuArray explicitly. RunMat's fusion planner and Accelerate layer manage residency and offload decisions automatically, keeping tensors on the GPU whenever device execution is beneficial. Explicit gpuArray and gather remain available for MATLAB compatibility or fine-grained residency control.

Examples

Complex conjugate of a scalar value in MATLAB

z = 3 + 4i;
result = conj(z)

Expected output:

result = 3 - 4i

Apply conj to every element of a complex matrix

Z = [1+2i, 4-3i; -5+0i, 7+8i];
C = conj(Z)

Expected output:

C =
   1 - 2i   4 + 3i
  -5 + 0i   7 - 8i

Ensure conj leaves real inputs unchanged

data = [-2.5 0 9.75];
unchanged = conj(data)

Expected output:

unchanged = [-2.5 0 9.75]

Use conj on logical masks converted to doubles

mask = logical([0 1 0; 1 1 0]);
numeric = conj(mask)

Expected output:

numeric =
     0     1     0
     1     1     0

Convert MATLAB char arrays to numeric codes with conj

chars = 'RunMat';
codes = conj(chars)
outputClass = class(codes)

Expected output:

codes = [82 117 110 77 97 116];
outputClass = 'double'

Compute conjugate on GPU-resident arrays

G = rand(4096, 256, "gpuArray");
H = conj(G)

FAQ

Does conj change purely real inputs?

No. Real values (including logical and character data) are returned unchanged, although logical and character inputs become double precision arrays just like in MATLAB.

How does conj handle complex zeros?

conj(0 + 0i) returns 0. Imaginary zeros remain zero after negation.

Can I call conj on string arrays?

No. The builtin only accepts numeric, logical, or character inputs. Convert strings with double(string) if you need numeric codes.

Does conj allocate a new array?

Yes. The builtin materialises a new tensor (or scalar). Fusion may eliminate the allocation when the surrounding expression can be fused safely, especially when the data stays on the GPU.

What happens on the GPU without unary_conj?

RunMat gathers the tensor to host memory, applies the CPU semantics (including complex negation), and allows later operations to re-upload data if advantageous.

Is GPU execution numerically identical to CPU?

Yes. For real tensors the result is an exact copy; the conjugate matches CPU results bit-for-bit for supported precisions.

Does conj participate in fusion?

Yes. The fusion planner can fold conj into neighbouring elementwise kernels, letting providers keep tensors on the GPU whenever possible.

These functions work well alongside conj. Each page has runnable examples you can try in the browser.

real, imag, abs, gpuArray, gather, angle, double, exp, expm1, factorial, gamma, hypot, ldivide, log, log10, log1p, log2, minus, plus, pow2, power, rdivide, sign, single, sqrt, times

Open-source implementation

Unlike proprietary runtimes, every RunMat function is open-source. Read exactly how conj works, line by line, in Rust.

About RunMat

RunMat is an open-source runtime that executes MATLAB-syntax code — faster, on any GPU, with no license required.

  • Simulations that took hours now take minutes. RunMat automatically optimizes your math for GPU execution on Apple, Nvidia, and AMD hardware. No code changes needed.
  • Start running code in seconds. Open the browser sandbox or download a single binary. No license server, no IT ticket, no setup.
  • A full development environment. GPU-accelerated 2D and 3D plotting, automatic versioning on every save, and a browser IDE you can share with a link.

Getting started · Benchmarks · Pricing

Try RunMat — free, no sign-up

Start running MATLAB code immediately in your browser.