or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-math.mdbasic-operations.mdconstruction.mdindex.mdinterpolation.mdrotation.md

advanced-math.mddocs/

0

# Advanced Mathematics

1

2

Advanced mathematical operations including exponential/logarithm functions, Riemannian manifold operations, and distance metrics for quaternions.

3

4

## Capabilities

5

6

### Exponential and Logarithm Operations

7

8

Quaternion exponential and logarithm functions for advanced mathematical computations.

9

10

```python { .api }

11

@classmethod

12

def exp(cls, q):

13

"""

14

Quaternion exponential function.

15

16

Computes exp(q) for any quaternion using the formula:

17

exp(q) = exp(q.scalar) * (cos(|q.vector|) + (q.vector/|q.vector|) * sin(|q.vector|))

18

19

Parameters:

20

q: Quaternion, input quaternion argument

21

22

Returns:

23

Quaternion: exp(q)

24

25

Note:

26

Can compute exponential of any quaternion, not just unit quaternions.

27

For pure imaginary quaternions, reduces to Euler's formula.

28

"""

29

30

@classmethod

31

def log(cls, q):

32

"""

33

Quaternion natural logarithm.

34

35

Computes log(q) using the formula:

36

log(q) = log(|q|) + (q.vector/|q.vector|) * acos(q.scalar/|q|)

37

38

Parameters:

39

q: Quaternion, input quaternion (should be non-zero)

40

41

Returns:

42

Quaternion: log(q) = (log(|q|), v/|v| * acos(w/|q|))

43

For zero quaternion: (-inf, nan*vector)

44

For real quaternions: (log(|q|), [0,0,0])

45

46

Note:

47

Undefined for zero quaternion (returns -inf + nan*i + nan*j + nan*k).

48

For real quaternions, returns real logarithm with zero vector part.

49

"""

50

```

51

52

**Usage Examples:**

53

54

```python

55

from pyquaternion import Quaternion

56

import numpy as np

57

58

# Basic exponential and logarithm

59

q = Quaternion(1, 0.5, 0.3, 0.2)

60

exp_q = Quaternion.exp(q)

61

log_exp_q = Quaternion.log(exp_q)

62

63

print(f"Original: {q}")

64

print(f"exp(q): {exp_q}")

65

print(f"log(exp(q)): {log_exp_q}") # Should approximately equal original

66

67

# Pure imaginary quaternion (like Euler's formula)

68

pure_imag = Quaternion(0, 1, 0, 0) # i

69

exp_i = Quaternion.exp(pure_imag)

70

print(f"exp(i): {exp_i}") # Should be cos(1) + i*sin(1)

71

72

# Real quaternion

73

real_q = Quaternion(2.0) # Pure real

74

exp_real = Quaternion.exp(real_q)

75

log_real = Quaternion.log(real_q)

76

print(f"exp(2): {exp_real}") # Should be (e^2, 0, 0, 0)

77

print(f"log(2): {log_real}") # Should be (ln(2), 0, 0, 0)

78

79

# Zero and problematic cases

80

try:

81

zero_q = Quaternion(0, 0, 0, 0)

82

log_zero = Quaternion.log(zero_q)

83

print(f"log(0): {log_zero}") # (-inf, nan, nan, nan)

84

except:

85

print("Zero quaternion logarithm handling")

86

```

87

88

### Manifold Operations

89

90

Exponential and logarithm maps on the quaternion Riemannian manifold for advanced geometric computations.

91

92

