### Math Functions

Math functions include common vector and matrix operations. More specific noise and rendering functions can be found in the next two sections, Noise Functions and Auxiliary Functions.

```void mi_vector_neg(
miVector    *r)
```

r := −r

```void mi_vector_add(
miVector    *r,
miVector    *a,
miVector    *b)
```

r := a + b

##### mi_vector_sub
```void mi_vector_sub(
miVector    *r,
miVector    *a,
miVector    *b)
```

r := a − b

##### mi_vector_mul
```void mi_vector_mul(
miVector    *r,
miScalar    f)
```

r := r * f

##### mi_vector_div
```void mi_vector_div(
miVector    *r,
miScalar    f)
```

r := r ⁄ f    (If f is zero, leave r unchanged.)

##### mi_vector_prod
```void mi_vector_prod(
miVector    *r,
miVector    *a,
miVector    *b)
```

r := a x b

##### mi_vector_dot
```miScalar mi_vector_dot(
miVector    *a,
miVector    *b)
```

a * b

##### mi_vector_norm
```miScalar mi_vector_norm(
miVector    *a)
```

||a||

##### mi_vector_normalize
```void mi_vector_normalize(
miVector    *r)
```

r := r ⁄ ||r||    (If r is a null vector, leave r unchanged.)

##### mi_vector_min
```void mi_vector_min(
miVector    *r,
miVector    *a,
miVector    *b)
```

Assign the minimum x, y, and z coordinates of a and b to r.

##### mi_vector_max
```void mi_vector_max(
miVector    *r,
miVector    *a,
miVector    *b)
```

Assign the minimum x, y, and z coordinates of a and b to r.

##### mi_vector_det
```miScalar mi_vector_det(
miVector    *a,
miVector    *b,
miVector    *c)
```

Return the determinant of the matrix formed by the three column vectors a, b, and c.

##### mi_vector_dist
```miScalar mi_vector_dist(
miVector    *a,
miVector    *b)
```

||a − b||

```void mi_matrix_null(
miMatrix     r)
```

Return a null matrix, with all sixteen components set to 0.

##### mi_matrix_ident
```void mi_matrix_ident(
miMatrix     r)
```

Return an identity matrix, with the main diagonal components set to 1, and all other components set to 0.

##### mi_matrix_isident
```miBoolean mi_matrix_isident(
miMatrix const  a)
```

Return miTRUE if a is the identity matrix, and miFALSE otherwise.

```void mi_matrix_copy(
miMatrix     r,
miMatrix     a)
```

r := a

##### mi_matrix_invert
```miBoolean mi_matrix_invert(
miMatrix        r,
miMatrix const  a)
```

r := a−1   (Returns miFALSE if the matrix cannot be inverted.)

##### mi_matrix_prod
```void mi_matrix_prod(
miMatrix        r,
miMatrix const  a,
miMatrix const  b)
```

r := a x b

##### mi_matrix_rotate
```void mi_matrix_rotate(
miMatrix        a,
const miScalar  xrot,
const miScalar  yrot,
const miScalar  zrot)
```

Create a rotation matrix a rotating by xrot, then yrot, then zrot, in radians.

##### mi_matrix_rotate_axis
```void mi_matrix_rotate_axis(
miMatrix        a,
miVector const *const v,
miScalar const  r)
```

This function is similar to the previous, except that the rotation is specified with an axis and an angle. The resulting matrix will rotate a point r radians about the axis v according to the right-hand rule. v must have unit length, otherwise the result is undefined.

##### mi_matrix_solve
```void mi_matrix_solve(
miScalar        *X,
miMatrix const   A,
miScalar const  *B,
int              c)
```

Solve the system of linear equations A * X = B for X. A is a [4,4] matrix, but X and B are [4,c] (row major) matrices. For c = 1 they are simple vectors and the function solves A * X = B for X. In the case c=4, A and B are rectangular [4,4] matrices and the function computes the matrix division A ⁄ B. Using this function is both faster and more precise than explicitly computing A−1B.

All the following transformation functions may be called with identical pointers r and v. The vector is transformed in-place in this case. If the matrix m is a null pointer, no transformation is done and v is copied to r. If the result of a transformation is a point in homogeneous coordinates with a w component that is not equal to 1.0, the result vector's x, y, and z components are divided by w. For point transformations, a w component of 1.0 is implicitly appended to the v vector at the vector-matrix multiplication. For vector transformations the w component is implicitly zero. Note the distinction between object and light transformations - both sets deal with object space, but the former uses the current object's object space and the latter uses the current light's object space.

