Skip to content

Miscellaneous Utilities

Contains definition of a base vector object used in the models such as Domain Wall Dynamics or Smit-Beljers model.

VectorObj dataclass

Vector object for standard manipulation. Alternative to CVectors (which are used in the C++ code). Easier to modify and manipulate, but slower.

Parameters:

Name Type Description Default
theta float

positive z-axis angle (in xz plane) in radians.

required
phi float

positive x-axis (in xy plane) angle in radians

required
mag float

magnitude of the vector, if not set defaults to 1 unit vector

1
Source code in cmtj/utils/general.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@dataclass
class VectorObj:
    """Vector object for standard manipulation.
    Alternative to CVectors (which are used in the C++ code).
    Easier to modify and manipulate, but slower.
    :param theta: positive z-axis angle (in xz plane) in radians.
    :param phi: positive x-axis (in xy plane) angle in radians
    :param mag: magnitude of the vector, if not set defaults to 1 *unit vector*
    """

    theta: float  # in radians
    phi: float  # rad
    mag: float = 1

    def __add__(self, other):
        """Adds two vectors"""
        return VectorObj.from_cvector(self.to_cvector() + other.to_cvector())

    def __mul__(self, other: Union["VectorObj", float]):
        """Multiplies a vector by a scalar"""
        if isinstance(other, VectorObj):
            return self._componentwise_mul(other)
        return VectorObj.from_cvector(self.to_cvector() * other)

    def __rmul__(self, other: Union["VectorObj", float]):
        """Multiplies a vector by a scalar"""
        return self.__mul__(other)

    def __repr__(self) -> str:
        return f"VectorObj(theta={self.theta}, phi={self.phi}, mag={self.mag})"

    def __hash__(self) -> int:
        return hash(str(self))

    def __eq__(self, __value: "VectorObj") -> bool:
        return (self.theta == __value.theta and self.phi == __value.phi
                and self.mag == __value.mag)

    def _componentwise_mul(self, other):
        coors = self.get_cartesian()
        other_coords = other.get_cartesian()
        return VectorObj.from_cartesian(
            coors[0] * other_coords[0],
            coors[1] * other_coords[1],
            coors[2] * other_coords[2],
        )

    def get_cartesian(self):
        """Returns the vector in Cartesian coordinates with (x, y, z) compnents"""
        return VectorObj.from_spherical(self.theta, self.phi, self.mag)

    @staticmethod
    def from_spherical(theta, phi, mag=1):
        """Creates a Cartesian vector from spherical components"""
        return [
            mag * math.sin(theta) * math.cos(phi),
            mag * math.sin(theta) * math.sin(phi),
            mag * math.cos(theta),
        ]

    @staticmethod
    def from_cartesian(x: float, y: float, z: float):
        """Creates a spherical vector from Cartesian components"""
        mag = math.sqrt(x**2 + y**2 + z**2)
        if mag == 0:
            return VectorObj(0, 0, 0)
        theta = math.acos(z / mag)
        phi = math.atan2(y, x)
        return VectorObj(theta, phi, mag)

    @staticmethod
    def from_cvector(cvector: CVector):
        """Creates a spherical vector from Cartesian components"""
        mag = cvector.length()
        if mag == 0:
            return VectorObj(0, 0, 0)
        theta = math.acos(cvector.z / mag)
        phi = math.atan2(cvector.y, cvector.x)
        return VectorObj(theta, phi, mag)

    def to_cvector(self):
        """Creates a Cartesian vector from spherical components"""
        return CVector(*self.get_cartesian())

__add__(other)

Adds two vectors

Source code in cmtj/utils/general.py
24
25
26
def __add__(self, other):
    """Adds two vectors"""
    return VectorObj.from_cvector(self.to_cvector() + other.to_cvector())

__mul__(other)

Multiplies a vector by a scalar