```python { .api }

93

@classmethod

94

def exp_map(cls, q, eta):

95

"""

96

Quaternion exponential map on Riemannian manifold.

97

98

Computes the endpoint of geodesic starting at q in direction eta,

99

with length equal to magnitude of eta.

100

101

Parameters:

102

q: Quaternion, base point of exponential map

103

eta: Quaternion, tangent vector argument (direction and magnitude)

104

105

Returns:

106

Quaternion: Endpoint quaternion p = q * exp(eta)

107

108

Note:

109

Important for integrating orientation variations (angular velocities).

110

Projects quaternion tangent vectors onto the quaternion manifold.

111

"""

112

113

@classmethod

114

def sym_exp_map(cls, q, eta):

115

"""

116

Quaternion symmetrized exponential map.

117

118

Symmetric formulation analogous to exponential maps for

119

symmetric positive definite tensors.

120

121

Parameters:

122

q: Quaternion, base point

123

eta: Quaternion, tangent vector argument

124

125

Returns:

126

Quaternion: p = sqrt(q) * exp(eta) * sqrt(q)

127

"""

128

129

@classmethod

130

def log_map(cls, q, p):

131

"""

132

Quaternion logarithm map on Riemannian manifold.

133

134

Finds tangent vector with length and direction given by

135

the geodesic joining q and p.

136

137

Parameters:

138

q: Quaternion, base point where logarithm is computed

139

p: Quaternion, target point

140

141

Returns:

142

Quaternion: Tangent vector from q to p

143

Formula: log(q^(-1) * p)

144

"""

145

146

@classmethod

147

def sym_log_map(cls, q, p):

148

"""

149

Quaternion symmetrized logarithm map.

150

151

Symmetric formulation for numerically stable gradient descent

152

on the Riemannian quaternion manifold.

153

154

Parameters:

155

q: Quaternion, base point

156

p: Quaternion, target point

157

158

Returns:

159

Quaternion: Symmetrized tangent vector

160

Formula: log(q^(-1/2) * p * q^(-1/2))

161

"""

162

```

163

164

**Usage Examples:**

165

166

```python

167

# Manifold operations for trajectory planning

168

q_start = Quaternion(axis=[0, 0, 1], degrees=0)

169

q_end = Quaternion(axis=[0, 0, 1], degrees=90)

170

171

# Compute tangent vector from start to end

172

tangent_vec = Quaternion.log_map(q_start, q_end)

173

print(f"Tangent vector: {tangent_vec}")

174

175

# Move along geodesic using exponential map

176

fraction = 0.3 # 30% of the way

177

scaled_tangent = Quaternion(tangent_vec.elements * fraction)

178

intermediate = Quaternion.exp_map(q_start, scaled_tangent)

179

print(f"30% along geodesic: {intermediate}")

180

181

# Verify round-trip

182

reconstructed_end = Quaternion.exp_map(q_start, tangent_vec)

183

print(f"Original end: {q_end}")

184

print(f"Reconstructed: {reconstructed_end}")

185

186

# Symmetrized operations (more numerically stable)

187

sym_tangent = Quaternion.sym_log_map(q_start, q_end)

188

sym_intermediate = Quaternion.sym_exp_map(q_start, scaled_tangent)

189

print(f"Symmetric tangent: {sym_tangent}")

190

print(f"Symmetric intermediate: {sym_intermediate}")

191

```

192

193

### Distance Metrics

194

195

Various distance measures between quaternions for similarity analysis and optimization.

196

197

```python { .api }

198

@classmethod

199

def absolute_distance(cls, q0, q1):

200

"""

201

Quaternion absolute distance accounting for sign ambiguity.

202

203

Computes chord distance of shortest path connecting q0 to q1,

204

accounting for the fact that q and -q represent the same rotation.

205

206

Parameters:

207

q0: Quaternion, first quaternion

208

q1: Quaternion, second quaternion

209

210

Returns:

211

float: Positive chord distance, good indicator for rotation similarity

212

Returns min(|q0 - q1|, |q0 + q1|)

213

214

Note:

215

Does not measure distance on hypersphere, but accounts for

216

quaternion double-cover (q ≡ -q for rotations).

217

"""

218

219

@classmethod

220

def distance(cls, q0, q1):

221

"""

222

Intrinsic geodesic distance between quaternions.

223

224

Computes length of geodesic arc connecting q0 to q1 on the

225

quaternion manifold.

226

227

Parameters:

228

q0: Quaternion, first quaternion

229

q1: Quaternion, second quaternion

230

231

Returns:

232

float: Geodesic arc length

233

Formula: |log_map(q0, q1).norm|

234

"""

235

236

@classmethod

237

def sym_distance(cls, q0, q1):

238

"""

239

Symmetrized geodesic distance between quaternions.

240

241

More numerically stable for iterative gradient descent on

242

Riemannian quaternion manifold.

243

244

Parameters:

245

q0: Quaternion, first quaternion

246

q1: Quaternion, second quaternion

247

248

Returns:

249

float: Symmetrized geodesic distance

250

251

Note:

252

Distance between q and -q equals π, making this less useful

253

for rotation similarity when samples span angles > π/2.

254

"""

255

```

