From 49265879b90bf1e00c96288512676ff1622b05ba Mon Sep 17 00:00:00 2001 From: chentianyu03 Date: Tue, 8 Dec 2020 14:00:36 +0800 Subject: [PATCH] remove complex module direction (#29419) (#29460) --- python/paddle/incubate/complex/__init__.py | 21 - python/paddle/incubate/complex/helper.py | 40 -- .../incubate/complex/tensor/__init__.py | 24 -- .../paddle/incubate/complex/tensor/linalg.py | 75 ---- .../incubate/complex/tensor/manipulation.py | 142 ------ python/paddle/incubate/complex/tensor/math.py | 404 ------------------ .../incubate/complex/tensor_op_patch.py | 53 --- 7 files changed, 759 deletions(-) delete mode 100644 python/paddle/incubate/complex/__init__.py delete mode 100644 python/paddle/incubate/complex/helper.py delete mode 100644 python/paddle/incubate/complex/tensor/__init__.py delete mode 100644 python/paddle/incubate/complex/tensor/linalg.py delete mode 100644 python/paddle/incubate/complex/tensor/manipulation.py delete mode 100644 python/paddle/incubate/complex/tensor/math.py delete mode 100644 python/paddle/incubate/complex/tensor_op_patch.py diff --git a/python/paddle/incubate/complex/__init__.py b/python/paddle/incubate/complex/__init__.py deleted file mode 100644 index ff61c52ca3..0000000000 --- a/python/paddle/incubate/complex/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from . import tensor -from .tensor_op_patch import monkey_patch_math_complex -from .tensor import * - -__all__ = tensor.__all__ + [] - -monkey_patch_math_complex() diff --git a/python/paddle/incubate/complex/helper.py b/python/paddle/incubate/complex/helper.py deleted file mode 100644 index 504cf51cec..0000000000 --- a/python/paddle/incubate/complex/helper.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ...fluid import framework - - -def is_complex(x): - """ - Return true if the input(x) is a ComplexVariable. - """ - return isinstance(x, framework.ComplexVariable) - - -def is_real(x): - """ - Return true if the input(x) is a real number Variable. - """ - return isinstance(x, framework.Variable) - - -def complex_variable_exists(inputs, layer_name): - for inp in inputs: - if is_complex(inp): - return - err_msg = "At least one inputs of layer complex." if len(inputs) > 1 \ - else "The input of layer complex." - raise ValueError(err_msg + layer_name + - "() must be ComplexVariable, please " - "use the layer for real numher instead.") diff --git a/python/paddle/incubate/complex/tensor/__init__.py b/python/paddle/incubate/complex/tensor/__init__.py deleted file mode 100644 index b9601a9f29..0000000000 --- a/python/paddle/incubate/complex/tensor/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from . import linalg -from . import math -from . import manipulation -from .linalg import * -from .math import * -from .manipulation import * - -__all__ = math.__all__ -__all__ += linalg.__all__ -__all__ += manipulation.__all__ diff --git a/python/paddle/incubate/complex/tensor/linalg.py b/python/paddle/incubate/complex/tensor/linalg.py deleted file mode 100644 index 946a0fd553..0000000000 --- a/python/paddle/incubate/complex/tensor/linalg.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ..helper import is_complex, is_real, complex_variable_exists -from ....fluid.framework import ComplexVariable -from ....fluid import layers - -__all__ = ['matmul', ] - - -def matmul(x, y, transpose_x=False, transpose_y=False, alpha=1.0, name=None): - """ - Applies matrix multiplication to two complex number tensors. See the - detailed description in :ref:`api_fluid_layers_matmul`. - - Args: - x (ComplexVariable|Variable): The first input, can be a ComplexVariable - with data type complex64 or complex128, or a Variable with data type - float32 or float64. - y (ComplexVariable|Variable): The second input, can be a ComplexVariable - with data type complex64 or complex128, or a Variable with data type - float32 or float64. - transpose_x (bool): Whether to transpose :math:`x` before multiplication. - transpose_y (bool): Whether to transpose :math:`y` before multiplication. - alpha (float): The scale of output. Default 1.0. - name(str|None): A name for this layer(optional). If set None, the layer - will be named automatically. - - Returns: - ComplexVariable: The product result, with the same data type as inputs. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - import paddle.fluid.dygraph as dg - with dg.guard(): - x = np.array([[1.0 + 1j, 2.0 + 1j], [3.0+1j, 4.0+1j]]) - y = np.array([1.0 + 1j, 1.0 + 1j]) - x_var = dg.to_variable(x) - y_var = dg.to_variable(y) - result = paddle.complex.matmul(x_var, y_var) - print(result.numpy()) - # [1.+5.j 5.+9.j] - """ - # x = a + bi, y = c + di - # P1 = ac; P2 = (a + b)(c + d); P3 = bd; then mm(x, y) = (P1-P3) + (P2-P1-P3)j - complex_variable_exists([x, y], "matmul") - a, b = (x.real, x.imag) if is_complex(x) else (x, None) - c, d = (y.real, y.imag) if is_complex(y) else (y, None) - P1 = layers.matmul(a, c, transpose_x, transpose_y, alpha, name) - if is_real(b) and is_real(d): - P2 = layers.matmul(a + b, c + d, transpose_x, transpose_y, alpha, name) - P3 = layers.matmul(b, d, transpose_x, transpose_y, alpha, name) - real = P1 - P3 - imag = P2 - P1 - P3 - elif is_real(b): - real = P1 - imag = layers.matmul(b, c, transpose_x, transpose_y, alpha, name) - else: - real = P1 - imag = layers.matmul(a, d, transpose_x, transpose_y, alpha, name) - return ComplexVariable(real, imag) diff --git a/python/paddle/incubate/complex/tensor/manipulation.py b/python/paddle/incubate/complex/tensor/manipulation.py deleted file mode 100644 index d1e0cbed82..0000000000 --- a/python/paddle/incubate/complex/tensor/manipulation.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from paddle.common_ops_import import * -from ..helper import is_complex, is_real, complex_variable_exists -from ....fluid.framework import ComplexVariable -from ....fluid import layers - -__all__ = [ - 'reshape', - 'transpose', -] - - -def reshape(x, shape, inplace=False, name=None): - """ - To change the shape of ``x`` without changing its data. - - There are some tricks when specifying the target shape. - - 1. -1 means the value of this dimension is inferred from the total element - number of x and remaining dimensions. Thus one and only one dimension can - be set -1. - - 2. 0 means the actual dimension value is going to be copied from the - corresponding dimension of x. The index of 0s in shape can not exceed - the dimension of x. - - Here are some examples to explain it. - - 1. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape - is [6, 8], the reshape operator will transform x into a 2-D tensor with - shape [6, 8] and leaving x's data unchanged. - - 2. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape - specified is [2, 3, -1, 2], the reshape operator will transform x into a - 4-D tensor with shape [2, 3, 4, 2] and leaving x's data unchanged. In this - case, one dimension of the target shape is set to -1, the value of this - dimension is inferred from the total element number of x and remaining - dimensions. - - 3. Given a 3-D tensor x with a shape [2, 4, 6], and the target shape - is [-1, 0, 3, 2], the reshape operator will transform x into a 4-D tensor - with shape [2, 4, 3, 2] and leaving x's data unchanged. In this case, - besides -1, 0 means the actual dimension value is going to be copied from - the corresponding dimension of x. - - Args: - x(ComplexVariable): the input. A ``Tensor`` or ``LoDTensor`` , data - type: ``complex64`` or ``complex128``. - shape(list|tuple|Variable): target shape. At most one dimension of - the target shape can be -1. If ``shape`` is a list or tuple, the - elements of it should be integers or Tensors with shape [1] and - data type ``int32``. If ``shape`` is an Variable, it should be - an 1-D Tensor of data type ``int32``. - inplace(bool, optional): If ``inplace`` is True, the output of - ``reshape`` is the same ComplexVariable as the input. Otherwise, - the input and output of ``reshape`` are different - ComplexVariables. Defaults to False. Note that if ``x``is more - than one OPs' input, ``inplace`` must be False. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name` . - - Returns: - ComplexVariable: A ``Tensor`` or ``LoDTensor``. The data type is same as ``x``. It is a new ComplexVariable if ``inplace`` is ``False``, otherwise it is ``x``. - - Raises: - ValueError: If more than one elements of ``shape`` is -1. - ValueError: If the element of ``shape`` is 0, the corresponding dimension should be less than or equal to the dimension of ``x``. - ValueError: If the elements in ``shape`` is negative except -1. - - Examples: - .. code-block:: python - - import paddle.fluid as fluid - import paddle.complex as cpx - import paddle.fluid.dygraph as dg - import numpy as np - - x_np = np.random.randn(2, 3, 4) + 1j * np.random.randn(2, 3, 4) - - place = fluid.CPUPlace() - with dg.guard(place): - x_var = dg.to_variable(x_np) - y_var = cpx.reshape(x_var, (2, -1)) - y_np = y_var.numpy() - print(y_np.shape) - # (2, 12) - """ - complex_variable_exists([x], "reshape") - if inplace: - x.real = fluid.layers.reshape(x.real, shape, inplace=inplace, name=name) - x.imag = fluid.layers.reshape(x.imag, shape, inplace=inplace, name=name) - return x - out_real = fluid.layers.reshape(x.real, shape, inplace=inplace, name=name) - out_imag = fluid.layers.reshape(x.imag, shape, inplace=inplace, name=name) - return ComplexVariable(out_real, out_imag) - - -def transpose(x, perm, name=None): - """ - Permute the data dimensions for complex number :attr:`input` according to `perm`. - - See :ref:`api_fluid_layers_transpose` for the real number API. - - Args: - x (ComplexVariable): The input n-D ComplexVariable with data type - complex64 or complex128. - perm (list): Permute the input according to the value of perm. - name (str): The name of this layer. It is optional. - - Returns: - ComplexVariable: A transposed n-D ComplexVariable, with the same data type as :attr:`input`. - - Examples: - .. code-block:: python - - import paddle - - x = paddle.to_tensor([[1.0 + 1.0j, 2.0 + 1.0j], [3.0+1.0j, 4.0+1.0j], [5.0+1.0j, 6.0+1.0j]]) - x_transposed = paddle.complex.transpose(x, [1, 0]) - print(x_transposed.numpy()) - #[[1.+1.j 3.+1.j 5.+1.j] - # [2.+1.j 4.+1.j 6.+1.j]] - - """ - complex_variable_exists([x], "transpose") - real = layers.transpose(x.real, perm, name) - imag = layers.transpose(x.imag, perm, name) - return ComplexVariable(real, imag) diff --git a/python/paddle/incubate/complex/tensor/math.py b/python/paddle/incubate/complex/tensor/math.py deleted file mode 100644 index 465e4887a1..0000000000 --- a/python/paddle/incubate/complex/tensor/math.py +++ /dev/null @@ -1,404 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from paddle.common_ops_import import * -from ..helper import is_complex, is_real, complex_variable_exists -from ....fluid.framework import ComplexVariable -from ....fluid import layers -from ....tensor import math - -__all__ = [ - 'elementwise_add', - 'elementwise_sub', - 'elementwise_mul', - 'elementwise_div', - 'kron', - 'trace', - 'sum', -] - - -def elementwise_add(x, y, axis=-1, name=None): - """ - The element-wise addition layer for complex number inputs. At least one of - inputs :attr:`x` and :attr:`y` must be a ComplexVariable. See the detailed - description for the function and other arguments - in :ref:`api_fluid_layers_elementwise_add` . - - Args: - x (Variable|ComplexVariable): The first input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - y (Variable|ComplexVariable): The second input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name`. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - import paddle.fluid.dygraph as dg - - a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]]) - b = np.array([[5.0+2.0j, 6.0+2.0j], [7.0+2.0j, 8.0+2.0j]]) - with dg.guard(): - x = dg.to_variable(a) - y = dg.to_variable(b) - out = paddle.complex.elementwise_add(x, y) - print(out.numpy()) - # [[ 6.+3.j 8.+3.j] - # [10.+3.j 12.+3.j]] - """ - complex_variable_exists([x, y], "elementwise_add") - (x_real, x_imag) = (x.real, x.imag) if is_complex(x) else (x, None) - (y_real, y_imag) = (y.real, y.imag) if is_complex(y) else (y, None) - real = layers.elementwise_add(x_real, y_real, axis=axis, name=name) - if is_real(x_imag) and is_real(y_imag): - imag = layers.elementwise_add(x_imag, y_imag, axis=axis, name=name) - elif is_real(x_imag): - imag = layers.assign(x_imag) - else: - imag = layers.elementwise_add( - layers.zeros_like(x_real), y_imag, axis=axis, name=name) - return ComplexVariable(real, imag) - - -def elementwise_sub(x, y, axis=-1, name=None): - """ - The element-wise subtraction layer for complex number inputs. At least one of - inputs :attr:`x` and :attr:`y` must be a ComplexVariable. See the detailed - description for the function and other arguments - in :ref:`api_fluid_layers_elementwise_sub` . - - Args: - x (Variable|ComplexVariable): The first input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - y (Variable|ComplexVariable): The second input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name`. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - import paddle.fluid.dygraph as dg - - a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]]) - b = np.array([[5.0+2.0j, 6.0+2.0j], [7.0+2.0j, 8.0+2.0j]]) - with dg.guard(): - x = dg.to_variable(a) - y = dg.to_variable(b) - out = paddle.complex.elementwise_sub(x, y) - print(out.numpy()) - # [[-4.-1.j -4.-1.j] - # [-4.-1.j -4.-1.j]] - """ - complex_variable_exists([x, y], "elementwise_sub") - (x_real, x_imag) = (x.real, x.imag) if is_complex(x) else (x, None) - (y_real, y_imag) = (y.real, y.imag) if is_complex(y) else (y, None) - real = layers.elementwise_sub(x_real, y_real, axis=axis, name=name) - if is_real(x_imag) and is_real(y_imag): - imag = layers.elementwise_sub(x_imag, y_imag, axis=axis, name=name) - elif is_real(x_imag): - imag = layers.assign(x_imag) - else: - imag = layers.elementwise_sub( - layers.zeros_like(x_real), y_imag, axis=axis, name=name) - return ComplexVariable(real, imag) - - -def elementwise_mul(x, y, axis=-1, name=None): - """ - The element-wise multiplication layer for complex number inputs. At least - one of inputs :attr:`x` and :attr:`y` must be a ComplexVariable. See the - detailed description for the function and other arguments - in :ref:`api_fluid_layers_elementwise_mul` . - - Args: - x (Variable|ComplexVariable): The first input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - y (Variable|ComplexVariable): The second input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name`. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - import paddle.fluid.dygraph as dg - - a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]]) - b = np.array([[5.0+2.0j, 6.0+2.0j], [7.0+2.0j, 8.0+2.0j]]) - with dg.guard(): - x = dg.to_variable(a) - y = dg.to_variable(b) - out = paddle.complex.elementwise_mul(x, y) - print(out.numpy()) - # [[ 3. +7.j 10.+10.j] - # [19.+13.j 30.+16.j]] - """ - complex_variable_exists([x, y], "elementwise_mul") - # (a + bi)(c + di) = (ac - bd) + (bc + ad)i - (a, b) = (x.real, x.imag) if is_complex(x) else (x, None) - (c, d) = (y.real, y.imag) if is_complex(y) else (y, None) - - ac = layers.elementwise_mul(a, c, axis=axis, name=name) - bd = layers.elementwise_mul( - b, d, axis=axis, name=name) if is_real(b) and is_real(d) else None - bc = layers.elementwise_mul( - b, c, axis=axis, name=name) if is_real(b) else None - ad = layers.elementwise_mul( - a, d, axis=axis, name=name) if is_real(d) else None - real = ac - bd if is_real(bd) else ac - imag = bc + ad if is_real(bc) and is_real(ad) else bc if is_real(bc) else ad - return ComplexVariable(real, imag) - - -def elementwise_div(x, y, axis=-1, name=None): - """ - The element-wise division layer for complex number inputs. At least one of - inputs :attr:`x` and :attr:`y` must be a ComplexVariable. See the detailed - description for the function and other arguments - in :ref:`api_fluid_layers_elementwise_div` . - - Args: - x (Variable|ComplexVariable): The first input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - y (Variable|ComplexVariable): The second input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name`. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - import paddle.fluid.dygraph as dg - - a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]]) - b = np.array([[5.0+2.0j, 6.0+2.0j], [7.0+2.0j, 8.0+2.0j]]) - with dg.guard(): - x = dg.to_variable(a) - y = dg.to_variable(b) - out = paddle.complex.elementwise_div(x, y) - print(out.numpy()) - # [[0.24137931+0.10344828j 0.35 +0.05j ] - # [0.43396226+0.01886792j 0.5 +0.j ]] - """ - complex_variable_exists([x, y], "elementwise_div") - # (a + bi)/(c + di) = (a + bi)(c - di)/(c^2 + d^2) - (c, d) = (y.real, y.imag) if is_complex(y) else (y, None) - y_conj = ComplexVariable(c, -d) if is_real(d) else c - e = 1 / (layers.pow(c, 2.0) + layers.pow(d, 2.0) - ) if is_real(d) else 1 / layers.pow(c, 2.0) - return elementwise_mul( - elementwise_mul( - x, y_conj, axis=axis, name=name), - e, - axis=axis, - name=name) - - -def trace(x, offset=0, axis1=0, axis2=1, name=None): - """ - The layer to compute the trace for a complex number tensor. x :attr:`x` must be a ComplexVariable. - See the detailed description for the function and other arguments - in :ref:`api_tensor_math_trace` . - - Args: - x(ComplexVariable): The input ComplexVariable x. Must be at least 2-dimensional. - The supported data types include complex64 and complex128. - offset(int, optional): Which diagonals in input tensor x will be taken. Default: 0 (main diagonals). - axis1(int, optional): The first axis with respect to take diagonal. Default: 0. - axis2(int, optional): The second axis with respect to take diagonal. Default: 1. - name (str, optional): Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default: None. - - Returns: - ComplexVariable: The trace result of input tensor x, it's data type is the same as input data type. - - Examples: - .. code-block:: python - - import paddle - import numpy as np - - case1 = np.random.randn(3, 10, 10).astype('float64') + 1j * np.random.randn(3, 10, 10).astype('float64') - - paddle.disable_static() - case1 = paddle.to_tensor(case1) - data1 = paddle.complex.trace(case1, offset=1, axis1=1, axis2=2) # data1.shape = [3] - """ - complex_variable_exists([x], "trace") - real = math.trace(x.real, offset, axis1, axis2, name) - imag = math.trace(x.imag, offset, axis1, axis2, name) - - return ComplexVariable(real, imag) - - -def sum(input, dim=None, keep_dim=False, name=None): - """ - The layer to compute the sum for a complex number tensor elements over the given dimension. input :attr:`input` must be a ComplexVariable. - See the detailed description for the function and other arguments - in :ref:`api_tensor_math_sum` . - - Args: - input(ComplexVariable): The input ComplexVariable with any number of dimensions. - The supported data types include complex64 and complex128. - dim (list|int, optional): The dimensions along which the sum is performed. If - :attr:`None`, sum all elements of :attr:`input` and return a - Tensor variable with a single element, otherwise must be in the - range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`, - the dimension to reduce is :math:`rank + dim[i]`. - keep_dim (bool, optional): Whether to reserve the reduced dimension in the - output Tensor. The result tensor will have one fewer dimension - than the :attr:`input` unless :attr:`keep_dim` is true, default - value is False. - name(str, optional): The default value is None. Normally there is no need for - user to set this property. For more information, please refer to :ref:`api_guide_Name` - - Returns: - ComplexVariable: Results of summation operation on the specified dim of input tensor, - it's data type is the same as input. - - Raises: - ValueError: the :attr:`dtype` must be float64 or int64. - - Examples: - .. code-block:: python - - import paddle.complex as cpx - import paddle.fluid.dygraph as dg - import numpy as np - - with dg.guard(): - # x is a Tensor variable with following elements: - # [[0.2, 0.3, 0.5, 0.9], - # [0.1, 0.2, 0.6, 0.7]] - # Each example is followed by the corresponding output tensor. - x = np.array([[0.2, 0.3, 0.5, 0.9],[0.1, 0.2, 0.6, 0.7]]) + 1j * np.array([[0.3, 0.4, 0.5, 0.2],[0.3, 0.6, 0.8, 0.3]]) - x = dg.to_variable(x) - out1 = cpx.sum(x) # [3.5+3.4j] - out2 = cpx.sum(x, dim=0) # [0.3+0.6j, 0.5+1.j, 1.1+1.3j, 1.6+0.5j] - out3 = cpx.sum(x, dim=-1) # [1.9+1.4j, 1.6+2.j] - out4 = cpx.sum(x, dim=1, keep_dim=True) # [[1.9+1.4j], [1.6+2.j]] - - # y is a Tensor variable with shape [2, 2, 2] and elements as below: - # [[[1, 2], [3, 4]], - # [[5, 6], [7, 8]]] - # Each example is followed by the corresponding output tensor. - y = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + 1j * np.array([[[4, 3], [2, 1]], [[8, 7], [6, 5]]]) - y = dg.to_variable(y) - out5 = cpx.sum(y, dim=[1, 2]) # [10.+10.j, 26.+26.j] - out6 = cpx.sum(y, dim=[0, 1]) # [16.+20.j, 20.+16.j] - - """ - complex_variable_exists([input], "sum") - real = math.sum(input.real, axis=dim, keepdim=keep_dim, name=name) - imag = math.sum(input.imag, axis=dim, keepdim=keep_dim, name=name) - return ComplexVariable(real, imag) - - -def kron(x, y, name=None): - """ - The kronecker product of two complex tensors. At least one of inputs :attr:`x` - and :attr:`y` must be a ComplexVariable. See the detailed description for - the function and other arguments in :ref:`api_paddle_tensor_kron` . - - Let $x = a + ib$, and $y = c + id$, the euqation is - - .. math:: - kron(x, y) = kron(a, c) - kron(b, d) + i(kron(a, d) + kron(b, c)) - - Args: - x (Variable|ComplexVariable): The first input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - y (Variable|ComplexVariable): The second input Variable or ComplexVariable - with any number of dimensions. The supported data types include float32 - and float64 when it is a Variable. Otherwise the supported data types - are complex64 or complex128. - name(str, optional): The default value is None. Normally there is no - need for user to set this property. For more information, please - refer to :ref:`api_guide_Name`. - - Returns: - ComplexVariable: The kronecker product, data type: complex64 or complex128, depending on the data type of x and y. If the data types of x and y are float32/complex64, the data type of the output is complex64, else if the data types of x and y are float64/complex128, the data type of the output is complex128. - - Examples: - .. code-block:: python - - import numpy as np - import paddle - from paddle import fluid - import paddle.fluid.dygraph as dg - - a = np.array([[1.0+1.0j, 2.0+1.0j], [3.0+1.0j, 4.0+1.0j]]) - b = np.array([[5.0+2.0j, 6.0+2.0j], [7.0+2.0j, 8.0+2.0j]]) - - place = fluid.CPUPlace() - with dg.guard(place): - x = dg.to_variable(a) - y = dg.to_variable(b) - out = paddle.complex.kron(x, y) - print(out.numpy()) - # [[ 3. +7.j 4. +8.j 8. +9.j 10.+10.j] - # [ 5. +9.j 6.+10.j 12.+11.j 14.+12.j] - # [13.+11.j 16.+12.j 18.+13.j 22.+14.j] - # [19.+13.j 22.+14.j 26.+15.j 30.+16.j]] - """ - complex_variable_exists([x, y], "kron") - - # X = A + Bi, Y = C+Di - # kron(X, Y) = kron(A, C) - kron(B, D) + (kron(A, D) + kron(B, C))i - (a, b) = (x.real, x.imag) if is_complex(x) else (x, None) - (c, d) = (y.real, y.imag) if is_complex(y) else (y, None) - - if is_real(b) and is_real(d): - real = math.kron(a, c) - math.kron(b, d) - imag = math.kron(a, d) + math.kron(b, c) - elif is_real(b): - real = math.kron(a, c) - imag = math.kron(b, c) - else: - # is_real(d) - real = math.kron(a, c) - imag = math.kron(a, d) - return ComplexVariable(real, imag) diff --git a/python/paddle/incubate/complex/tensor_op_patch.py b/python/paddle/incubate/complex/tensor_op_patch.py deleted file mode 100644 index eb7dbd2a3b..0000000000 --- a/python/paddle/incubate/complex/tensor_op_patch.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import division -from ...fluid import framework -from . import tensor - - -def monkey_patch_math_complex(): - # complexVariable do not support scaler type now, so here not contains - # reverse methods, such as "__radd__", "__rsub__", "__rmul__", "__rdiv__", - # "__rtruediv__", "__rmatmul__". - complex_methods = [ - ('__add__', _binary_creator_('__add__', "elementwise_add", False)), - ('__sub__', _binary_creator_('__sub__', "elementwise_sub", False)), - ('__mul__', _binary_creator_('__mul__', "elementwise_mul", False)), - ('__div__', _binary_creator_('__div__', "elementwise_div", False)), - ('__truediv__', _binary_creator_('__truediv__', "elementwise_div", - False)), - ('__matmul__', _binary_creator_('__matmul__', "matmul", False)), - ] - - for method in complex_methods: - method_name = method[0] - method_impl = method[1] - if method_impl: - setattr(framework.ComplexVariable, method_name, method_impl) - - for method in tensor.__all__: - method_impl = getattr(tensor, method) - if method_impl: - setattr(framework.ComplexVariable, method, method_impl) - - -# for binary operator such as elementwise -def _binary_creator_(method_name, op_type, reverse=False): - def __impl__(self, other_var): - math_op = getattr(tensor, op_type) - return math_op(self, other_var) - - __impl__.__name__ = method_name - return __impl__ -- GitLab