Source code in cmtj/utils/general.py
28
29
30
31
32
def __mul__(self, other: Union["VectorObj", float]):
    """Multiplies a vector by a scalar"""
    if isinstance(other, VectorObj):
        return self._componentwise_mul(other)
    return VectorObj.from_cvector(self.to_cvector() * other)

__rmul__(other)

Multiplies a vector by a scalar

Source code in cmtj/utils/general.py
34
35
36
def __rmul__(self, other: Union["VectorObj", float]):
    """Multiplies a vector by a scalar"""
    return self.__mul__(other)

from_cartesian(x, y, z) staticmethod

Creates a spherical vector from Cartesian components

Source code in cmtj/utils/general.py
70
71
72
73
74
75
76
77
78
@staticmethod
def from_cartesian(x: float, y: float, z: float):
    """Creates a spherical vector from Cartesian components"""
    mag = math.sqrt(x**2 + y**2 + z**2)
    if mag == 0:
        return VectorObj(0, 0, 0)
    theta = math.acos(z / mag)
    phi = math.atan2(y, x)
    return VectorObj(theta, phi, mag)

from_cvector(cvector) staticmethod

Creates a spherical vector from Cartesian components

Source code in cmtj/utils/general.py
80
81
82
83
84
85
86
87
88
@staticmethod
def from_cvector(cvector: CVector):
    """Creates a spherical vector from Cartesian components"""
    mag = cvector.length()
    if mag == 0:
        return VectorObj(0, 0, 0)
    theta = math.acos(cvector.z / mag)
    phi = math.atan2(cvector.y, cvector.x)
    return VectorObj(theta, phi, mag)

from_spherical(theta, phi, mag=1) staticmethod

Creates a Cartesian vector from spherical components

Source code in cmtj/utils/general.py
61
62
63
64
65
66
67
68
@staticmethod
def from_spherical(theta, phi, mag=1):
    """Creates a Cartesian vector from spherical components"""
    return [
        mag * math.sin(theta) * math.cos(phi),
        mag * math.sin(theta) * math.sin(phi),
        mag * math.cos(theta),
    ]

get_cartesian()

Returns the vector in Cartesian coordinates with (x, y, z) compnents

Source code in cmtj/utils/general.py
57
58
59
def get_cartesian(self):
    """Returns the vector in Cartesian coordinates with (x, y, z) compnents"""
    return VectorObj.from_spherical(self.theta, self.phi, self.mag)

to_cvector()

Creates a Cartesian vector from spherical components

Source code in cmtj/utils/general.py
90
91
92
def to_cvector(self):
    """Creates a Cartesian vector from spherical components"""
    return CVector(*self.get_cartesian())

box_muller_random(mean, std)

Generates Gaussian noise with mean and standard deviation using the Box-Muller transform. https://en.wikipedia.org/wiki/Box–Muller_transform

Parameters:

Name Type Description Default
mean

mean of the Gaussian.

required
std

standard deviation of the Gaussian.

required
Source code in cmtj/utils/general.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def box_muller_random(mean, std):
    """
    Generates Gaussian noise with mean and standard deviation
    using the Box-Muller transform.
    https://en.wikipedia.org/wiki/Box–Muller_transform
    :param mean: mean of the Gaussian.
    :param std: standard deviation of the Gaussian.
    """
    u1 = np.random.uniform(0, 1)
    u2 = np.random.uniform(0, 1)
    mag = std * math.sqrt(-2.0 * math.log(u1))
    z0 = mag * math.cos(2 * math.pi * u2) + mean
    z1 = mag * math.sin(2 * math.pi * u2) + mean
    return z0, z1

perturb_position(eq_point, pmax=0.001)

Perturbs an equilibrium point by a random amount.

Source code in cmtj/utils/general.py
111
112
113
114
115
def perturb_position(eq_point, pmax=1e-3):
    """
    Perturbs an equilibrium point by a random amount.
    """
    return np.asarray(eq_point) + np.random.normal(0, pmax, len(eq_point))