← Back to team overview

ufl team mailing list archive

Re: Support for tan(x)

 

Attached is a patch for inverse trig functions (subsumes the previous
patch). asin(x)/acos(x) evaluate to real numbers for a very narrow range
of x, so I have disabled their tests for now.

Also attached is a small FFC patch to expose this functionality.

Harish

On 3/16/10 4:17 PM, Anders Logg wrote:
> Sounds good to me. Go ahead and add the others. Maybe you could throw
> in some Bessel functions as well. :-)
> 
> I'll push it later (if no one else has pushed it by then).
> 
> --
> Anders
> 
> 
> On Tue, Mar 16, 2010 at 03:34:15PM +0100, Harish Narayanan wrote:
>> I have attached a patch which adds support for evaluating and
>> differentiating tan(f) in UFL forms. If this is acceptable, I plan to
>> similarly add inverse trigonometric functions.
>>
>> Harish
> 
>> # Bazaar merge directive format 2 (Bazaar 0.90)
>> # revision_id: hnarayanan@xxxxxxxxx-20100316142718-t6amwqkb9j70u0j5
>> # target_branch: bzr+ssh://bazaar.launchpad.net/~ufl-core/ufl/main/
>> # testament_sha1: b8523f9c30cb9e70ef5f736b0c5b00d198551b87
>> # timestamp: 2010-03-16 15:31:38 +0100
>> # base_revision_id: k.b.oelgaard@xxxxxxxxx-20100216094344-\
>> #   xgpckx7p1jdwh523
>> #
>> # Begin patch
>> === modified file 'TODO'
>> --- TODO	2009-12-08 15:59:29 +0000
>> +++ TODO	2010-03-16 14:27:18 +0000
>> @@ -145,7 +145,6 @@
>>        even if f is defined on a quadrature element.
>>
>>  # Additional operators (low priority):
>> -    - tan(f)
>>      - log(f, base)
>>      - other mathematical functions in <cmath> (need derivatives)
>>      - bessel functions (needs non-standard library code)
>>
>> === modified file 'test/derivative.py'
>> --- test/derivative.py	2010-02-07 21:15:52 +0000
>> +++ test/derivative.py	2010-03-16 14:27:18 +0000
>> @@ -91,6 +91,11 @@
>>          def df(w, v): return -v*sin(w)
>>          self._test(f, df)
>>
>> +    def testTan(self):
>> +        def f(w):  return tan(w)
>> +        def df(w, v): return v*2.0/(cos(2.0*w) + 1.0)
>> +        self._test(f, df)
>> +
>>      def testIndexSum(self):
>>          def f(w):
>>              # 3*w + 4*w**2 + 5*w**3
>>
>> === modified file 'test/diff.py'
>> --- test/diff.py	2009-03-27 13:03:47 +0000
>> +++ test/diff.py	2010-03-16 14:27:18 +0000
>> @@ -83,6 +83,11 @@
>>          def df(v): return -sin(v)
>>          self._test(f, df)
>>
>> +    def testTan(self):
>> +        def f(v):  return tan(v)
>> +        def df(v): return 2.0/(cos(2.0*v) + 1.0)
>> +        self._test(f, df)
>> +
>>      def testIndexSum(self):
>>          def f(v):
>>              # 3*v + 4*v**2 + 5*v**3
>>
>> === modified file 'test/evaluate.py'
>> --- test/evaluate.py	2009-12-08 15:59:29 +0000
>> +++ test/evaluate.py	2010-03-16 14:27:18 +0000
>> @@ -120,6 +120,11 @@
>>          e = s((5,7))
>>          v = math.cos(5)
>>          self.assertTrue(e == v)
>> +
>> +        s = tan(x)
>> +        e = s((5,7))
>> +        v = math.tan(5)
>> +        self.assertTrue(e == v)
>>
>>          s = ln(x)
>>          e = s((5,7))
>>
>> === modified file 'ufl/__init__.py'
>> --- ufl/__init__.py	2010-02-15 15:12:43 +0000
>> +++ ufl/__init__.py	2010-03-16 14:27:18 +0000
>> @@ -80,7 +80,7 @@
>>      Dx, grad, div, curl, rot, Dn
>>
>>  Nonlinear functions:
>> -    abs, sign, sqrt, exp, ln, cos, sin,
>> +    abs, sign, sqrt, exp, ln, cos, sin, tan
>>
>>  Discontinuous Galerkin operators:
>>      jump, avg, v('+'), v('-')
>> @@ -163,7 +163,7 @@
>>                         outer, inner, dot, cross, \
>>                         det, inv, cofac, \
>>                         transpose, tr, dev, skew, sym, \
>> -                       sqrt, exp, ln, cos, sin, \
>> +                       sqrt, exp, ln, cos, sin, tan, \
>>                         eq, ne, le, ge, lt, gt, conditional, sign, \
>>                         variable, diff, \
>>                         Dx,  grad, div, curl, rot, Dn, \
>>
>> === modified file 'ufl/algorithms/forward_ad.py'
>> --- ufl/algorithms/forward_ad.py	2009-12-08 15:59:29 +0000
>> +++ ufl/algorithms/forward_ad.py	2010-03-16 14:27:18 +0000
>> @@ -23,7 +23,7 @@
>>  from ufl.algebra import Sum, Product, Division, Power, Abs
>>  from ufl.tensoralgebra import Transposed, Outer, Inner, Dot, Cross, Trace, \
>>      Determinant, Inverse, Deviatoric, Cofactor
>> -from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin
>> +from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin, Tan
>>  from ufl.restriction import Restricted, PositiveRestricted, NegativeRestricted
>>  from ufl.differentiation import Derivative, FunctionDerivative,\
>>      SpatialDerivative, VariableDerivative
>> @@ -33,7 +33,7 @@
>>  #from ufl.classes import ufl_classes, terminal_classes, nonterminal_classes
>>  from ufl.classes import terminal_classes
>>  from ufl.operators import dot, inner, outer, lt, eq, conditional, sign
>> -from ufl.operators import sqrt, exp, ln, cos, sin
>> +from ufl.operators import sqrt, exp, ln, cos, sin, tan
>>  from ufl.algorithms.traversal import iter_expressions
>>  from ufl.algorithms.analysis import extract_type
>>  from ufl.algorithms.transformations import expand_compounds, Transformer, transform, transform_integrands
>> @@ -402,6 +402,12 @@
>>          op = fp*cos(f)
>>          return (o, op)
>>
>> +    def tan(self, o, a):
>> +        f, fp = a
>> +        o = self.reuse_if_possible(o, f)
>> +        op = fp*2.0/(cos(2.0*f) + 1.0)
>> +        return (o, op)
>> +
>>      # --- Restrictions
>>
>>      def positive_restricted(self, o, a):
>>
>> === modified file 'ufl/algorithms/pdiffs.py'
>> --- ufl/algorithms/pdiffs.py	2009-04-25 09:47:05 +0000
>> +++ ufl/algorithms/pdiffs.py	2010-03-16 14:27:18 +0000
>> @@ -7,7 +7,7 @@
>>  from ufl.log import error
>>  from ufl.assertions import ufl_assert
>>  from ufl.classes import Zero, IntValue, FloatValue
>> -from ufl.operators import sin, cos, exp, ln, sqrt, conditional, sign
>> +from ufl.operators import sin, cos, tan, exp, ln, sqrt, conditional, sign
>>  from ufl.tensors import unit_vectors, ListTensor
>>  from ufl.algorithms.transformations import MultiFunction
>>
>> @@ -100,6 +100,11 @@
>>          "d/dx sin x = cos(x)"
>>          x, = f.operands()
>>          return (cos(x),)
>> +
>> +    def tan(self, f):
>> +        "d/dx tan x = (sec(x))^2 = 2/(cos(2x) + 1)"
>> +        x, = f.operands()
>> +        return (2.0/(cos(2.0*x) + 1.0),)
>>
>>      # --- Shape and indexing manipulators
>>
>>
>> === modified file 'ufl/algorithms/ufl2latex.py'
>> --- ufl/algorithms/ufl2latex.py	2010-02-07 21:15:52 +0000
>> +++ ufl/algorithms/ufl2latex.py	2010-03-16 14:27:18 +0000
>> @@ -22,7 +22,7 @@
>>  from ufl.algebra import Sum, Product, Division, Power, Abs
>>  from ufl.indexsum import IndexSum
>>  from ufl.tensoralgebra import Transposed, Outer, Inner, Dot, Cross, Trace, Determinant, Inverse, Deviatoric, Cofactor
>> -from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin
>> +from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin, Tan
>>  from ufl.restriction import PositiveRestricted, NegativeRestricted
>>  from ufl.differentiation import SpatialDerivative, VariableDerivative, Grad, Div, Curl
>>  from ufl.conditional import EQ, NE, LE, GE, LT, GT, Conditional
>> @@ -206,6 +206,9 @@
>>      def sin(self, o, f):
>>          return r"\sin{%s}" % par(f)
>>
>> +    def tan(self, o, f):
>> +        return r"\tan{%s}" % par(f)
>> +
>>      def power(self, o, a, b):
>>          return "{%s}^{%s}" % (par(a), par(b))
>>
>>
>> === modified file 'ufl/classes.py'
>> --- ufl/classes.py	2009-12-08 15:59:29 +0000
>> +++ ufl/classes.py	2010-03-16 14:27:18 +0000
>> @@ -21,7 +21,7 @@
>>  from ufl.tensors import ListTensor, ComponentTensor
>>  from ufl.algebra import Sum, Product, Division, Power, Abs
>>  from ufl.tensoralgebra import CompoundTensorOperator, Transposed, Outer, Inner, Dot, Cross, Trace, Determinant, Cofactor, Inverse, Deviatoric, Skew, Sym
>> -from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin
>> +from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin, Tan
>>  from ufl.restriction import Restricted, PositiveRestricted, NegativeRestricted
>>  from ufl.lifting import LiftingResult, LiftingOperatorResult, LiftingFunctionResult, TerminalOperator, LiftingOperator, LiftingFunction
>>  from ufl.differentiation import Derivative, CompoundDerivative, FunctionDerivative, SpatialDerivative, VariableDerivative, Grad, Div, Curl
>>
>> === modified file 'ufl/mathfunctions.py'
>> --- ufl/mathfunctions.py	2009-04-21 07:40:04 +0000
>> +++ ufl/mathfunctions.py	2010-03-16 14:27:18 +0000
>> @@ -94,3 +94,11 @@
>>      def __init__(self, argument):
>>          MathFunction.__init__(self, "sin", argument)
>>
>> +class Tan(MathFunction):
>> +    def __new__(cls, argument):
>> +        if isinstance(argument, (ScalarValue, Zero)):
>> +            return FloatValue(math.tan(float(argument)))
>> +        return MathFunction.__new__(cls)
>> +
>> +    def __init__(self, argument):
>> +        MathFunction.__init__(self, "tan", argument)
>>
>> === modified file 'ufl/operators.py'
>> --- ufl/operators.py	2009-12-01 17:09:26 +0000
>> +++ ufl/operators.py	2010-03-16 14:27:18 +0000
>> @@ -16,7 +16,7 @@
>>  from ufl.variable import Variable
>>  from ufl.tensors import as_tensor
>>  from ufl.conditional import EQ, NE, LE, GE, LT, GT, Conditional
>> -from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin
>> +from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin, Tan
>>  from ufl.indexing import indices
>>  from ufl.geometry import SpatialCoordinate
>>
>> @@ -283,3 +283,6 @@
>>      "The sinus of f."
>>      return _mathfunction(f, Sin, math.sin)
>>
>> +def tan(f):
>> +    "The tangent of f."
>> +    return _mathfunction(f, Tan, math.tan)
>>
>> # Begin bundle
>> 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
>> 50A=
> 
>> _______________________________________________
>> Mailing list: https://launchpad.net/~ufl
>> Post to     : ufl@xxxxxxxxxxxxxxxxxxx
>> Unsubscribe : https://launchpad.net/~ufl
>> More help   : https://help.launchpad.net/ListHelp
> 

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: hnarayanan@xxxxxxxxx-20100317151637-90381sjs5scc9ysi
# target_branch: bzr+ssh://bazaar.launchpad.net/~ufl-core/ufl/main/
# testament_sha1: d8a8805513f63a0e12434813ac19fd529dd54d26
# timestamp: 2010-03-17 16:17:05 +0100
# base_revision_id: k.b.oelgaard@xxxxxxxxx-20100216094344-\
#   xgpckx7p1jdwh523
# 
# Begin patch
=== modified file 'TODO'
--- TODO	2009-12-08 15:59:29 +0000
+++ TODO	2010-03-16 14:27:18 +0000
@@ -145,7 +145,6 @@
       even if f is defined on a quadrature element.
 
 # Additional operators (low priority):
