gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master db24229: Library (arithmetic.h): trigonometric


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master db24229: Library (arithmetic.h): trigonometric and hyperbolic functions added
Date: Sat, 20 Feb 2021 13:55:02 -0500 (EST)

branch: master
commit db242297d17037754ee853dcd1c19cb5dfb4c922
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (arithmetic.h): trigonometric and hyperbolic functions added
    
    Until now, the trigonometric and hyperbolic functions were only available
    in Table's column arithmetic. However, they can also be useful in general
    on any type of data (for example some conversions like those for image
    vizualization that use 'asinh' that is discussed in task #15878:
    http://doi.org/10.1086/382245 ).
    
    With this commit, these functions have been removed from inside the Table
    program and taken into Gnuastro's Arithmetic library. As a result, they are
    now also available within the Arithmetic program to operate on images or
    cubes also. Of course, exactly the same internal function will also be used
    by Table's Column arithmetic, so Table users shouldn't feel any difference.
---
 NEWS                      |  18 +++
 bin/table/arithmetic.c    | 197 +--------------------------------
 bin/table/arithmetic.h    |  13 ---
 doc/gnuastro.texi         | 122 +++++++++++---------
 lib/arithmetic.c          | 277 +++++++++++++++++++++++++++++-----------------
 lib/gnuastro/arithmetic.h |  16 ++-
 6 files changed, 282 insertions(+), 361 deletions(-)

diff --git a/NEWS b/NEWS
index 266231f..8bd4219 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,24 @@ See the end of the file for license conditions.
 
 ** New features
 
+  Arithmetic:
+   - New operators (the trigonometric/hyperbolic functions were previously
+     only avaialble in Table's column arithmetic, but they have been moved
+     into the Gnuastro library and are thus now available on images within
+     Arithmetic also):
+     - sin: Trigonometric sine (input in degrees).
+     - cos: Trigonometric cosine (input in degrees).
+     - tan: Trigonometric tangent (input in degrees).
+     - asin: Inverse of trigonometric sine (output in degrees).
+     - acos: Inverse of trigonometric cosine (output in degrees).
+     - atab: Inverse of trigonometric tangent (output in degrees).
+     - sinh: Hyperbolic sine.
+     - cosh: Hyperbolic cosine.
+     - tanh: Hyperbolic tangent.
+     - asinh: Inverse of hyperbolic sine.
+     - acosh: Inverse of hyperbolic cosine.
+     - atabh: Inverse of hyperbolic tangent.
+
   Table:
    - When given a value of '_all', the '--noblank' option (that will remove
      all rows with a blank value in the given columns) will check all
diff --git a/bin/table/arithmetic.c b/bin/table/arithmetic.c
index c9996d1..dfa576c 100644
--- a/bin/table/arithmetic.c
+++ b/bin/table/arithmetic.c
@@ -129,19 +129,6 @@ arithmetic_operator_name(int operator)
     switch(operator)
       {
       case ARITHMETIC_TABLE_OP_SET: out="set"; break;
-      case ARITHMETIC_TABLE_OP_SIN: out="sin"; break;
-      case ARITHMETIC_TABLE_OP_COS: out="cos"; break;
-      case ARITHMETIC_TABLE_OP_TAN: out="tan"; break;
-      case ARITHMETIC_TABLE_OP_ASIN: out="asin"; break;
-      case ARITHMETIC_TABLE_OP_ACOS: out="acos"; break;
-      case ARITHMETIC_TABLE_OP_ATAN: out="atan"; break;
-      case ARITHMETIC_TABLE_OP_SINH: out="sinh"; break;
-      case ARITHMETIC_TABLE_OP_COSH: out="cosh"; break;
-      case ARITHMETIC_TABLE_OP_TANH: out="tanh"; break;
-      case ARITHMETIC_TABLE_OP_ASINH: out="asinh"; break;
-      case ARITHMETIC_TABLE_OP_ACOSH: out="acosh"; break;
-      case ARITHMETIC_TABLE_OP_ATANH: out="atanh"; break;
-      case ARITHMETIC_TABLE_OP_ATAN2: out="atan2"; break;
       case ARITHMETIC_TABLE_OP_WCSTOIMG: out="wcstoimg"; break;
       case ARITHMETIC_TABLE_OP_IMGTOWCS: out="imgtowcs"; break;
       case ARITHMETIC_TABLE_OP_DATETOSEC: out="date-to-sec"; break;
@@ -194,33 +181,7 @@ arithmetic_set_operator(struct tableparams *p, char 
*string,
   if( op==GAL_ARITHMETIC_OP_INVALID )
     {
       /* Simple operators. */
-      if(      !strcmp(string, "sin"))
-        { op=ARITHMETIC_TABLE_OP_SIN; *num_operands=0; }
-      else if( !strcmp(string, "cos"))
-        { op=ARITHMETIC_TABLE_OP_COS; *num_operands=0; }
-      else if( !strcmp(string, "tan"))
-        { op=ARITHMETIC_TABLE_OP_TAN; *num_operands=0; }
-      else if( !strcmp(string, "asin"))
-        { op=ARITHMETIC_TABLE_OP_ASIN; *num_operands=0; }
-      else if( !strcmp(string, "acos"))
-        { op=ARITHMETIC_TABLE_OP_ACOS; *num_operands=0; }
-      else if( !strcmp(string, "atan"))
-        { op=ARITHMETIC_TABLE_OP_ATAN; *num_operands=0; }
-      else if( !strcmp(string, "atan2"))
-        { op=ARITHMETIC_TABLE_OP_ATAN2; *num_operands=0; }
-      else if( !strcmp(string, "sinh"))
-        { op=ARITHMETIC_TABLE_OP_SINH; *num_operands=0; }
-      else if( !strcmp(string, "cosh"))
-        { op=ARITHMETIC_TABLE_OP_COSH; *num_operands=0; }
-      else if( !strcmp(string, "tanh"))
-        { op=ARITHMETIC_TABLE_OP_TANH; *num_operands=0; }
-      else if( !strcmp(string, "asinh"))
-        { op=ARITHMETIC_TABLE_OP_ASINH; *num_operands=0; }
-      else if( !strcmp(string, "acosh"))
-        { op=ARITHMETIC_TABLE_OP_ACOSH; *num_operands=0; }
-      else if( !strcmp(string, "atanh"))
-        { op=ARITHMETIC_TABLE_OP_ATANH; *num_operands=0; }
-      else if( !strcmp(string, "wcstoimg"))
+      if(      !strcmp(string, "wcstoimg"))
         { op=ARITHMETIC_TABLE_OP_WCSTOIMG; *num_operands=0; }
       else if( !strcmp(string, "imgtowcs"))
         { op=ARITHMETIC_TABLE_OP_IMGTOWCS; *num_operands=0; }
@@ -679,146 +640,6 @@ arithmetic_distance(struct tableparams *p, gal_data_t 
**stack, int operator)
 
 
 
-static void
-arithmetic_trig_hyper(struct tableparams *p, gal_data_t **stack,
-                      int operator)
-{
-  size_t i;
-  double *x=NULL, *y=NULL;
-  gal_data_t *in=NULL, *in2=NULL;
-  double pi=3.14159265358979323846264338327;
-
-  /* Read the input columns as a 'double'. */
-  in=arithmetic_stack_pop(stack, operator, NULL);
-  in=gal_data_copy_to_new_type_free(in, GAL_TYPE_FLOAT64);
-  if(in->comment) { free(in->comment); in->comment=NULL; }
-  if(in->name)    { free(in->name);    in->name=NULL;    }
-  if(in->unit)    { free(in->unit);    in->unit=NULL;    }
-  x=in->array;
-
-  /* Pop the second operand if necessary. */
-  if(operator==ARITHMETIC_TABLE_OP_ATAN2)
-    {
-      in2=arithmetic_stack_pop(stack, operator, NULL);
-      in2=gal_data_copy_to_new_type_free(in2, GAL_TYPE_FLOAT64);
-      y=in2->array;
-    }
-
-  /* Parse the array and do the calculation in place. */
-  switch(operator)
-    {
-      /* Single-operand operators. */
-    case ARITHMETIC_TABLE_OP_SIN:
-      for(i=0;i<in->size;++i) x[i]=sin( pi*x[i]/180.0f );
-      gal_checkset_allocate_copy("sin", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Sine of an angle.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_COS:
-      for(i=0;i<in->size;++i) x[i]=cos( pi*x[i]/180.0f );
-      gal_checkset_allocate_copy("cos", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Cosine of an angle.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_TAN:
-      for(i=0;i<in->size;++i) x[i]=tan( pi*x[i]/180.0f );
-      gal_checkset_allocate_copy("tan", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Tangent of an angle.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ASIN:
-      for(i=0;i<in->size;++i) x[i]=asin(x[i])*180.0f/pi;
-      gal_checkset_allocate_copy("asin", &in->name);
-      gal_checkset_allocate_copy("deg", &in->unit);
-      gal_checkset_allocate_copy("Inverse sine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ACOS:
-      for(i=0;i<in->size;++i) x[i]=acos(x[i])*180.0f/pi;
-      gal_checkset_allocate_copy("acos", &in->name);
-      gal_checkset_allocate_copy("deg", &in->unit);
-      gal_checkset_allocate_copy("Inverse cosine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ATAN:
-      for(i=0;i<in->size;++i) x[i]=atan(x[i])*180.0f/pi;
-      gal_checkset_allocate_copy("atan", &in->name);
-      gal_checkset_allocate_copy("deg", &in->unit);
-      gal_checkset_allocate_copy("Inverse tangent of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_SINH:
-      for(i=0;i<in->size;++i) x[i]=sinh(x[i]);
-      gal_checkset_allocate_copy("sinh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Hyperbolic sine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_COSH:
-      for(i=0;i<in->size;++i) x[i]=cosh(x[i]);
-      gal_checkset_allocate_copy("cosh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Hyperbolic cosine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_TANH:
-      for(i=0;i<in->size;++i) x[i]=tanh(x[i]);
-      gal_checkset_allocate_copy("tanh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Hyperbolic tangent of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ASINH:
-      for(i=0;i<in->size;++i) x[i]=asinh(x[i]);
-      gal_checkset_allocate_copy("asinh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Inverse hyperbolic sine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ACOSH:
-      for(i=0;i<in->size;++i) x[i]=acosh(x[i]);
-      gal_checkset_allocate_copy("acosh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Inverse hyperbolic cossine of a value.",
-                                 &in->comment);
-      break;
-    case ARITHMETIC_TABLE_OP_ATANH:
-      for(i=0;i<in->size;++i) x[i]=atanh(x[i]);
-      gal_checkset_allocate_copy("atanh", &in->name);
-      gal_checkset_allocate_copy("ratio", &in->unit);
-      gal_checkset_allocate_copy("Inverse hyperbolic tangent of a value.",
-                                 &in->comment);
-      break;
-
-    /* Two operand operators. */
-    case ARITHMETIC_TABLE_OP_ATAN2:
-      for(i=0;i<in->size;++i) x[i]=atan2(y[i], x[i])*180.0f/pi;
-      gal_checkset_allocate_copy("atan2", &in->name);
-      gal_checkset_allocate_copy("deg", &in->unit);
-      gal_checkset_allocate_copy("Inverse tangent of point (preserving "
-                                 "the quadrant)", &in->comment);
-      break;
-
-    /* Not recognized (a bug). */
-    default:
-      error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s to fix "
-            "the problem. The code %d is not recognized as an operator "
-            "related to this function", __func__, PACKAGE_BUGREPORT,
-            operator);
-    }
-
-  /* Clean up and put the resulting calculation back on the stack. */
-  if(in2) gal_data_free(in2);
-  gal_list_data_add(stack, in);
-}
-
-
-
-
-
 /* Convert the ISO date format to seconds since Unix time. */
 static void
 arithmetic_datetosec(struct tableparams *p, gal_data_t **stack,
@@ -1008,22 +829,6 @@ arithmetic_operator_run(struct tableparams *p,
     {
       switch(token->operator)
         {
-        case ARITHMETIC_TABLE_OP_SIN:
-        case ARITHMETIC_TABLE_OP_COS:
-        case ARITHMETIC_TABLE_OP_TAN:
-        case ARITHMETIC_TABLE_OP_ASIN:
-        case ARITHMETIC_TABLE_OP_ACOS:
-        case ARITHMETIC_TABLE_OP_ATAN:
-        case ARITHMETIC_TABLE_OP_SINH:
-        case ARITHMETIC_TABLE_OP_COSH:
-        case ARITHMETIC_TABLE_OP_TANH:
-        case ARITHMETIC_TABLE_OP_ASINH:
-        case ARITHMETIC_TABLE_OP_ACOSH:
-        case ARITHMETIC_TABLE_OP_ATANH:
-        case ARITHMETIC_TABLE_OP_ATAN2:
-          arithmetic_trig_hyper(p, stack, token->operator);
-          break;
-
         case ARITHMETIC_TABLE_OP_WCSTOIMG:
         case ARITHMETIC_TABLE_OP_IMGTOWCS:
           arithmetic_wcs(p, stack, token->operator);
diff --git a/bin/table/arithmetic.h b/bin/table/arithmetic.h
index 06d31ce..dd682fb 100644
--- a/bin/table/arithmetic.h
+++ b/bin/table/arithmetic.h
@@ -36,19 +36,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 enum arithmetic_operators
 {
   ARITHMETIC_TABLE_OP_SET = GAL_ARITHMETIC_OP_LAST_CODE,
-  ARITHMETIC_TABLE_OP_SIN,
-  ARITHMETIC_TABLE_OP_COS,
-  ARITHMETIC_TABLE_OP_TAN,
-  ARITHMETIC_TABLE_OP_ASIN,
-  ARITHMETIC_TABLE_OP_ACOS,
-  ARITHMETIC_TABLE_OP_ATAN,
-  ARITHMETIC_TABLE_OP_ATAN2,
-  ARITHMETIC_TABLE_OP_SINH,
-  ARITHMETIC_TABLE_OP_COSH,
-  ARITHMETIC_TABLE_OP_TANH,
-  ARITHMETIC_TABLE_OP_ASINH,
-  ARITHMETIC_TABLE_OP_ACOSH,
-  ARITHMETIC_TABLE_OP_ATANH,
   ARITHMETIC_TABLE_OP_WCSTOIMG,
   ARITHMETIC_TABLE_OP_IMGTOWCS,
   ARITHMETIC_TABLE_OP_DATETOSEC,
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 82f5866..b3d2c71 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -10137,56 +10137,6 @@ Besides the operators in @ref{Arithmetic operators}, 
several operators are only
 @cindex WCS: World Coordinate System
 @cindex World Coordinate System (WCS)
 @table @code
-@item  sin
-@itemx cos
-@itemx tan
-@cindex Trigonometry
-Basic trigonometric functions.
-They take one operand, in units of degrees.
-
-@item  asin
-@itemx acos
-@itemx atan
-Inverse trigonometric functions.
-They take one operand and the returned values are in units of degrees.
-
-@item atan2
-Inverse tangent (output in units of degrees) which uses the signs of the input 
coordinates to distinguish between the quadrants.
-This operator therefore needs two operands: the first popped operand is 
assumed to be the X axis position of the point, and the second popped operand 
is its Y axis coordinate.
-
-For example see the commands below for four points in the four quadrants (if 
you want to try them, you don't need to type/copy the parts after @key{#}).
-The first point (2,2) is in the first quadrant, therefore the returned angle 
is 45 degrees.
-But the second, third and fourth points are in the quadrants of the same 
order, and the returned angles reflect the quadrant.
-
-@example
-$ echo " 2  2" | asttable -c'arith $2 $1 atan2'   # -->   45
-$ echo " 2 -2" | asttable -c'arith $2 $1 atan2'   # -->  -45
-$ echo "-2 -2" | asttable -c'arith $2 $1 atan2'   # --> -135
-$ echo "-2  2" | asttable -c'arith $2 $1 atan2'   # -->  135
-@end example
-
-However, if you simply use the classic arc-tangent operator (@code{atan}) for 
the same points, the result will only be in two quadrants as you see below:
-
-@example
-echo " 2  2" | "$utility" -c'arith $2 $1 / atan'  # -->   45
-echo " 2 -2" | "$utility" -c'arith $2 $1 / atan'  # -->  -45
-echo "-2 -2" | "$utility" -c'arith $2 $1 / atan'  # -->   45
-echo "-2  2" | "$utility" -c'arith $2 $1 / atan'  # -->  -45
-@end example
-
-@item  sinh
-@itemx cosh
-@itemx tanh
-@cindex Hyperbolic functions
-Hyperbolic sine, cosine, and tangent.
-These operators take a single operand.
-
-@item  asinh
-@itemx acosh
-@itemx atanh
-Inverse Hyperbolic sine, cosine, and tangent.
-These operators take a single operand.
-
 @item wcstoimg
 Convert the given WCS positions to image/dataset coordinates based on the 
number of dimensions in the WCS structure of @option{--wcshdu} extension/HDU in 
@option{--wcsfile}.
 It will output the same number of columns.
@@ -11910,6 +11860,58 @@ For example the command below will take the base-10 
logarithm of every pixel in
 $ astarithmetic image.fits log10
 @end example
 
+@item  sin
+@itemx cos
+@itemx tan
+@cindex Trigonometry
+Basic trigonometric functions.
+They take one operand, in units of degrees.
+
+@item  asin
+@itemx acos
+@itemx atan
+Inverse trigonometric functions.
+They take one operand and the returned values are in units of degrees.
+
+@item atan2
+Inverse tangent (output in units of degrees) that uses the signs of the input 
coordinates to distinguish between the quadrants.
+This operator therefore needs two operands: the first popped operand is 
assumed to be the X axis position of the point, and the second popped operand 
is its Y axis coordinate.
+
+For example see the commands below.
+To be more clear, we are using Table's @ref{Column arithmetic} which uses 
exactly the same internal library function as the Arithmetic program for images.
+We are showing the results for four points in the four quadrants of the 2D 
space (if you want to try running them, you don't need to type/copy the parts 
after @key{#}).
+The first point (2,2) is in the first quadrant, therefore the returned angle 
is 45 degrees.
+But the second, third and fourth points are in the quadrants of the same 
order, and the returned angles reflect the quadrant.
+
+@example
+$ echo " 2  2" | asttable -c'arith $2 $1 atan2'   # -->   45
+$ echo " 2 -2" | asttable -c'arith $2 $1 atan2'   # -->  -45
+$ echo "-2 -2" | asttable -c'arith $2 $1 atan2'   # --> -135
+$ echo "-2  2" | asttable -c'arith $2 $1 atan2'   # -->  135
+@end example
+
+However, if you simply use the classic arc-tangent operator (@code{atan}) for 
the same points, the result will only be in two quadrants as you see below:
+
+@example
+$ echo " 2  2" | asttable -c'arith $2 $1 / atan'  # -->   45
+$ echo " 2 -2" | asttable -c'arith $2 $1 / atan'  # -->  -45
+$ echo "-2 -2" | asttable -c'arith $2 $1 / atan'  # -->   45
+$ echo "-2  2" | asttable -c'arith $2 $1 / atan'  # -->  -45
+@end example
+
+@item  sinh
+@itemx cosh
+@itemx tanh
+@cindex Hyperbolic functions
+Hyperbolic sine, cosine, and tangent.
+These operators take a single operand.
+
+@item  asinh
+@itemx acosh
+@itemx atanh
+Inverse Hyperbolic sine, cosine, and tangent.
+These operators take a single operand.
+
 @item minvalue
 Minimum value in the first popped operand, so ``@command{a.fits minvalue}'' 
will push the minimum pixel value in this image onto the stack.
 When this operator acts on a single image, the output (operand that is put 
back on the stack) will no longer be an image, but a number.
@@ -25179,6 +25181,26 @@ different type, you can convert the input to a 
floating point type with
 @code{gal_data_copy_to_new_type_free}(see @ref{Copying datasets}).
 @end deffn
 
+@deffn  Macro GAL_ARITHMETIC_OP_SIN
+@deffnx Macro GAL_ARITHMETIC_OP_COS
+@deffnx Macro GAL_ARITHMETIC_OP_TAN
+@deffnx Macro GAL_ARITHMETIC_OP_ASIN
+@deffnx Macro GAL_ARITHMETIC_OP_ACOS
+@deffnx Macro GAL_ARITHMETIC_OP_ATAN
+@deffnx Macro GAL_ARITHMETIC_OP_ATAN2
+Trigonometric functions (and their inverse).
+All the angles, either inputs or outputs, are in units of degrees.
+@end deffn
+
+@deffn  Macro GAL_ARITHMETIC_OP_SINH
+@deffnx Macro GAL_ARITHMETIC_OP_COSH
+@deffnx Macro GAL_ARITHMETIC_OP_TANH
+@deffnx Macro GAL_ARITHMETIC_OP_ASINH
+@deffnx Macro GAL_ARITHMETIC_OP_ACOSH
+@deffnx Macro GAL_ARITHMETIC_OP_ATANH
+Hyperbolic functions (and their inverse).
+@end deffn
+
 @deffn  Macro GAL_ARITHMETIC_OP_RA_TO_DEGREE
 @deffnx Macro GAL_ARITHMETIC_OP_DEC_TO_DEGREE
 @deffnx Macro GAL_ARITHMETIC_OP_DEGREE_TO_RA
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 6372151..e7f68d9 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -362,120 +362,120 @@ static char *
 arithmetic_units_degree_to_dec(double decimal)
 { return gal_units_degree_to_dec(decimal, 0); }
 
-#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT(OT, IT, OP){                    \
+#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT(OT, IT, OP, BEFORE, AFTER){     \
     OT *oa=o->array;                                                    \
     IT *ia=in->array, *iaf=ia + in->size;                               \
-    do *oa++ = OP(*ia++); while(ia<iaf);                                \
+    do *oa++ = OP( *ia++ BEFORE ) AFTER; while(ia<iaf);                 \
   }
 
-#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(IT, OP)                   \
+#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(IT, OP, BEFORE, AFTER)    \
   switch(o->type)                                                       \
     {                                                                   \
     case GAL_TYPE_UINT8:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t,  IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t,  IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_INT8:                                                 \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t,   IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t,   IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_UINT16:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_INT16:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t,  IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t,  IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_UINT32:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_INT32:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t,  IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t,  IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_UINT64:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_INT64:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t,  IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t,  IT, OP, BEFORE, AFTER)  \
         break;                                                          \
     case GAL_TYPE_FLOAT32:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float,    IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float,    IT, OP, BEFORE, AFTER)  \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double,   IT, OP)                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double,   IT, OP, BEFORE, AFTER)  \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type code %d not recognized",         \
             "UNIARY_FUNCTION_ON_ELEMENT", in->type);                    \
     }
 
-#define UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(OP)                    \
+#define UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(OP)     \
   switch(in->type)                                                      \
     {                                                                   \
     case GAL_TYPE_UINT8:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint8_t,  OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint8_t,  OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_INT8:                                                 \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int8_t,   OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int8_t,   OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_UINT16:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint16_t, OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint16_t, OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_INT16:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int16_t,  OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int16_t,  OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_UINT32:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint32_t, OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint32_t, OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_INT32:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int32_t,  OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int32_t,  OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_UINT64:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint64_t, OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, uint64_t, OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_INT64:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int64_t,  OP)             \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, int64_t,  OP, +0, +0)     \
         break;                                                          \
     case GAL_TYPE_FLOAT32:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, float,    OP)             \
-      break;                                                            \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, float,    OP, +0, +0)     \
+        break;                                                          \
     case GAL_TYPE_FLOAT64:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, double,   OP)             \
-      break;                                                            \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char *, double,   OP, +0, +0)     \
+        break;                                                          \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type code %d not recognized",         \
             "UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING", in->type);      \
     }
 
-#define UNIARY_FUNCTION_ON_ELEMENT(OP)                                  \
+#define UNIARY_FUNCTION_ON_ELEMENT(OP, BEFORE, AFTER)                   \
   switch(in->type)                                                      \
     {                                                                   \
     case GAL_TYPE_UINT8:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint8_t,  OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint8_t,  OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_INT8:                                                 \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int8_t,   OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int8_t,   OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_UINT16:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint16_t, OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint16_t, OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_INT16:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int16_t,  OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int16_t,  OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_UINT32:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint32_t, OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint32_t, OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_INT32:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int32_t,  OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int32_t,  OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_UINT64:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint64_t, OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint64_t, OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_INT64:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int64_t,  OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int64_t,  OP, BEFORE, AFTER) \
         break;                                                          \
     case GAL_TYPE_FLOAT32:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(float,    OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(float,    OP, BEFORE, AFTER) \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(double,   OP)               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(double,   OP, BEFORE, AFTER) \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type code %d not recognized",         \
@@ -490,24 +490,26 @@ arithmetic_units_degree_to_dec(double decimal)
 }
 
 static gal_data_t *
-arithmetic_unary_function(int operator, int flags, gal_data_t *in)
+arithmetic_function_unary(int operator, int flags, gal_data_t *in)
 {
   uint8_t otype;
   int inplace=0;
   gal_data_t *o;
+  double pi=3.14159265358979323846264338327;
 
-  /* See if the operation should be done in place. Note that so far, the
-     output of these operators is defined in the real space (floating
-     point). So even if the user requested inplace opereation, if its not a
-     floating point type, its not useful.*/
+  /* See if the operation should be done in place. The output of these
+     operators is defined in the floating point space. So even if the input
+     is integer type and user requested inplace opereation, if its not a
+     floating point type, it will not be in-place. */
   if( (flags & GAL_ARITHMETIC_INPLACE)
-      && (in->type==GAL_TYPE_FLOAT32 || in->type==GAL_TYPE_FLOAT64)
-      && (operator != GAL_ARITHMETIC_OP_RA_TO_DEGREE
-      &&  operator != GAL_ARITHMETIC_OP_DEC_TO_DEGREE
-      &&  operator != GAL_ARITHMETIC_OP_DEGREE_TO_RA
-      &&  operator != GAL_ARITHMETIC_OP_DEGREE_TO_DEC ) )
+      && ( in->type==GAL_TYPE_FLOAT32 || in->type==GAL_TYPE_FLOAT64 )
+      && ( operator != GAL_ARITHMETIC_OP_RA_TO_DEGREE
+      &&   operator != GAL_ARITHMETIC_OP_DEC_TO_DEGREE
+      &&   operator != GAL_ARITHMETIC_OP_DEGREE_TO_RA
+      &&   operator != GAL_ARITHMETIC_OP_DEGREE_TO_DEC ) )
     inplace=1;
 
+  /* Set the output pointer. */
   if(inplace)
     {
       o = in;
@@ -515,19 +517,19 @@ arithmetic_unary_function(int operator, int flags, 
gal_data_t *in)
     }
   else
     {
-      otype = ( in->type==GAL_TYPE_FLOAT64
-                ? GAL_TYPE_FLOAT64
-                : GAL_TYPE_FLOAT32 );
-
       /* Check for operators which have fixed output types */
-      if ( operator == GAL_ARITHMETIC_OP_RA_TO_DEGREE ||
-           operator == GAL_ARITHMETIC_OP_DEC_TO_DEGREE )
+      if(         operator == GAL_ARITHMETIC_OP_RA_TO_DEGREE
+               || operator == GAL_ARITHMETIC_OP_DEC_TO_DEGREE )
         otype = GAL_TYPE_FLOAT64;
-
-      if (operator == GAL_ARITHMETIC_OP_DEGREE_TO_RA ||
-          operator == GAL_ARITHMETIC_OP_DEGREE_TO_DEC)
+      else if(    operator == GAL_ARITHMETIC_OP_DEGREE_TO_RA
+               || operator == GAL_ARITHMETIC_OP_DEGREE_TO_DEC )
         otype = GAL_TYPE_STRING;
+      else
+        otype = ( in->type==GAL_TYPE_FLOAT64
+                  ? GAL_TYPE_FLOAT64
+                  : GAL_TYPE_FLOAT32 );
 
+      /* Set the final output type. */
       o = gal_data_alloc(NULL, otype, in->ndim, in->dsize, in->wcs,
                          0, in->minmapsize, in->quietmmap,
                          NULL, NULL, NULL);
@@ -537,39 +539,52 @@ arithmetic_unary_function(int operator, int flags, 
gal_data_t *in)
   switch(operator)
     {
     case GAL_ARITHMETIC_OP_SQRT:
-      UNIARY_FUNCTION_ON_ELEMENT( sqrt );
-      break;
-
+      UNIARY_FUNCTION_ON_ELEMENT( sqrt,  +0, +0);         break;
     case GAL_ARITHMETIC_OP_LOG:
-      UNIARY_FUNCTION_ON_ELEMENT( log );
-      break;
-
+      UNIARY_FUNCTION_ON_ELEMENT( log,   +0, +0);         break;
     case GAL_ARITHMETIC_OP_LOG10:
-      UNIARY_FUNCTION_ON_ELEMENT( log10 );
-      break;
-
+      UNIARY_FUNCTION_ON_ELEMENT( log10, +0, +0);         break;
+    case GAL_ARITHMETIC_OP_SIN:
+      UNIARY_FUNCTION_ON_ELEMENT( sin,   *pi/180.0f, +0); break;
+    case GAL_ARITHMETIC_OP_COS:
+      UNIARY_FUNCTION_ON_ELEMENT( cos,   *pi/180.0f, +0); break;
+    case GAL_ARITHMETIC_OP_TAN:
+      UNIARY_FUNCTION_ON_ELEMENT( tan,   *pi/180.0f, +0); break;
+    case GAL_ARITHMETIC_OP_ASIN:
+      UNIARY_FUNCTION_ON_ELEMENT( asin,  +0, *180.0f/pi); break;
+    case GAL_ARITHMETIC_OP_ACOS:
+      UNIARY_FUNCTION_ON_ELEMENT( acos,  +0, *180.0f/pi); break;
+    case GAL_ARITHMETIC_OP_ATAN:
+      UNIARY_FUNCTION_ON_ELEMENT( atan,  +0, *180.0f/pi); break;
+    case GAL_ARITHMETIC_OP_SINH:
+      UNIARY_FUNCTION_ON_ELEMENT( sinh,  +0, +0);         break;
+    case GAL_ARITHMETIC_OP_COSH:
+      UNIARY_FUNCTION_ON_ELEMENT( cosh,  +0, +0);         break;
+    case GAL_ARITHMETIC_OP_TANH:
+      UNIARY_FUNCTION_ON_ELEMENT( tanh,  +0, +0);         break;
+    case GAL_ARITHMETIC_OP_ASINH:
+      UNIARY_FUNCTION_ON_ELEMENT( asinh, +0, +0);         break;
+    case GAL_ARITHMETIC_OP_ACOSH:
+      UNIARY_FUNCTION_ON_ELEMENT( acosh, +0, +0);         break;
+    case GAL_ARITHMETIC_OP_ATANH:
+      UNIARY_FUNCTION_ON_ELEMENT( atanh, +0, +0);         break;
     case GAL_ARITHMETIC_OP_RA_TO_DEGREE:
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT_STRING(double, gal_units_ra_to_degree);
       break;
-
     case GAL_ARITHMETIC_OP_DEC_TO_DEGREE:
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT_STRING(double, gal_units_dec_to_degree);
       break;
-
     case GAL_ARITHMETIC_OP_DEGREE_TO_RA:
       UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(arithmetic_units_degree_to_ra);
       break;
-
     case GAL_ARITHMETIC_OP_DEGREE_TO_DEC:
       UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(arithmetic_units_degree_to_dec);
       break;
-
     default:
       error(EXIT_FAILURE, 0, "%s: operator code %d not recognized",
             __func__, operator);
     }
 
-
   /* Clean up. Note that if the input arrays can be freed, and any of right
      or left arrays needed conversion, 'UNIFUNC_CONVERT_TO_COMPILED_TYPE'
      has already freed the input arrays, and we only have 'r' and 'l'
@@ -1639,24 +1654,24 @@ arithmetic_binary(int operator, int flags, gal_data_t 
*l, gal_data_t *r)
 
 
 
-#define BINFUNC_RUN_FUNCTION(OT, RT, LT, OP){                           \
+#define BINFUNC_RUN_FUNCTION(OT, RT, LT, OP, AFTER){                    \
     LT *la=l->array;                                                    \
     RT *ra=r->array;                                                    \
     OT *oa=o->array, *of=oa + o->size;                                  \
-    if(l->size==r->size) do *oa = OP(*la++, *ra++); while(++oa<of);     \
-    else if(l->size==1)  do *oa = OP(*la,   *ra++); while(++oa<of);     \
-    else                 do *oa = OP(*la++, *ra  ); while(++oa<of);     \
+    if(l->size==r->size) do *oa = OP(*la++, *ra++) AFTER; while(++oa<of); \
+    else if(l->size==1)  do *oa = OP(*la,   *ra++) AFTER; while(++oa<of); \
+    else                 do *oa = OP(*la++, *ra  ) AFTER; while(++oa<of); \
   }
 
 
-#define BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(RT, LT, OP)                   \
+#define BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(RT, LT, OP, AFTER)            \
   switch(o->type)                                                       \
     {                                                                   \
     case GAL_TYPE_FLOAT32:                                              \
-      BINFUNC_RUN_FUNCTION(float, RT, LT, OP);                          \
+      BINFUNC_RUN_FUNCTION(float, RT, LT, OP, AFTER);                   \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      BINFUNC_RUN_FUNCTION(double, RT, LT, OP);                         \
+      BINFUNC_RUN_FUNCTION(double, RT, LT, OP, AFTER);                  \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type %d not recognized for o->type ", \
@@ -1664,14 +1679,14 @@ arithmetic_binary(int operator, int flags, gal_data_t 
*l, gal_data_t *r)
     }
 
 
-#define BINFUNC_F_OPERATOR_LEFT_SET(LT, OP)                             \
+#define BINFUNC_F_OPERATOR_LEFT_SET(LT, OP, AFTER)                      \
   switch(r->type)                                                       \
     {                                                                   \
     case GAL_TYPE_FLOAT32:                                              \
-      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(float, LT, OP);                 \
+      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(float, LT, OP, AFTER);          \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(double, LT, OP);                \
+      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(double, LT, OP, AFTER);         \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type %d not recognized for r->type",  \
@@ -1679,14 +1694,14 @@ arithmetic_binary(int operator, int flags, gal_data_t 
*l, gal_data_t *r)
     }
 
 
-#define BINFUNC_F_OPERATOR_SET(OP)                                      \
+#define BINFUNC_F_OPERATOR_SET(OP, AFTER)                               \
   switch(l->type)                                                       \
     {                                                                   \
     case GAL_TYPE_FLOAT32:                                              \
-      BINFUNC_F_OPERATOR_LEFT_SET(float, OP);                           \
+      BINFUNC_F_OPERATOR_LEFT_SET(float, OP, AFTER);                    \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      BINFUNC_F_OPERATOR_LEFT_SET(double, OP);                          \
+      BINFUNC_F_OPERATOR_LEFT_SET(double, OP, AFTER);                   \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type %d not recognized for l->type",  \
@@ -1695,12 +1710,13 @@ arithmetic_binary(int operator, int flags, gal_data_t 
*l, gal_data_t *r)
 
 
 static gal_data_t *
-arithmetic_binary_function_flt(int operator, int flags, gal_data_t *il,
+arithmetic_function_binary_flt(int operator, int flags, gal_data_t *il,
                                gal_data_t *ir)
 {
   int final_otype;
   size_t out_size, minmapsize;
   gal_data_t *l, *r, *o=NULL;
+  double pi=3.14159265358979323846264338327;
   int quietmmap=il->quietmmap && ir->quietmmap;
 
   /* Simple sanity check on the input sizes */
@@ -1709,6 +1725,7 @@ arithmetic_binary_function_flt(int operator, int flags, 
gal_data_t *il,
     error(EXIT_FAILURE, 0, "%s: the input datasets don't have the same "
           "dimension/size", __func__);
 
+
   /* Convert the values to double precision floating point if they are
      integer. */
   l = ( (il->type==GAL_TYPE_FLOAT32 || il->type==GAL_TYPE_FLOAT64)
@@ -1716,12 +1733,15 @@ arithmetic_binary_function_flt(int operator, int flags, 
gal_data_t *il,
   r = ( (ir->type==GAL_TYPE_FLOAT32 || ir->type==GAL_TYPE_FLOAT64)
          ? ir : gal_data_copy_to_new_type(ir, GAL_TYPE_FLOAT64) );
 
+
   /* Set the output type. */
   final_otype = gal_type_out(l->type, r->type);
 
+
   /* Set the output sizes. */
   minmapsize = ( l->minmapsize < r->minmapsize
-                 ? l->minmapsize : r->minmapsize );
+                 ? l->minmapsize
+                 : r->minmapsize );
   out_size = l->size > r->size ? l->size : r->size;
 
 
@@ -1751,7 +1771,10 @@ arithmetic_binary_function_flt(int operator, int flags, 
gal_data_t *il,
   /* Start setting the operator and operands. */
   switch(operator)
     {
-    case GAL_ARITHMETIC_OP_POW:  BINFUNC_F_OPERATOR_SET( pow ); break;
+    case GAL_ARITHMETIC_OP_POW:
+      BINFUNC_F_OPERATOR_SET( pow,   +0 );         break;
+    case GAL_ARITHMETIC_OP_ATAN2:
+      BINFUNC_F_OPERATOR_SET( atan2, *180.0f/pi ); break;
     default:
       error(EXIT_FAILURE, 0, "%s: operator code %d not recognized",
             __func__, operator);
@@ -1898,15 +1921,43 @@ gal_arithmetic_set_operator(char *string, size_t 
*num_operands)
   else if (!strcmp(string, "log10"))
     { op=GAL_ARITHMETIC_OP_LOG10;             *num_operands=1;  }
 
+  /* Trigonometric functions. */
+  else if( !strcmp(string, "sin"))
+    { op=GAL_ARITHMETIC_OP_SIN;               *num_operands=1; }
+  else if( !strcmp(string, "cos"))
+    { op=GAL_ARITHMETIC_OP_COS;               *num_operands=1; }
+  else if( !strcmp(string, "tan"))
+    { op=GAL_ARITHMETIC_OP_TAN;               *num_operands=1; }
+  else if( !strcmp(string, "asin"))
+    { op=GAL_ARITHMETIC_OP_ASIN;              *num_operands=1; }
+  else if( !strcmp(string, "acos"))
+    { op=GAL_ARITHMETIC_OP_ACOS;              *num_operands=1; }
+  else if( !strcmp(string, "atan"))
+    { op=GAL_ARITHMETIC_OP_ATAN;              *num_operands=1; }
+  else if( !strcmp(string, "atan2"))
+    { op=GAL_ARITHMETIC_OP_ATAN2;             *num_operands=2; }
+  else if( !strcmp(string, "sinh"))
+    { op=GAL_ARITHMETIC_OP_SINH;              *num_operands=1; }
+  else if( !strcmp(string, "cosh"))
+    { op=GAL_ARITHMETIC_OP_COSH;              *num_operands=1; }
+  else if( !strcmp(string, "tanh"))
+    { op=GAL_ARITHMETIC_OP_TANH;              *num_operands=1; }
+  else if( !strcmp(string, "asinh"))
+    { op=GAL_ARITHMETIC_OP_ASINH;             *num_operands=1; }
+  else if( !strcmp(string, "acosh"))
+    { op=GAL_ARITHMETIC_OP_ACOSH;             *num_operands=1; }
+  else if( !strcmp(string, "atanh"))
+    { op=GAL_ARITHMETIC_OP_ATANH;             *num_operands=1; }
+
   /* Units conversion functions */
   else if (!strcmp(string, "ra-to-degree"))
-    { op=GAL_ARITHMETIC_OP_RA_TO_DEGREE;   *num_operands=1;  }
+    { op=GAL_ARITHMETIC_OP_RA_TO_DEGREE;      *num_operands=1;  }
   else if (!strcmp(string, "dec-to-degree"))
-    { op=GAL_ARITHMETIC_OP_DEC_TO_DEGREE;  *num_operands=1;  }
+    { op=GAL_ARITHMETIC_OP_DEC_TO_DEGREE;     *num_operands=1;  }
   else if (!strcmp(string, "degree-to-ra"))
-    { op=GAL_ARITHMETIC_OP_DEGREE_TO_RA;   *num_operands=1;  }
+    { op=GAL_ARITHMETIC_OP_DEGREE_TO_RA;      *num_operands=1;  }
   else if (!strcmp(string, "degree-to-dec"))
-    { op=GAL_ARITHMETIC_OP_DEGREE_TO_DEC;  *num_operands=1;  }
+    { op=GAL_ARITHMETIC_OP_DEGREE_TO_DEC;     *num_operands=1;  }
 
   /* Statistical/higher-level operators. */
   else if (!strcmp(string, "minvalue"))
@@ -2062,6 +2113,20 @@ gal_arithmetic_operator_string(int operator)
     case GAL_ARITHMETIC_OP_LOG:             return "log";
     case GAL_ARITHMETIC_OP_LOG10:           return "log10";
 
+    case GAL_ARITHMETIC_OP_SIN:             return "sin";
+    case GAL_ARITHMETIC_OP_COS:             return "cos";
+    case GAL_ARITHMETIC_OP_TAN:             return "tan";
+    case GAL_ARITHMETIC_OP_ASIN:            return "asin";
+    case GAL_ARITHMETIC_OP_ACOS:            return "acos";
+    case GAL_ARITHMETIC_OP_ATAN:            return "atan";
+    case GAL_ARITHMETIC_OP_SINH:            return "sinh";
+    case GAL_ARITHMETIC_OP_COSH:            return "cosh";
+    case GAL_ARITHMETIC_OP_TANH:            return "tanh";
+    case GAL_ARITHMETIC_OP_ASINH:           return "asinh";
+    case GAL_ARITHMETIC_OP_ACOSH:           return "acosh";
+    case GAL_ARITHMETIC_OP_ATANH:           return "atanh";
+    case GAL_ARITHMETIC_OP_ATAN2:           return "atan2";
+
     case GAL_ARITHMETIC_OP_RA_TO_DEGREE:    return "ra-to-degree";
     case GAL_ARITHMETIC_OP_DEC_TO_DEGREE:   return "dec-to-degree";
     case GAL_ARITHMETIC_OP_DEGREE_TO_RA:    return "degree-to-ra";
@@ -2161,17 +2226,36 @@ gal_arithmetic(int operator, size_t numthreads, int 
flags, ...)
       out=d1;
       break;
 
-
     /* Unary function operators. */
     case GAL_ARITHMETIC_OP_SQRT:
     case GAL_ARITHMETIC_OP_LOG:
     case GAL_ARITHMETIC_OP_LOG10:
+    case GAL_ARITHMETIC_OP_SIN:
+    case GAL_ARITHMETIC_OP_COS:
+    case GAL_ARITHMETIC_OP_TAN:
+    case GAL_ARITHMETIC_OP_ASIN:
+    case GAL_ARITHMETIC_OP_ACOS:
+    case GAL_ARITHMETIC_OP_ATAN:
+    case GAL_ARITHMETIC_OP_SINH:
+    case GAL_ARITHMETIC_OP_COSH:
+    case GAL_ARITHMETIC_OP_TANH:
+    case GAL_ARITHMETIC_OP_ASINH:
+    case GAL_ARITHMETIC_OP_ACOSH:
+    case GAL_ARITHMETIC_OP_ATANH:
     case GAL_ARITHMETIC_OP_RA_TO_DEGREE:
     case GAL_ARITHMETIC_OP_DEC_TO_DEGREE:
     case GAL_ARITHMETIC_OP_DEGREE_TO_RA:
     case GAL_ARITHMETIC_OP_DEGREE_TO_DEC:
       d1 = va_arg(va, gal_data_t *);
-      out=arithmetic_unary_function(operator, flags, d1);
+      out=arithmetic_function_unary(operator, flags, d1);
+      break;
+
+    /* Binary function operators. */
+    case GAL_ARITHMETIC_OP_POW:
+    case GAL_ARITHMETIC_OP_ATAN2:
+      d1 = va_arg(va, gal_data_t *);
+      d2 = va_arg(va, gal_data_t *);
+      out=arithmetic_function_binary_flt(operator, flags, d1, d2);
       break;
 
     /* Statistical operators that return one value. */
@@ -2210,15 +2294,6 @@ gal_arithmetic(int operator, size_t numthreads, int 
flags, ...)
       out=arithmetic_multioperand(operator, flags, d1, d2, numthreads);
       break;
 
-
-    /* Binary function operators. */
-    case GAL_ARITHMETIC_OP_POW:
-      d1 = va_arg(va, gal_data_t *);
-      d2 = va_arg(va, gal_data_t *);
-      out=arithmetic_binary_function_flt(operator, flags, d1, d2);
-      break;
-
-
     /* Binary operators that only work on integer types. */
     case GAL_ARITHMETIC_OP_BITAND:
     case GAL_ARITHMETIC_OP_BITOR:
diff --git a/lib/gnuastro/arithmetic.h b/lib/gnuastro/arithmetic.h
index c854208..0d543ec 100644
--- a/lib/gnuastro/arithmetic.h
+++ b/lib/gnuastro/arithmetic.h
@@ -77,7 +77,7 @@ enum gal_arithmetic_operators
 
   GAL_ARITHMETIC_OP_PLUS,         /*   +     */
   GAL_ARITHMETIC_OP_MINUS,        /*   -     */
-  GAL_ARITHMETIC_OP_MULTIPLY,     /*   *     */
+  GAL_ARITHMETIC_OP_MULTIPLY,     /*   x     */
   GAL_ARITHMETIC_OP_DIVIDE,       /*   /     */
   GAL_ARITHMETIC_OP_MODULO,       /*   %     */
 
@@ -106,6 +106,20 @@ enum gal_arithmetic_operators
   GAL_ARITHMETIC_OP_LOG,          /* log()   */
   GAL_ARITHMETIC_OP_LOG10,        /* log10() */
 
+  GAL_ARITHMETIC_OP_SIN,          /* sine    */
+  GAL_ARITHMETIC_OP_COS,          /* cosine  */
+  GAL_ARITHMETIC_OP_TAN,          /* tangent */
+  GAL_ARITHMETIC_OP_ASIN,         /* Inverse sine */
+  GAL_ARITHMETIC_OP_ACOS,         /* Inverse cosine */
+  GAL_ARITHMETIC_OP_ATAN,         /* Inverse tangent */
+  GAL_ARITHMETIC_OP_ATAN2,        /* Inverse tangent (with two inputs). */
+  GAL_ARITHMETIC_OP_SINH,         /* Hyperbolic sine. */
+  GAL_ARITHMETIC_OP_COSH,         /* Hyperbolic cosine. */
+  GAL_ARITHMETIC_OP_TANH,         /* Hyperbolic tangent. */
+  GAL_ARITHMETIC_OP_ASINH,        /* Inverse hyperbolic sine. */
+  GAL_ARITHMETIC_OP_ACOSH,        /* Inverse hyperbolic cosine. */
+  GAL_ARITHMETIC_OP_ATANH,        /* Inverse hyperbolic tangent. */
+
   GAL_ARITHMETIC_OP_RA_TO_DEGREE, /* right ascension to decimal      */
   GAL_ARITHMETIC_OP_DEC_TO_DEGREE,/* declination to decimal          */
   GAL_ARITHMETIC_OP_DEGREE_TO_RA, /* right ascension to decimal      */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]