Version: v1.6.0

# Math Module

Taichi provides a built-in `math` module that supports frequently used mathematical functions and utility functions, including:

• Commonly-used mathematical functions that are analogous to those in Python's built-in `math` module.
• Small vector and matrix types that are analogous to those in the OpenGL shading language (GLSL).
• Some GLSL-standard functions.
• Complex number operations in the form of 2D vectors.

## Mathematical functions

You must call the mathematical functions provided by Taichi's `math` module from within the Taichi scope. For example:

``import taichi as tiimport taichi.math as tmti.init()@ti.kerneldef test():    a = 1.0    x = tm.sin(a)    y = tm.floor(a)    z = tm.degrees(a)    w = tm.log2(a)    ...``

These functions also take vectors and matrices as arguments and operate on them element-wise:

``@ti.kerneldef test():    a = ti.Vector([1.0, 2.0, 3.0])    x = tm.sin(a)  # [0.841471, 0.909297, 0.141120]    y = tm.floor(a)  #  [1.000000, 2.000000, 3.000000]    z = tm.degrees(a)  #  [57.295780, 114.591560, 171.887344]    b = ti.Vector([2.0, 3.0, 4.0])    w = tm.atan2(b, a)  # [1.107149, 0.982794, 0.927295]    ...``
##### note

Taichi's math module overlaps to a large extent with Python's built-in math module. Ensure that you follow a few extra rules when using Taichi's math module:

• You must call the functions provided by Taichi's math module from within the Taichi scope.
• Functions in Taichi's math module also take vectors or matrices as arguments.
• The precision of a function in Taichi's math module depends on the settings of `default_fp` and `arch` (backend) in `ti.init()`.

## Small vector and matrix types

Taichi's math module provides a few small vector and matrix types:

• `vec2/vec3/vec4`: 2D/3D/4D floating-point vector types.
• `ivec2/ivec3/ivec4`: 2D/3D/4D integer vector types.
• `uvec2/uvec3/uvec4`: 2D/3D/4D unsigned integer vector types.
• `mat2/mat3/mat4`: 2D/3D/4D floating-point square matrix types.

To create one of the vector/matrix types above, use template function `ti.types.vector()` or `ti.types.matrix()`. For example, `vec2` is defined as follows:

``vec2 = ti.types.vector(2, float)``

The number of precision bits of such a type is determined by `default_fp` or `default_ip` in the `ti.init()` method call. For example, if `ti.init(default_fp=ti.f64)` is called, then `vec2/vec3/vec4` and `mat2/mat3/mat4` defined in the Taichi scope all have a 64-bit floating-point precision.

You can use these types to instantiate vectors/matrices or annotate data types for function arguments and struct members. See the Type System for more information. Here we emphasize that they have very flexible initialization routines:

``mat2 = ti.math.mat2vec3 = ti.math.mat3vec4 = ti.math.vec4m = mat2(1)  # [[1., 1.], [1., 1.]]m = mat2(1, 2, 3, 4)  # [[1., 2.], [3, 4.]]m = mat2([1, 2], [3, 4])  # [[1., 2.], [3, 4.]]m = mat2([1, 2, 3, 4])  # [[1., 2.], [3, 4.]]v = vec3(1, 2, 3)m = mat2(v, 4)  # [[1., 2.], [3, 4.]]u = vec4([1, 2], [3, 4])u = vec4(v, 4.0)``

Another important feature of vector types created by `ti.types.vector()` is that they support vector swizzling just as GLSL vectors do. This means you can use `xyzw`, `rgba`, `stpq` to access their elements with indices four:

``v = ti.math.vec4(1, 2, 3, 4)u = v.xyz  # vec3(1, 2, 3)u = v.xxx  # vec3(1, 1, 1)u = v.wzyx  # vec4(4, 3, 2, 1)u = v.rraa  # vec4(1, 1, 2, 2)``

### Relations between `ti.Vector`, `ti.types.vector` and `ti.math.vec3`

• `ti.Vector` is a function that accepts a 1D array and returns a matrix instance that has only one column. For example, `ti.Vector([1, 2, 3, 4, 5])`.

• `ti.types.vector` is a function that accepts an integer and a primitive type and returns a vector type. For example: `vec5f = ti.types.vector(5, float)`. `vec5f` can then be used to instantiate 5D vectors or annotate data types of function arguments and struct members:

``@ti.kerneldef test(v: vec5f):    print(v.xyz)``

Unlike `ti.Vector`, whose input data must be a 1D array, vector types created by `ti.types.vector()` have more flexible ways to initialize, as explained above.

• `ti.math.vec3` is created by `vec3 = ti.types.vector(3, float)`.

## GLSL-standard functions

Taichi's math module also supports a few GLSL standard functions. These functions follow the GLSL standard, except that they accept arbitrary vectors and matrices as arguments and operate on them element-wise. For example:

``import taichi as tiimport taichi.math as tm@ti.kerneldef example():    v = tm.vec3(0., 1., 2.)    w = tm.smoothstep(0.0, 1.0, v)    w = tm.clamp(w, 0.2, 0.8)    w = tm.reflect(v, tm.normalize(tm.vec3(1)))``
##### note

Texture support in Taichi is implemented in the `ti.types.texture_types` module.

## Complex number operations

Taichi's math module also supports basic complex arithmetic operations on 2D vectors.

You can use a 2D vector of type `ti.math.vec2` to represent a complex number. In this way, additions and subtractions of complex numbers come in the form of 2D vector additions and subtractions. You can call `ti.math.cmul()` and `ti.math.cdiv()` to conduct multiplication and division of complex numbers:

``import taichi as tiimport taichi.math as tmti.init()@ti.kerneldef test():    x = tm.vec2(1, 1)  # complex number 1+1j    y = tm.vec2(0, 1)  # complex number 1j    z = tm.cmul(x, y)  # vec2(-1, 1) = -1+1j    w = tm.cdiv(x, y)  #  vec2(2, 0) = 2+0j``

You can also compute the power, logarithm, and exponential of a complex number:

``@ti.kerneldef test():    x = tm.vec2(1, 1)  # complex number 1 + 1j    y = tm.cpow(x, 2)  # complex number (1 + 1j)**2 = 2j    z = tm.clog(x)     # complex number (0.346574 + 0.785398j)    w = tm.cexp(x)     # complex number (1.468694 + 2.287355j)``