-    - tan(f)
     - log(f, base)
     - other mathematical functions in <cmath> (need derivatives)
     - bessel functions (needs non-standard library code)

=== modified file 'test/derivative.py'
--- test/derivative.py	2010-02-07 21:15:52 +0000
+++ test/derivative.py	2010-03-17 15:16:37 +0000
@@ -81,14 +81,35 @@
         def df(w, v): return v / w
         self._test(f, df)
 
+    def testCos(self):
+        def f(w):  return cos(w)
+        def df(w, v): return -v*sin(w)
+        self._test(f, df)
+
     def testSin(self):
         def f(w):  return sin(w)
         def df(w, v): return v*cos(w)
         self._test(f, df)
 
-    def testCos(self):
-        def f(w):  return cos(w)
-        def df(w, v): return -v*sin(w)
+    def testTan(self):
+        def f(w):  return tan(w)
+        def df(w, v): return v*2.0/(cos(2.0*w) + 1.0)
+        self._test(f, df)
+
+# TODO: Check the following tests. They run into strange math domain errors.
+#     def testAcos(self):
+#         def f(w):  return acos(w)
+#         def df(w, v): return -v/sqrt(1.0 - w**2)
+#         self._test(f, df)
+
+#     def testAsin(self):
+#         def f(w):  return asin(w)
+#         def df(w, v): return v/sqrt(1.0 - w**2)
+#         self._test(f, df)
+
+    def testAtan(self):
+        def f(w):  return atan(w)
+        def df(w, v): return v/(1.0 + w**2)
         self._test(f, df)
 
     def testIndexSum(self):