256

257

**Usage Examples:**

258

259

```python

260

# Compare different distance metrics

261

q1 = Quaternion(axis=[1, 0, 0], degrees=30)

262

q2 = Quaternion(axis=[1, 0, 0], degrees=60)

263

q3 = Quaternion(axis=[0, 1, 0], degrees=30) # Different axis

264

265

# Compute various distances

266

abs_dist_12 = Quaternion.absolute_distance(q1, q2)

267

abs_dist_13 = Quaternion.absolute_distance(q1, q3)

268

269

geo_dist_12 = Quaternion.distance(q1, q2)

270

geo_dist_13 = Quaternion.distance(q1, q3)

271

272

sym_dist_12 = Quaternion.sym_distance(q1, q2)

273

sym_dist_13 = Quaternion.sym_distance(q1, q3)

274

275

print("Distance comparison:")

276

print(f"q1 to q2 (same axis, 30° apart):")

277

print(f" Absolute: {abs_dist_12:.4f}")

278

print(f" Geodesic: {geo_dist_12:.4f}")

279

print(f" Symmetric: {sym_dist_12:.4f}")

280

281

print(f"q1 to q3 (different axis, same angle):")

282

print(f" Absolute: {abs_dist_13:.4f}")

283

print(f" Geodesic: {geo_dist_13:.4f}")

284

print(f" Symmetric: {sym_dist_13:.4f}")

285

286

# Demonstrate sign ambiguity handling

287

q_pos = Quaternion(1, 0, 0, 0)

288

q_neg = Quaternion(-1, 0, 0, 0) # Same rotation, opposite quaternion

289

290

regular_dist = (q_pos - q_neg).norm # Regular Euclidean distance

291

absolute_dist = Quaternion.absolute_distance(q_pos, q_neg)

292

293

print(f"\nSign ambiguity demonstration:")

294

print(f"q = {q_pos}")

295

print(f"-q = {q_neg}")

296

print(f"Regular Euclidean distance: {regular_dist:.4f}")

297

print(f"Absolute distance: {absolute_dist:.4f}") # Should be ~0

298

```

299

300

### Clustering and Optimization Applications

301

302

```python

303

# Example: Quaternion averaging using distance metrics

304

def quaternion_mean_iterative(quaternions, max_iterations=100, tolerance=1e-6):

305

"""

306

Compute quaternion mean using iterative optimization on manifold.

307

"""

308

# Initialize with first quaternion

309

mean_q = quaternions[0].normalised

310

311

for iteration in range(max_iterations):

312

# Compute tangent vectors to all quaternions

313

tangent_sum = Quaternion(0, 0, 0, 0)

314

315

for q in quaternions:

316

tangent_vec = Quaternion.log_map(mean_q, q)

317

tangent_sum += tangent_vec

318

319

# Average tangent vector

320

avg_tangent = Quaternion(tangent_sum.elements / len(quaternions))

321

322

# Update mean using exponential map

323

step_size = 0.5 # Learning rate

324

scaled_tangent = Quaternion(avg_tangent.elements * step_size)

325

new_mean = Quaternion.exp_map(mean_q, scaled_tangent)

326

327

# Check convergence

328

update_distance = Quaternion.distance(mean_q, new_mean)

329

if update_distance < tolerance:

330

break

331

332

mean_q = new_mean.normalised

333

334

return mean_q

335

336

# Usage

337

sample_quaternions = [

338

Quaternion(axis=[1, 0, 0], degrees=10),

339

Quaternion(axis=[1, 0, 0], degrees=20),

340

Quaternion(axis=[1, 0, 0], degrees=15),

341

Quaternion(axis=[1, 0, 0], degrees=12),

342

]

343

344

mean_quaternion = quaternion_mean_iterative(sample_quaternions)

345

print(f"Mean quaternion: {mean_quaternion}")

346

print(f"Mean angle: {mean_quaternion.degrees:.1f}°")

347

```