Skip to content

Commit

Permalink
[Doc] Separate arithmetics.rst from syntax.rst and fill it with more …
Browse files Browse the repository at this point in the history
…details (#1761)

* [Doc] Separate arithmetics.rst from syntax.rst and fill it with more details

* [skip ci] missing

* [skip ci] Update docs/arithmetics.rst

* [skip ci] Apply suggestions from code review
  • Loading branch information
archibate authored Aug 26, 2020
1 parent 7cb37fe commit 0077ccb
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 87 deletions.
166 changes: 166 additions & 0 deletions docs/arithmetics.rst
Original file line number Diff line number Diff line change
@@ -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]
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ The Taichi Programming Language
type
tensor_matrix
external
atomic


.. toctree::
Expand All @@ -28,6 +27,8 @@ The Taichi Programming Language
scalar_tensor
vector
matrix
arithmetics
atomic
snode


Expand Down
83 changes: 2 additions & 81 deletions docs/syntax.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Syntax
======
Kernels and functions
=====================

Taichi-scope vs Python-scope
----------------------------
Expand Down Expand Up @@ -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]
2 changes: 2 additions & 0 deletions docs/type.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _type:

Type system
===========

Expand Down
8 changes: 3 additions & 5 deletions python/taichi/lang/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down

0 comments on commit 0077ccb

Please sign in to comment.