=== modified file 'test/diff.py'
--- test/diff.py	2009-03-27 13:03:47 +0000
+++ test/diff.py	2010-03-17 15:16:37 +0000
@@ -83,6 +83,27 @@
         def df(v): return -sin(v)
         self._test(f, df)
 
+    def testTan(self):
+        def f(v):  return tan(v)
+        def df(v): return 2.0/(cos(2.0*v) + 1.0)
+        self._test(f, df)
+
+# TODO: Check the following tests. They run into strange math domain errors.
+#     def testAsin(self):
+#         def f(v):  return asin(v)
+#         def df(v): return 1/sqrt(1.0 - v**2)
+#         self._test(f, df)
+
+#     def testAcos(self):
+#         def f(v):  return acos(v)
+#         def df(v): return -1/sqrt(1.0 - v**2)
+#         self._test(f, df)
+
+    def testAtan(self):
+        def f(v):  return atan(v)
+        def df(v): return 1/(1.0 + v**2)
+        self._test(f, df)
+
     def testIndexSum(self):
         def f(v):
             # 3*v + 4*v**2 + 5*v**3

=== modified file 'test/evaluate.py'
--- test/evaluate.py	2009-12-08 15:59:29 +0000
+++ test/evaluate.py	2010-03-16 14:27:18 +0000
@@ -120,6 +120,11 @@
         e = s((5,7))
         v = math.cos(5)
         self.assertTrue(e == v)
