Three-component vectors

R3 holds three real components; C3 holds three complex components. R3 is used for positions, translations, lattice vectors, magnetization, and polarization. C3 appears in custom form factors as a complex momentum transfer.

The vector itself has no fixed units. The receiving operation determines them: particle positions use nm, magnetization uses A/m, and polarization vectors are dimensionless.

Create and access components

import bornagain as ba
import numpy as np

v = ba.R3(1, 2, 3)
q = ba.C3(1 + 0.2j, 2, 3)
zero = ba.R3()

print(v.x(), v.y(), v.z())
v.setZ(4)
components = np.array([v.x(), v.y(), v.z()])

x(), y(), z() and setX, setY, setZ work for both types. Use explicit component access for conversion to NumPy; these vectors do not support indexing or iteration.

Arithmetic

For real vectors:

a = ba.R3(1, 2, 3)
b = ba.R3(3, 2, 1)
combined = a + b
difference = a + (-b)
scaled = 2*a
halved = a*0.5

R3 supports addition, unary minus, and multiplication by a real scalar on either side. Binary subtraction and division are not available; use a + (-b) and a*(1/c).

Both types support in-place += and -=. C3 has no binary addition, subtraction, multiplication, or division operators; use its components or convert to a NumPy array for further arithmetic. Both types support exact component-wise comparison with == and !=.

Length and direction

Operation Result
v.mag() Length.
v.mag2() Squared length.
v.magxy() Length of the x-y components.
v.magxy2() Squared length of the x-y components.
v.unit_or_throw() Normalized copy; raises an error for a zero vector.
v.unit_or_null() Normalized copy; returns zero for a zero vector.
v.rotatedY(angle) Copy rotated about the y axis; angle in rad.
v.rotatedZ(angle) Copy rotated about the z axis; angle in rad.

Lengths use absolute squares for complex components. These operations leave the original vector unchanged. Positive rotatedZ angles turn +x toward -y, whereas RotationZ turns +x toward +y:

v = ba.R3(1, 0, 0)
around_z = v.rotatedZ(90*ba.deg)  # approximately (0, -1, 0)
around_y = v.rotatedY(90*ba.deg)  # approximately (0, 0, -1)

Real and complex components

Operation Result
v.complex() A C3 copy of the components.
q.real() An R3 containing their real parts.
q.conj() A copy with complex-conjugated components.
q.analytic_square() qx*qx + qy*qy + qz*qz, without conjugation.
q.analytic_square_xy() qx*qx + qy*qy, without conjugation.

For complex components, analytic_square() differs from mag2(). See complex momentum transfer for its use in a form factor.