diff --git a/docs/arithmetics.rst b/docs/arithmetics.rst new file mode 100644 index 0000000000000..cfdd31985eadf --- /dev/null +++ b/docs/arithmetics.rst @@ -0,0 +1,166 @@ +Scalar operations +================= + +Operators +--------- + +Arithmetic operators +******************** + +- ``-a`` +- ``a + b`` +- ``a - b`` +- ``a * b`` +- ``a / b`` +- ``a // b`` +- ``a % b`` +- ``a ** b`` + +.. note:: + + The ``%`` operator in Taichi follows the Python style instead of C style, e.g.: + + .. code-block:: python + + # no matter Taichi-scope or Python-scope: + print(2 % 3) # 2 + print(-2 % 3) # 1 + + For C-style mod, please use ``ti.raw_mod``: + + .. code-block:: python + + print(ti.raw_mod(2, 3)) # 2 + print(ti.raw_mod(-2, 3)) # -2 + +.. note:: + + Python 3 distinguishes ``/`` (true division) and ``//`` (floor division). For example, ``1.0 / 2.0 = 0.5``, + ``1 / 2 = 0.5``, ``1 // 2 = 0``, ``4.2 // 2 = 2``. And Taichi follows the same design: + + - **true divisions** on integral types will first cast their operands to the default float point type. + - **floor divisions** on float-point types will first cast their operands to the default integer type. + + To avoid such implicit casting, you can manually cast your operands to desired types, using ``ti.cast``. + See :ref:`default_precisions` for more details on default numerical types. + +Logic operators +*************** + +- ``~a`` +- ``a == b`` +- ``a != b`` +- ``a > b`` +- ``a < b`` +- ``a >= b`` +- ``a <= b`` +- ``not a`` +- ``a or b`` +- ``a and b`` +- ``a if cond else b`` + +Bitwise operators +***************** + +- ``a & b`` +- ``a ^ b`` +- ``a | b`` + +Functions +--------- + +Trigonometric functions +*********************** + +.. function:: ti.sin(x) +.. function:: ti.cos(x) +.. function:: ti.tan(x) +.. function:: ti.asin(x) +.. function:: ti.acos(x) +.. function:: ti.atan2(x, y) +.. function:: ti.tanh(x) + +Other arithmetic functions +************************** + +.. function:: ti.sqrt(x) +.. function:: ti.rsqrt(x) + + A fast version for ``1 / ti.sqrt(x)``. + +.. function:: ti.exp(x) +.. function:: ti.log(x) +.. function:: ti.floor(x) +.. function:: ti.ceil(x) + +Casting types +************* + +.. function:: ti.cast(x, dtype) + + See :ref:`type` for more details. + +.. function:: int(x) + + A shortcut for ``ti.cast(x, int)``. + +.. function:: float(x) + + A shortcut for ``ti.cast(x, float)``. + +Builtin-alike functions +*********************** + +.. function:: abs(x) +.. function:: max(x, y, ...) +.. function:: min(x, y, ...) +.. function:: pow(x, y) + + Same as ``x ** y``. + +Random number generator +*********************** + +.. function:: ti.random(dtype = float) + + +Element-wise arithmetics for vectors and matrices +------------------------------------------------- + +When these scalar functions are applied on :ref:`matrix` and :ref:`vector`, they are applied in an element-wise manner. +For example: + +.. code-block:: python + + B = ti.Matrix([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) + C = ti.Matrix([[3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]) + + A = ti.sin(B) + # is equivalent to + for i in ti.static(range(2)): + for j in ti.static(range(3)): + A[i, j] = ti.sin(B[i, j]) + + A = B ** 2 + # is equivalent to + for i in ti.static(range(2)): + for j in ti.static(range(3)): + A[i, j] = B[i, j] ** 2 + + A = B ** C + # is equivalent to + for i in ti.static(range(2)): + for j in ti.static(range(3)): + A[i, j] = B[i, j] ** C[i, j] + + A += 2 + # is equivalent to + for i in ti.static(range(2)): + for j in ti.static(range(3)): + A[i, j] += 2 + + A += B + # is equivalent to + for i in ti.static(range(2)): + for j in ti.static(range(3)): + A[i, j] += B[i, j] diff --git a/docs/index.rst b/docs/index.rst index f1cdef727c283..3f36d7f5052c6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,7 +18,6 @@ The Taichi Programming Language type tensor_matrix external - atomic .. toctree:: @@ -28,6 +27,8 @@ The Taichi Programming Language scalar_tensor vector matrix + arithmetics + atomic snode diff --git a/docs/syntax.rst b/docs/syntax.rst index 584722e442a50..f4418cd9a5e91 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -1,5 +1,5 @@ -Syntax -====== +Kernels and functions +===================== Taichi-scope vs Python-scope ---------------------------- @@ -270,82 +270,3 @@ reference: else: ret = 0.0 return ret - - -Scalar arithmetics ------------------- - -Supported scalar functions: - -.. function:: ti.sin(x) -.. function:: ti.cos(x) -.. function:: ti.asin(x) -.. function:: ti.acos(x) -.. function:: ti.atan2(x, y) -.. function:: ti.cast(x, data_type) -.. function:: ti.sqrt(x) -.. function:: ti.rsqrt(x) -.. function:: ti.floor(x) -.. function:: ti.ceil(x) -.. function:: ti.tan(x) -.. function:: ti.tanh(x) -.. function:: ti.exp(x) -.. function:: ti.log(x) -.. function:: ti.random(data_type) -.. function:: abs(x) -.. function:: int(x) -.. function:: float(x) -.. function:: max(x, y) -.. function:: min(x, y) -.. function:: pow(x, y) - -.. note:: - - Python 3 distinguishes ``/`` (true division) and ``//`` (floor division). For example, ``1.0 / 2.0 = 0.5``, - ``1 / 2 = 0.5``, ``1 // 2 = 0``, ``4.2 // 2 = 2``. Taichi follows this design: - - - **true divisions** on integral types will first cast their operands to the default float point type. - - **floor divisions** on float-point types will first cast their operands to the default integer type. - - To avoid such implicit casting, you can manually cast your operands to desired types, using ``ti.cast``. - See :ref:`default_precisions` for more details on default numerical types. - -.. note:: - - When these scalar functions are applied on :ref:`matrix` and :ref:`vector`, they are applied in an element-wise manner. - For example: - - .. code-block:: python - - B = ti.Matrix([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) - C = ti.Matrix([[3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]) - - A = ti.sin(B) - # is equivalent to - for i in ti.static(range(2)): - for j in ti.static(range(3)): - A[i, j] = ti.sin(B[i, j]) - - A = ti.pow(B, 2) - # is equivalent to - for i in ti.static(range(2)): - for j in ti.static(range(3)): - A[i, j] = ti.pow(B[i, j], 2) - - A = ti.pow(B, C) - # is equivalent to - for i in ti.static(range(2)): - for j in ti.static(range(3)): - A[i, j] = ti.pow(B[i, j], C[i, j]) - - A += 2 - # is equivalent to - for i in ti.static(range(2)): - for j in ti.static(range(3)): - A[i, j] += 2 - - A += B - # is equivalent to - for i in ti.static(range(2)): - for j in ti.static(range(3)): - A[i, j] += B[i, j] diff --git a/docs/type.rst b/docs/type.rst index 7c23b7cc46da5..dcff98c72cd03 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -1,3 +1,5 @@ +.. _type: + Type system =========== diff --git a/python/taichi/lang/ops.py b/python/taichi/lang/ops.py index 96b6858fdf0db..d4d36f9acda73 100644 --- a/python/taichi/lang/ops.py +++ b/python/taichi/lang/ops.py @@ -273,11 +273,9 @@ def logical_not(a): return _unary_operation(ti_core.expr_logic_not, lambda x: int(not x), a) -def random(dt=None): - if dt is None: - import taichi - dt = taichi.get_runtime().default_fp - x = Expr(ti_core.make_rand_expr(dt)) +def random(dtype=float): + dtype = cook_dtype(dtype) + x = Expr(ti_core.make_rand_expr(dtype)) return expr_init(x)