+
+        s = tan(x)
+        e = s((5,7))
+        v = math.tan(5)
+        self.assertTrue(e == v)
         
         s = ln(x)
         e = s((5,7))

=== modified file 'ufl/__init__.py'
--- ufl/__init__.py	2010-02-15 15:12:43 +0000
+++ ufl/__init__.py	2010-03-17 15:16:37 +0000
@@ -80,7 +80,7 @@
     Dx, grad, div, curl, rot, Dn
 
 Nonlinear functions:
-    abs, sign, sqrt, exp, ln, cos, sin,
+    abs, sign, sqrt, exp, ln, cos, sin, tan, acos, asin, atan
 
 Discontinuous Galerkin operators:
     jump, avg, v('+'), v('-')
@@ -163,7 +163,7 @@
                        outer, inner, dot, cross, \
                        det, inv, cofac, \
                        transpose, tr, dev, skew, sym, \
-                       sqrt, exp, ln, cos, sin, \
+                       sqrt, exp, ln, cos, sin, tan, acos, asin, atan, \
                        eq, ne, le, ge, lt, gt, conditional, sign, \
                        variable, diff, \
                        Dx,  grad, div, curl, rot, Dn, \

=== modified file 'ufl/algorithms/forward_ad.py'
--- ufl/algorithms/forward_ad.py	2009-12-08 15:59:29 +0000
+++ ufl/algorithms/forward_ad.py	2010-03-17 15:16:37 +0000
@@ -23,7 +23,7 @@
 from ufl.algebra import Sum, Product, Division, Power, Abs
 from ufl.tensoralgebra import Transposed, Outer, Inner, Dot, Cross, Trace, \
     Determinant, Inverse, Deviatoric, Cofactor
