"""The WaveBlocks Project

This file contains the class for constructing high dimensional
quadrature rules from one-dimensional ones by taking tensor products.

@author: R. Bourquin
@copyright: Copyright (C) 2012, 2013 R. Bourquin
@license: Modified BSD License
"""

from copy import deepcopy
import operator as op
from numpy import vstack

from QuadratureRule import QuadratureRule
from Utils import meshgrid_nd

__all__ = ["TensorProductQR"]


class TensorProductQR(QuadratureRule):
    r"""This class implements the construction of high dimensional
    quadrature rules from one-dimensional ones by taking tensor products.
    """

    def __init__(self, rules, options={}):
        r"""
        Initialize a :py:class:`TensorProductQR` instance.

        :param rules: A list of :py:class:`QuadratureRule` subclass instances. Their
                      nodes and weights will be used to compute the tensor product.
        """
        # The dimension of the quadrature rule.
        self._dimension = len(rules)

        # The individual quadrature rules.
        self._qrs = tuple(rules)

        # The order R of the tensor product quadrature.
        self._order = None
        # TODO: Compute the order from the orders of the input QRs

        # Set the options
        self._options = options

        # The number of nodes in this quadrature rule.
        self._number_nodes = reduce(op.mul, [ rule.get_number_nodes() for rule in rules ])

        # The quadrature nodes \gamma.
        nodes = meshgrid_nd([ rule.get_nodes() for rule in rules ])
        self._nodes = vstack([ node.flatten() for node in nodes ])

        # The quadrature weights \omega.
        weights = meshgrid_nd([ rule.get_weights() for rule in rules ])
        weights = reduce(lambda x,y: x*y, weights)
        self._weights = weights.flatten()


    def __str__(self):
        s = "Tensor product quadrature rule consisting of:\n"
        l = ["  " + str(rule) + "\n" for rule in self._qrs]
        s += reduce(lambda x,y:x+y, l)
        return s


    def get_description(self):
        r"""Return a description of this quadrature rule object.
        A description is a ``dict`` containing all key-value pairs
        necessary to reconstruct the current instance. A description
        never contains any data.
        """
        d = {}
        d["type"] = "TensorProductQR"
        d["dimension"] = self._dimension
        d["qr_rules"] = [ qr.get_description() for qr in self._qrs ]
        d["options"] = deepcopy(self._options)
        return d


    def get_nodes(self, flat=True, split=False):
        r"""Returns the quadrature nodes :math:`\gamma_i`.

        :param flat: Dummy parameter for API compatibility with Grids.
        :type flat: Boolean, default is ``True``.
        :param split: Dummy parameter for API compatibility with Grids.
        :type split: Boolean, default is ``False``.
        :return: An :py:class:`ndarray` containing the quadrature nodes :math:`\gamma_i`.
        """
        return self._nodes.copy()


    def get_weights(self):
        r"""Returns the quadrature weights :math:`\omega_i`.

        :return: An :py:class:`ndarray` containing the quadrature weights :math:`\omega_i`.
        """
        return self._weights.copy()

@@ -1441,24 +1441,579 @@
 n rules %5D)%0A%0A
+        # Nodes and weights%0A        self._nodes, self._weights = self.tensor_product(rules)%0A%0A%0A    def tensor_product(self, rules):%0A        r%22%22%22Compute the tensor product of the given quadrature rules.%0A%0A        :param rules: A list of one dimensional quadrature rules.%0A        :return: The nodes :math:%60%5Cgamma%60 and weights :math:%60omega%60 of%0A                 the tensor product quadrature rule. The array of all%0A                 nodes has a shape of :math:%60(D, %7C%5CGamma%7C)%60 and the%0A                 array of weights is of shape :math:%60(%7C%5CGamma%7C)%60.%0A        %22%22%22%0A
         # Th
@@ -2111,30 +2111,24 @@
  %5D)%0A        
-self._
 nodes = vsta
@@ -2164,25 +2164,24 @@
 in nodes %5D)%0A
-%0A
         # Th
@@ -2340,31 +2340,29 @@
         
-self._weights =
+return nodes,
  weights

Clean up tensor product computations