##### mi_matrix_rot_det
```float mi_matrix_rot_det(
miMatrix const  a)
```

Return the determinant of the 3 x 3 rotation part of matrix a.

##### mi_point_transform
```void mi_point_transform(
miVector       *const r,
miVector const *const v,
miMatrix const  m)
```

r := v * M

##### mi_vector_transform
```void mi_vector_transform(
miVector       *const r,
miVector const *const v,
miMatrix const  m)
```

r := v * M    Only the upper left 3-by-3 submatrix is used since this is a vector transform. The translation row in the matrix is ignored as w is implicitly assumed to be 0.

##### mi_vector_transform_T
```void mi_vector_transform_T(
miVector       *const r,
miVector const *const v,
miMatrix const  m)
```

r := v * MT    The transpose of the upper left 3-by-3 submatrix is used for the vector transformation. The w component of v is implicitly assumed to be 0. This function is required for transformation of normals.

##### mi_point_to_world
```void mi_point_to_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal point v in the state to world space, r.

##### mi_point_to_camera
```void mi_point_to_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal point v in the state to camera space, r.

##### mi_point_to_object
```void mi_point_to_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal point v to the object space of the current object (illuminated point), r.

##### mi_point_to_light
```void mi_point_to_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal point v in the state to the object space of the current light. This function (and the other five light transformation functions described below) are similar to the corresponding object transformation functions except that they use state→light_instance instead of state→instance to locate the correct object space transformation matrices.

##### mi_point_to_raster
```void mi_point_to_raster(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal point v in the state to 2D raster space, r. Raster space dimension is defined by the camera resolution.

##### mi_point_from_world
```void mi_point_from_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert point v in world space to internal space, r.

##### mi_point_from_camera
```void mi_point_from_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert point in camera space v to internal space, r.

##### mi_point_from_object
```void mi_point_from_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert point v in the object space of the current object (illuminated point) to internal space, r.

##### mi_point_from_light
```void mi_point_from_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert point v in the object space of the current light as found in state→light_instance to internal space, r.

##### mi_vector_to_world
```void mi_vector_to_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal vector v in the state to world space, r. Vector transformations work like point transformations, except that the translation row of the transformation matrix is ignored. The resulting vector is not renormalized. Vector transformations transform normals correctly only if there is no scaling. For correct transformation of normals use the normal transformations described below.

##### mi_vector_to_camera
```void mi_vector_to_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal vector v in the state to camera space, r.

##### mi_vector_to_object
```void mi_vector_to_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal vector v to the object space of the current object (illuminated point), r.

##### mi_vector_to_light
```void mi_vector_to_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal vector v in the state to object space of the current light as found in state→light_instance , r.

##### mi_vector_from_world
```void mi_vector_from_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert vector v in world space to internal space, r.

##### mi_vector_from_camera
```void mi_vector_from_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert vector in camera space v to internal space, r.

##### mi_vector_from_object
```void mi_vector_from_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert vector v in the object space of the current object (illuminated point) to internal space, r.

##### mi_vector_from_light
```void mi_vector_from_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert vector v in object space of the current light as found in state→light_instance to internal space, r.

##### mi_normal_to_world
```void mi_normal_to_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal normal v in the state to world space, r. Normal transformations work like vector transformations, except that the transpose of the inverse transformation matrix used. The resulting vector is not renormalized. This ensures that if a vector and a normal are orthogonal in one coordinate system they remain orthogonal after they have been transformed to a different coordinate system. This holds for arbitrary, not necessarily orthogonal transformations. The vector transformations described above transform normals correctly only if there is no scaling.

##### mi_normal_to_camera
```void mi_normal_to_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal normal v in the state to camera space, r.

##### mi_normal_to_object
```void mi_normal_to_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal normal v to the object space of the current object (illuminated point), r.

##### mi_normal_to_light
```void mi_normal_to_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert internal normal v in the state to object space of the current light as found in state→light_instance , r.

##### mi_normal_from_world
```void mi_normal_from_world(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert normal v in world space to internal space, r.

##### mi_normal_from_camera
```void mi_normal_from_camera(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert normal in camera space v to internal space, r.

##### mi_normal_from_object
```void mi_normal_from_object(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert normal v in the object space of the current object (illuminated point) to internal space, r.

##### mi_normal_from_light
```void mi_normal_from_light(
miState        *const state,
miVector       *r,
miVector       *const v)
```

Convert normal v in object space of the current light as found in state→light_instance to internal space, r.