-from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin
+from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin, Tan, Acos, Asin, Atan
 from ufl.restriction import Restricted, PositiveRestricted, NegativeRestricted
 from ufl.differentiation import Derivative, FunctionDerivative,\
     SpatialDerivative, VariableDerivative
@@ -33,7 +33,7 @@
 #from ufl.classes import ufl_classes, terminal_classes, nonterminal_classes
 from ufl.classes import terminal_classes
 from ufl.operators import dot, inner, outer, lt, eq, conditional, sign
-from ufl.operators import sqrt, exp, ln, cos, sin
+from ufl.operators import sqrt, exp, ln, cos, sin, tan, acos, asin, atan
 from ufl.algorithms.traversal import iter_expressions
 from ufl.algorithms.analysis import extract_type
 from ufl.algorithms.transformations import expand_compounds, Transformer, transform, transform_integrands
@@ -402,6 +402,30 @@
         op = fp*cos(f)
         return (o, op)
 
+    def tan(self, o, a):
+        f, fp = a
+        o = self.reuse_if_possible(o, f)
+        op = fp*2.0/(cos(2.0*f) + 1.0)
+        return (o, op)
+
+    def acos(self, o, a):
+        f, fp = a
+        o = self.reuse_if_possible(o, f)
+        op = -fp/sqrt(1.0 - f**2)
+        return (o, op)
+
+    def asin(self, o, a):
+        f, fp = a
+        o = self.reuse_if_possible(o, f)
+        op = fp/sqrt(1.0 - f**2)
+        return (o, op)
+
+    def atan(self, o, a):
+        f, fp = a
+        o = self.reuse_if_possible(o, f)
+        op = fp/(1.0 + f**2)
+        return (o, op)
+
     # --- Restrictions
 
     def positive_restricted(self, o, a):

=== modified file 'ufl/algorithms/pdiffs.py'
--- ufl/algorithms/pdiffs.py	2009-04-25 09:47:05 +0000
+++ ufl/algorithms/pdiffs.py	2010-03-17 15:16:37 +0000
@@ -7,7 +7,7 @@
 from ufl.log import error
 from ufl.assertions import ufl_assert
 from ufl.classes import Zero, IntValue, FloatValue
-from ufl.operators import sin, cos, exp, ln, sqrt, conditional, sign
+from ufl.operators import cos, sin, tan, acos, asin, atan, exp, ln, sqrt, conditional, sign
 from ufl.tensors import unit_vectors, ListTensor
 from ufl.algorithms.transformations import MultiFunction
 
@@ -100,6 +100,26 @@
         "d/dx sin x = cos(x)"
         x, = f.operands()
         return (cos(x),)
+
+    def tan(self, f):
+        "d/dx tan x = (sec(x))^2 = 2/(cos(2x) + 1)"
+        x, = f.operands()
+        return (2.0/(cos(2.0*x) + 1.0),)
+
+    def acos(self, f):
+        "d/dx acos x = -1/sqrt(1 - x^2)"
+        x, = f.operands()
+        return (-1.0/sqrt(1.0 - x**2),)
+    
+    def asin(self, f):
+        "d/dx asin x = 1/sqrt(1 - x^2)"
+        x, = f.operands()
+        return (1.0/sqrt(1.0 - x**2),)
+
+    def atan(self, f):
+        "d/dx atan x = 1/(1 + x^2)"
+        x, = f.operands()
+        return (1.0/(1.0 + x**2),)
     
     # --- Shape and indexing manipulators
     

=== modified file 'ufl/algorithms/ufl2latex.py'
--- ufl/algorithms/ufl2latex.py	2010-02-07 21:15:52 +0000
+++ ufl/algorithms/ufl2latex.py	2010-03-17 15:16:37 +0000
@@ -22,7 +22,7 @@
 from ufl.algebra import Sum, Product, Division, Power, Abs
 from ufl.indexsum import IndexSum
 from ufl.tensoralgebra import Transposed, Outer, Inner, Dot, Cross, Trace, Determinant, Inverse, Deviatoric, Cofactor
