View all functions

CategoryMath: Elementwise
GPUYes

What does the conj function do in MATLAB / RunMat?

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 does the conj function behave in MATLAB / 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.

conj Function GPU Execution Behaviour

RunMat Accelerate keeps tensors on the device whenever the active provider implements the unary_conj hook:

  • 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.

Examples of using the conj function in MATLAB / RunMat

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);

H stays on the GPU when the provider implements unary_conj. Otherwise, RunMat gathers G, computes the result on the CPU, and continues execution transparently.

GPU residency in RunMat (Do I need gpuArray?)

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.

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.

See Also

real, imag, abs, gpuArray, gather

Source & Feedback