1 # Vector Operations Extension to SV
3 This extension is usually dependent on SV SUBVL being implemented. When SUBVL is set to define the length of a subvector the operations in this extension interpret the elements as a single vector.
5 Normally in SV all operations are scalar and independent, and the operations on them may inherently be independently parallelised, with the result being a vector of length exactly equal to the input vectors.
7 In this extension, the subvector itself is typically the unit, although some operations will work on scalars or standard vectors as well, or the result is a scalar that is dependent on all elements within the vector arguments.
9 Examples which can require SUBVL include cross product and may in future involve complex numbers.
11 ## Vector cross product
13 Result is the cross product of x and y, i.e., the resulting components are, in order:
15 x[1] * y[2] - y[1] * x[2]
16 x[2] * y[0] - y[2] * x[0]
17 x[0] * y[1] - y[0] * x[1]
19 All the operands must be vectors of 3 components of a floating-point type.
23 Computes the dot product of two vectors. Internal accuracy must be greater than the
24 input vectors and the result.
28 The scalar length of a vector:
30 sqrt(x[0]^2 + x[1]^2 + ...).
34 The scalar distance between two vectors. Subtracts one vector from the other and returns length
38 Known as **fmix** in GLSL.
40 <https://en.m.wikipedia.org/wiki/Linear_interpolation>
44 <https://en.m.wikipedia.org/wiki/Slerp>
47 Quaternion slerp(Quaternion v0, Quaternion v1, double t) {
48 // Only unit quaternions are valid rotations.
49 // Normalize to avoid undefined behavior.
53 // Compute the cosine of the angle between the two vectors.
54 double dot = dot_product(v0, v1);
56 // If the dot product is negative, slerp won't take
57 // the shorter path. Note that v1 and -v1 are equivalent when
58 // the negation is applied to all four components. Fix by
59 // reversing one quaternion.
65 const double DOT_THRESHOLD = 0.9995;
66 if (dot > DOT_THRESHOLD) {
67 // If the inputs are too close for comfort, linearly interpolate
68 // and normalize the result.
70 Quaternion result = v0 + t*(v1 - v0);
75 // Since dot is in range [0, DOT_THRESHOLD], acos is safe
76 double theta_0 = acos(dot); // theta_0 = angle between input vectors
77 double theta = theta_0*t; // theta = angle between v0 and result
78 double sin_theta = sin(theta); // compute this value only once
79 double sin_theta_0 = sin(theta_0); // compute this value only once
81 double s0 = cos(theta) - dot * sin_theta / sin_theta_0; // == sin(theta_0 - theta) / sin(theta_0)
82 double s1 = sin_theta / sin_theta_0;
84 return (s0 * v0) + (s1 * v1);