-from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin
+from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin, Tan, Acos, Asin, Atan
 from ufl.restriction import PositiveRestricted, NegativeRestricted
 from ufl.differentiation import SpatialDerivative, VariableDerivative, Grad, Div, Curl
 from ufl.conditional import EQ, NE, LE, GE, LT, GT, Conditional
@@ -62,7 +62,7 @@
                             Determinant, Trace, Cofactor, Inverse, Deviatoric))
     precedence_list.append((Product, Division, Cross, Dot, Outer, Inner))
     precedence_list.append((Indexed, Transposed, Power))
-    precedence_list.append((Abs, Cos, Exp, Ln, Sin, Sqrt))
+    precedence_list.append((Abs, Cos, Exp, Ln, Sin, Sqrt, Tan, Acos, Asin, Atan))
     precedence_list.append((Variable,))
     precedence_list.append(terminal_classes)
 
@@ -206,6 +206,18 @@
     def sin(self, o, f):
         return r"\sin{%s}" % par(f)
 
+    def tan(self, o, f):
+        return r"\tan{%s}" % par(f)
+
+    def acos(self, o, f):
+        return r"\arccos{%s}" % par(f)
+
+    def asin(self, o, f):
+        return r"\arcsin{%s}" % par(f)
+
+    def atan(self, o, f):
+        return r"\arctan{%s}" % par(f)
+
     def power(self, o, a, b):
         return "{%s}^{%s}" % (par(a), par(b))
 

=== modified file 'ufl/classes.py'
--- ufl/classes.py	2009-12-08 15:59:29 +0000
+++ ufl/classes.py	2010-03-17 15:16:37 +0000
@@ -21,7 +21,7 @@
 from ufl.tensors import ListTensor, ComponentTensor
 from ufl.algebra import Sum, Product, Division, Power, Abs
 from ufl.tensoralgebra import CompoundTensorOperator, Transposed, Outer, Inner, Dot, Cross, Trace, Determinant, Cofactor, Inverse, Deviatoric, Skew, Sym
-from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin
+from ufl.mathfunctions import MathFunction, Sqrt, Exp, Ln, Cos, Sin, Tan, Acos, Asin, Atan
 from ufl.restriction import Restricted, PositiveRestricted, NegativeRestricted
 from ufl.lifting import LiftingResult, LiftingOperatorResult, LiftingFunctionResult, TerminalOperator, LiftingOperator, LiftingFunction
 from ufl.differentiation import Derivative, CompoundDerivative, FunctionDerivative, SpatialDerivative, VariableDerivative, Grad, Div, Curl
@@ -142,7 +142,7 @@
 
     # If parent operator binds stronger than child, must parenthesize child
 
-    precedence_list.append((Abs, MathFunction,)) # Abs, Sqrt, Exp, Ln, Cos, Sin
+    precedence_list.append((Abs, MathFunction,)) # Abs, Sqrt, Exp, Ln, Cos, Sin, Tan, Acos, Asin, Atan
     precedence_list.append((Variable,))
 
     precedence_list.append((Terminal,)) # terminal_classes

=== modified file 'ufl/mathfunctions.py'
--- ufl/mathfunctions.py	2009-04-21 07:40:04 +0000
+++ ufl/mathfunctions.py	2010-03-17 15:16:37 +0000
@@ -94,3 +94,38 @@
     def __init__(self, argument):
         MathFunction.__init__(self, "sin", argument)
 
+class Tan(MathFunction):
+    def __new__(cls, argument):
+        if isinstance(argument, (ScalarValue, Zero)):
+            return FloatValue(math.tan(float(argument)))
+        return MathFunction.__new__(cls)
+    
+    def __init__(self, argument):
+        MathFunction.__init__(self, "tan", argument)
+
+class Acos(MathFunction):
+    def __new__(cls, argument):
+        if isinstance(argument, (ScalarValue, Zero)):
+            return FloatValue(math.acos(float(argument)))
+        return MathFunction.__new__(cls)
+    
+    def __init__(self, argument):
+        MathFunction.__init__(self, "acos", argument)
+
+class Asin(MathFunction):
+    def __new__(cls, argument):
+        if isinstance(argument, (ScalarValue, Zero)):
+            return FloatValue(math.asin(float(argument)))
+        return MathFunction.__new__(cls)
+    
+    def __init__(self, argument):
+        MathFunction.__init__(self, "asin", argument)
+
+class Atan(MathFunction):
+    def __new__(cls, argument):
+        if isinstance(argument, (ScalarValue, Zero)):
+            return FloatValue(math.atan(float(argument)))
+        return MathFunction.__new__(cls)
+    
+    def __init__(self, argument):
+        MathFunction.__init__(self, "atan", argument)

=== modified file 'ufl/operators.py'
--- ufl/operators.py	2009-12-01 17:09:26 +0000
+++ ufl/operators.py	2010-03-17 15:16:37 +0000
@@ -16,7 +16,7 @@
 from ufl.variable import Variable
 from ufl.tensors import as_tensor
 from ufl.conditional import EQ, NE, LE, GE, LT, GT, Conditional
-from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin
+from ufl.mathfunctions import Sqrt, Exp, Ln, Cos, Sin, Tan, Acos, Asin, Atan
 from ufl.indexing import indices
 from ufl.geometry import SpatialCoordinate
 
@@ -283,3 +283,18 @@
     "The sinus of f."
     return _mathfunction(f, Sin, math.sin)
 
+def tan(f):
+    "The tangent of f."
+    return _mathfunction(f, Tan, math.tan)
+
+def acos(f):
+    "The inverse cosinus of f."
+    return _mathfunction(f, Acos, math.acos)
+
+def asin(f):
+    "The inverse sinus of f."
+    return _mathfunction(f, Asin, math.asin)
+
+def atan(f):
+    "The inverse tangent of f."
+    return _mathfunction(f, Atan, math.atan)

# Begin bundle
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
5pFsHfEfTN4O6qP/4u5IpwoSCTeIdyA=
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: hnarayanan@xxxxxxxxx-20100317152101-59glomlsx2b5thmt
# target_branch: bzr+ssh://bazaar.launchpad.net/~ffc-core/ffc/main/
# testament_sha1: 4e20dcd6dea2c8ed304c1261b679f51ff58cee1a
# timestamp: 2010-03-17 16:21:18 +0100
# base_revision_id: k.b.oelgaard@xxxxxxxxx-20100311143219-\
#   viogrlmwwjlxdifp
# 
# Begin patch
=== modified file 'ffc/cpp.py'
--- ffc/cpp.py	2010-03-11 13:59:32 +0000
+++ ffc/cpp.py	2010-03-17 15:21:01 +0000
@@ -69,6 +69,10 @@
     "ln":             lambda v: "std::log(%s)" % str(v),
     "cos":            lambda v: "std::cos(%s)" % str(v),
     "sin":            lambda v: "std::sin(%s)" % str(v),
+    "tan":            lambda v: "std::tan(%s)" % str(v),
+    "acos":           lambda v: "std::acos(%s)" % str(v),
+    "asin":           lambda v: "std::asin(%s)" % str(v),
+    "atan":           lambda v: "std::atan(%s)" % str(v),
     "absolute value": lambda v: "std::abs(%s)" % str(v),
     "sqrt":           lambda v: "std::sqrt(%s)" % str(v),
     "addition":       lambda v: _add(v),

=== modified file 'ffc/quadrature/quadraturetransformerbase.py'
--- ffc/quadrature/quadraturetransformerbase.py	2010-03-11 13:59:32 +0000
+++ ffc/quadrature/quadraturetransformerbase.py	2010-03-17 15:21:01 +0000
@@ -541,6 +541,22 @@
         #print("\n\nVisiting Sin: " + repr(o) + "with operands: " + "\n".join(map(repr,operands)))
         return self._math_function(operands, format["sin"])
 
+    def tan(self, o, *operands):
+        #print("\n\nVisiting Tan: " + repr(o) + "with operands: " + "\n".join(map(repr,operands)))
+        return self._math_function(operands, format["tan"])
+
+    def acos(self, o, *operands):
+        #print("\n\nVisiting Acos: " + repr(o) + "with operands: " + "\n".join(map(repr,operands)))
+        return self._math_function(operands, format["acos"])
+
+    def asin(self, o, *operands):
+        #print("\n\nVisiting Asin: " + repr(o) + "with operands: " + "\n".join(map(repr,operands)))
+        return self._math_function(operands, format["asin"])
+
+    def atan(self, o, *operands):
+        #print("\n\nVisiting Atan: " + repr(o) + "with operands: " + "\n".join(map(repr,operands)))
+        return self._math_function(operands, format["atan"])
+
     # -------------------------------------------------------------------------
     # PositiveRestricted and NegativeRestricted (restriction.py).
     # -------------------------------------------------------------------------

# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWZhpRvwAAsrfgETQWn//93JB
BQ6////wUAWedUV2m2bOygGQUhKUE0DQ09JiGmgNGQAAAABKTSZqRPyajTTUMgNAAAANAASJExBU
9M0UwnlBk0000AD1NDQHqDmmJgI0wIwjAAAAEwjAKlIEMgJgEm1U/J5Q2oj1GmppiDzSnqLSLzdr
5zJp/qzd9XBbOOKcuZlMh31c7iYMaq/Fktsz6CSVBgTiUKG0x5yozFE/RoUjbf23rOdh8TiblGcz
Vpgpb5re963mXbwzCvbT86y4WldbaUmU9pjy2H8m85Dt8dfhqV17divLnPyR+oV2IdYSJvp3tt1Q
UCUoDqBhULBUs7KG4ofUsqlZ/RrM/wLisofcoZArLCs4GM8XnPa9/lOL7ROUjHy7tnl7GP3S7HoO
sfZJ7T6x36aODPozWq8LZFNtVUTQnaobZXEq6CCa1IT61dgdPKUFVXHMDUQWJFb6Sn78l48YWRVY
xSLmyqJgPli4N7NofLujlqaaSil2LQtjCeN8bbaOH4U4wkeSPTNZIlgAaJJMhExAQd3bW3FLLQUL
yM9kGwprTqSSDlJLj8AEFywx4qE5T5uOGuUxYakFn+gUGG0IqMRHGUAXORFSqi3vLmz12sYbIG6q
TLD8Ms8s0UFHDrlSdxY9I5i+tsGIq435FI1TdbatXvuqtrxs1g54OnOKq82dnXPAbDI1TLbSKKFA
GXhZg1WozKR3+BP/Gu806sAmUcWqSpMlMQoTKtUqaUgkPdW9dCRaCzXUexvJew4xpWUi04kshZO7
JWkxGckR81ckCFJWFZAgX322MmhRjrGjq8zvPCPfOx35dJgbNXObatO3TS+8VpLCAdnNXIpffHxN
z28hgPQaRqM/qdk0XIL8mYWbGx/iJzLgxDAIBgdgUnNwL0ByXTCiC4lXESl0dGY40GHjK4KVCKlB
VRCARMmAIB+lIetUOiMRGI93rbCqNUnr21tevIlauutL0nbnF/Xw4OHsFrHW688DIrY82J7ZMPY8
J2YUfBJBdsZkGqWFoaL9cbhvPLQCI6wHqGVaag6Vksjb8bLmffdYyGIuzK7uPQyRyi8t07d37mFX
lP1lZmDD5/BmeLZW0NGHn5KsFSzsyN/PbRVgvj48l+zvVOOrlqpZcas+brTD/NS8bo3T85Ql+2/O
G3HVwrYiWxVebR7HVhye/lHl0zT7Ojs40kt1y6VfgstPKfSao6JnH3Sd8y74/tbUVVpmrHm7pRX3
d0WuHJq+myKW8E1JN6Vt2idxR+8ZrTKfxo02+MuMcUxVx/0/gtPGjl5vdLZ6Hfmim+PFJyL4vqPt
PW1K4nHX89c9B3C/pOSSxJxLk79JVgUMeegxvQVpcvYBkqzsHAJSBsaLA4IIggaCQEWJCKoHoRRE
AHtKSRzxNSDMToUnjpLzLwi2azgk0ilcPypd9z8F5eWYeUbqkeiuYRq1Fkux76KFUxy6C1im1rH4
Mew9Hp8vlR82XTmNRQ/9mfOlJgxRhYGKfmZEV+CqLtVUm03lc9TX1tmTpqMnWYIvM911mKg/BoJ8
Z1VFmPtiy/r3Gg1VzpVNmliP5thWwHexNoXoxQ+oDoMfLC0IZuU0SPoGcsG3e8NNxdkz2mXFpKGU
U158q06RljRKGmVXULcZYfR4mv3JkaRvNRhN8vjO3HpNsvG2XR3bgYzMRqOcjYqf8XckU4UJCYaU
b8A=

Follow ups

References