gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master ff9258a 006/125: Arithmetic with internal type


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master ff9258a 006/125: Arithmetic with internal type conversion
Date: Sun, 23 Apr 2017 22:36:25 -0400 (EDT)

branch: master
commit ff9258a201cac1c11cc900a67f115b07bd77c447
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Arithmetic with internal type conversion
    
    Arithmetic now uses the internal type conversion of C on arrays on internal
    binary operators when the types are different.  Until now, it would convert
    them to the same type and then do the operation. But now, there is no need
    to do any conversion. This will speed up the process, but it is a strong
    burden on the compilation, so the compilation can become very slow,
    especially, when all the types are desired, on my computer it took about 40
    minutes to compile `data.o' and `data.c'. So some configure time options
    have been added to allow the users to choose the non-basic types if they
    want them.
    
    Don't forget to add/describe the configure time options in the final
    manual, and also the new macros in `gnuastro/config.h' describing the
    different arithmetic types.
---
 configure.ac          |  73 +++++++++++
 lib/Makefile.am       |   7 +
 lib/config.h.in       |   7 +
 lib/data-arithmetic.h | 344 +++++++++++++++++++++++++++++++++++++++-----------
 lib/data.c            |  16 +--
 lib/gnuastro/data.h   |  12 ++
 6 files changed, 378 insertions(+), 81 deletions(-)

diff --git a/configure.ac b/configure.ac
index a1bbc2e..037d841 100644
--- a/configure.ac
+++ b/configure.ac
@@ -259,6 +259,79 @@ AC_DEFINE_UNQUOTED([CONF_SHOWFMT], [" %-20s"],
 
 
 
+# Enable the types
+AC_ARG_ENABLE([arith-char],
+              [AS_HELP_STRING([--enable-arith-char],
+                    [Enable direct arithmetic on char.])],
+             [AS_IF([test "x$enable_arith_char" != xno],
+                     [enable_arith_char=1], [enable_arith_char=0])],
+              [enable_arith_char=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_CHAR], [$enable_arith_char],
+                   [Direct arithmetic on char data.])
+AC_SUBST(HAVE_ARITH_CHAR, [$enable_arith_char])
+
+AC_ARG_ENABLE([arith-ushort],
+              [AS_HELP_STRING([--enable-arith-ushort],
+                    [Enable direct arithmetic on ushort.])],
+             [AS_IF([test "x$enable_arith_ushort" != xno],
+                     [enable_arith_ushort=1], [enable_arith_ushort=0])],
+              [enable_arith_ushort=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_USHORT], [$enable_arith_ushort],
+                   [Direct arithmetic on unsigned short data.])
+AC_SUBST(HAVE_ARITH_USHORT, [$enable_arith_ushort])
+
+AC_ARG_ENABLE([arith-short],
+              [AS_HELP_STRING([--enable-arith-short],
+                    [Enable direct arithmetic on short.])],
+             [AS_IF([test "x$enable_arith_short" != xno],
+                     [enable_arith_short=1], [enable_arith_short=0])],
+              [enable_arith_short=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_SHORT], [$enable_arith_short],
+                   [Direct arithmetic on short data.])
+AC_SUBST(HAVE_ARITH_SHORT, [$enable_arith_short])
+
+AC_ARG_ENABLE([arith-uint],
+              [AS_HELP_STRING([--enable-arith-uint],
+                    [Enable direct arithmetic on uint.])],
+             [AS_IF([test "x$enable_arith_uint" != xno],
+                     [enable_arith_uint=1], [enable_arith_uint=0])],
+              [enable_arith_uint=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_UINT], [$enable_arith_uint],
+                   [Direct arithmetic on unsigned int data.])
+AC_SUBST(HAVE_ARITH_UINT, [$enable_arith_uint])
+
+AC_ARG_ENABLE([arith-int],
+              [AS_HELP_STRING([--enable-arith-int],
+                    [Enable direct arithmetic on int.])],
+             [AS_IF([test "x$enable_arith_int" != xno],
+                     [enable_arith_int=1], [enable_arith_int=0])],
+              [enable_arith_int=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_INT], [$enable_arith_int],
+                   [Direct arithmetic on int data.])
+AC_SUBST(HAVE_ARITH_INT, [$enable_arith_int])
+
+AC_ARG_ENABLE([arith-ulong],
+              [AS_HELP_STRING([--enable-arith-ulong],
+                    [Enable direct arithmetic on unsigned long.])],
+             [AS_IF([test "x$enable_arith_ulong" != xno],
+                     [enable_arith_ulong=1], [enable_arith_ulong=0])],
+              [enable_arith_ulong=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_ULONG], [$enable_arith_ulong],
+                   [Direct arithmetic on unsigned long data.])
+AC_SUBST(HAVE_ARITH_ULONG, [$enable_arith_ulong])
+
+AC_ARG_ENABLE([arith-longlong],
+              [AS_HELP_STRING([--enable-arith-longlong],
+                    [Enable direct arithmetic on long long.])],
+             [AS_IF([test "x$enable_arith_longlong" != xno],
+                     [enable_arith_longlong=1], [enable_arith_longlong=0])],
+              [enable_arith_longlong=0])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_ARITH_LONGLONG], [$enable_arith_longlong],
+                   [Direct arithmetic on long long data.])
+AC_SUBST(HAVE_ARITH_LONGLONG, [$enable_arith_longlong])
+
+
+
 
 # Read arguments about which programs to install. After checking if
 # the argument was actually called, remove any value the user might
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 49d36a6..e850b46 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -73,6 +73,13 @@ gnuastro/config.h: Makefile config.h.in
        $(MKDIR_P) gnuastro
        $(SED) -e 's|@address@hidden|$(VERSION)|g'                            \
               -e 's|@address@hidden|$(HAVE_LIBGIT2)|g'                  \
+              -e 's|@address@hidden|$(HAVE_ARITH_CHAR)|g'            \
+              -e 's|@address@hidden|$(HAVE_ARITH_USHORT)|g'        \
+              -e 's|@address@hidden|$(HAVE_ARITH_SHORT)|g'          \
+              -e 's|@address@hidden|$(HAVE_ARITH_UINT)|g'            \
+              -e 's|@address@hidden|$(HAVE_ARITH_INT)|g'              \
+              -e 's|@address@hidden|$(HAVE_ARITH_ULONG)|g'          \
+              -e 's|@address@hidden|$(HAVE_ARITH_LONGLONG)|g'    \
               -e 's|@address@hidden|$(HAVE_WCSLIB_VERSION)|g'    \
               -e 's|@address@hidden|$(HAVE_PTHREAD_BARRIER)|g'  \
                $(srcdir)/config.h.in >> address@hidden
diff --git a/lib/config.h.in b/lib/config.h.in
index e742ee6..5c795fc 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -30,6 +30,13 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Macros. */
 #define GAL_CONFIG_VERSION "@VERSION@"
 #define GAL_CONFIG_HAVE_LIBGIT2 @HAVE_LIBGIT2@
+#define GAL_CONFIG_ARITH_CHAR @HAVE_ARITH_CHAR@
+#define GAL_CONFIG_ARITH_USHORT @HAVE_ARITH_USHORT@
+#define GAL_CONFIG_ARITH_SHORT @HAVE_ARITH_SHORT@
+#define GAL_CONFIG_ARITH_UINT @HAVE_ARITH_UINT@
+#define GAL_CONFIG_ARITH_INT @HAVE_ARITH_INT@
+#define GAL_CONFIG_ARITH_ULONG @HAVE_ARITH_ULONG@
+#define GAL_CONFIG_ARITH_LONGLONG @HAVE_ARITH_LONGLONG@
 #define GAL_CONFIG_HAVE_WCSLIB_VERSION @HAVE_WCSLIB_VERSION@
 #define GAL_CONFIG_HAVE_PTHREAD_BARRIER @HAVE_PTHREAD_BARRIER@
 
diff --git a/lib/data-arithmetic.h b/lib/data-arithmetic.h
index c3c78c4..a0ef183 100644
--- a/lib/data-arithmetic.h
+++ b/lib/data-arithmetic.h
@@ -26,30 +26,271 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+#define BINARY_OPERATOR_FOR_TYPE(LT, RT, OT, OP){                       \
+    LT *la=l->array;                                                    \
+    RT *ra=r->array;                                                    \
+    OT *oa=o->array, *of=oa + o->size;                                  \
+    if(l->size==r->size) do *oa = *la++ OP *ra++; while(++oa<of);       \
+    else if(l->size==1)  do *oa = *la   OP *ra++; while(++oa<of);       \
+    else                 do *oa = *la++ OP *ra;   while(++oa<of);       \
+  }
+
+
+
+
+#if GAL_CONFIG_ARITH_CHAR == 1
+#define BINARY_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                         \
+  case GAL_DATA_TYPE_CHAR:                                              \
+    BINARY_OPERATOR_FOR_TYPE(LT, RT, char, OP);                         \
+    break;
+#define BINARY_LEFT_DONE_CHAR(LT, OP)                                   \
+    case GAL_DATA_TYPE_CHAR:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, char, OP);                             \
+      break;
+#define BINARY_MULTISWITCH_CHAR(OP)                                     \
+    case GAL_DATA_TYPE_CHAR:                                            \
+      BINARY_LEFT_DONE(char, OP);                                       \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)
+#define BINARY_LEFT_DONE_CHAR(LT, OP)
+#define BINARY_MULTISWITCH_CHAR(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_USHORT == 1
+#define BINARY_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)                         \
+  case GAL_DATA_TYPE_USHORT:                                              \
+    BINARY_OPERATOR_FOR_TYPE(LT, RT, unsigned short, OP);                 \
+    break;
+#define BINARY_LEFT_DONE_USHORT(LT, OP)                                   \
+    case GAL_DATA_TYPE_USHORT:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, unsigned short, OP);                     \
+      break;
+#define BINARY_MULTISWITCH_USHORT(OP)                                     \
+    case GAL_DATA_TYPE_USHORT:                                            \
+      BINARY_LEFT_DONE(unsigned short, OP);                               \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)
+#define BINARY_LEFT_DONE_USHORT(LT, OP)
+#define BINARY_MULTISWITCH_USHORT(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_SHORT == 1
+#define BINARY_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                         \
+  case GAL_DATA_TYPE_SHORT:                                              \
+    BINARY_OPERATOR_FOR_TYPE(LT, RT, short, OP);                         \
+    break;
+#define BINARY_LEFT_DONE_SHORT(LT, OP)                                   \
+    case GAL_DATA_TYPE_SHORT:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, short, OP);                             \
+      break;
+#define BINARY_MULTISWITCH_SHORT(OP)                                     \
+    case GAL_DATA_TYPE_SHORT:                                            \
+      BINARY_LEFT_DONE(short, OP);                                       \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)
+#define BINARY_LEFT_DONE_SHORT(LT, OP)
+#define BINARY_MULTISWITCH_SHORT(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_UINT == 1
+#define BINARY_LEFT_RIGHT_DONE_UINT(LT, RT, OP)                         \
+  case GAL_DATA_TYPE_UINT:                                              \
+    BINARY_OPERATOR_FOR_TYPE(LT, RT, unsigned int, OP);                 \
+    break;
+#define BINARY_LEFT_DONE_UINT(LT, OP)                                   \
+    case GAL_DATA_TYPE_UINT:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, unsigned int, OP);                     \
+      break;
+#define BINARY_MULTISWITCH_UINT(OP)                                     \
+    case GAL_DATA_TYPE_UINT:                                            \
+      BINARY_LEFT_DONE(unsigned int, OP);                               \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_UINT(LT, RT, OP)
+#define BINARY_LEFT_DONE_UINT(LT, OP)
+#define BINARY_MULTISWITCH_UINT(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_INT == 1
+#define BINARY_LEFT_RIGHT_DONE_INT(LT, RT, OP)                         \
+  case GAL_DATA_TYPE_INT:                                              \
+    BINARY_OPERATOR_FOR_TYPE(LT, RT, int, OP);                         \
+    break;
+#define BINARY_LEFT_DONE_INT(LT, OP)                                   \
+    case GAL_DATA_TYPE_INT:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, int, OP);                             \
+      break;
+#define BINARY_MULTISWITCH_INT(OP)                                     \
+    case GAL_DATA_TYPE_INT:                                            \
+      BINARY_LEFT_DONE(int, OP);                                       \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_INT(LT, RT, OP)
+#define BINARY_LEFT_DONE_INT(LT, OP)
+#define BINARY_MULTISWITCH_INT(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_ULONG == 1
+#define BINARY_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)                        \
+    case GAL_DATA_TYPE_ULONG:                                           \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, unsigned long, OP);              \
+      break;
+#define BINARY_LEFT_DONE_ULONG(LT, OP)                                  \
+    case GAL_DATA_TYPE_ULONG:                                           \
+      BINARY_LEFT_RIGHT_DONE(LT, unsigned long, OP);                    \
+      break;
+#define BINARY_MULTISWITCH_ULONG(OP)                                    \
+    case GAL_DATA_TYPE_ULONG:                                           \
+      BINARY_LEFT_DONE(unsigned long, OP);                              \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)
+#define BINARY_LEFT_DONE_ULONG(LT, OP)
+#define BINARY_MULTISWITCH_ULONG(OP)
+#endif
+
+
+
+#if GAL_CONFIG_ARITH_LONGLONG == 1
+#define BINARY_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)                     \
+    case GAL_DATA_TYPE_LONGLONG:                                        \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, LONGLONG, OP);                   \
+      break;
+#define BINARY_LEFT_DONE_LONGLONG(LT, OP)                               \
+    case GAL_DATA_TYPE_LONGLONG:                                        \
+      BINARY_LEFT_RIGHT_DONE(LT, long long, OP);                        \
+      break;
+#define BINARY_MULTISWITCH_LONGLONG(OP)                                 \
+    case GAL_DATA_TYPE_LONGLONG:                                        \
+      BINARY_LEFT_DONE(LONGLONG, OP);                                   \
+      break;
+#else
+#define BINARY_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)
+#define BINARY_LEFT_DONE_LONGLONG(LT, OP)
+#define BINARY_MULTISWITCH_LONGLONG(OP)
+#endif
+
+
+
+
+
+#define BINARY_LEFT_RIGHT_DONE(LT, RT, OP)                              \
+  switch(o->type)                                                       \
+    {                                                                   \
+                                                                        \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, unsigned char, OP);              \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONG:                                            \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, long, OP);                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, float, OP);                      \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, double, OP);                     \
+      break;                                                            \
+                                                                        \
+    BINARY_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                             \
+    BINARY_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                            \
+    BINARY_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)                           \
+    BINARY_LEFT_RIGHT_DONE_INT(LT, RT, OP)                              \
+    BINARY_LEFT_RIGHT_DONE_UINT(LT, RT, OP)                             \
+    BINARY_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)                            \
+    BINARY_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)                         \
+                                                                        \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for o->type in BINARY_LEFT_RIGHT_DONE", type);             \
+    }
+
+
+
+
+
+#define BINARY_LEFT_DONE(LT, OP)                                        \
+  switch(r->type)                                                       \
+    {                                                                   \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      BINARY_LEFT_RIGHT_DONE(LT, unsigned char, OP);                    \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONG:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, long, OP);                             \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINARY_LEFT_RIGHT_DONE(LT, float, OP);                            \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_LEFT_RIGHT_DONE(LT, double, OP);                           \
+      break;                                                            \
+                                                                        \
+    BINARY_LEFT_DONE_CHAR(LT, OP)                                       \
+    BINARY_LEFT_DONE_USHORT(LT, OP)                                     \
+    BINARY_LEFT_DONE_SHORT(LT, OP)                                      \
+    BINARY_LEFT_DONE_UINT(LT, OP)                                       \
+    BINARY_LEFT_DONE_INT(LT, OP)                                        \
+    BINARY_LEFT_DONE_ULONG(LT, OP)                                      \
+    BINARY_LEFT_DONE_LONGLONG(LT, OP)                                   \
+                                                                        \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for r->type in BINARY_LEFT_DONE", type);                   \
+    }
 
-#define BINARY_DEFINITIONS                                                \
-  unsigned char  *luc = l->array, *ruc = r->array, *ouc = o->array, *ucf; \
-  char           *lc  = l->array, *rc  = r->array, *oc  = o->array,  *cf; \
-  unsigned short *lus = l->array, *rus = r->array, *ous = o->array, *usf; \
-  short          *ls  = l->array, *rs  = r->array, *os  = o->array,  *sf; \
-  unsigned int   *lui = l->array, *rui = r->array, *oui = o->array, *uif; \
-  int            *li  = l->array, *ri  = r->array, *oi  = o->array, *iif; \
-  unsigned long  *lul = l->array, *rul = r->array, *oul = o->array, *ulf; \
-  long           *ll  = l->array, *rl  = r->array, *ol  = o->array,  *lf; \
-  LONGLONG       *lL  = l->array, *rL  = r->array, *oL  = o->array,  *Lf; \
-  float          *lff = l->array, *rf  = r->array, *of  = o->array,  *ff; \
-  double         *ld  = l->array, *rd  = r->array, *od  = o->array,  *df;
 
 
 
 
-#define OP_FUNC(OP,L, R)
-#define BINARY_OPERATOR_FOR_TYPE(Tf, oT, lT, rT, OP)                    \
-  Tf = oT + o->size;                                                    \
-  if(l->size==r->size) do *oT = *lT++ OP *rT++; while(++oT<Tf);         \
-  else if(l->size==1)  do *oT = *lT   OP *rT++; while(++oT<Tf);         \
-  else                 do *oT = *lT++ OP *rT;   while(++oT<Tf);         \
-  break;
+#define BINARY_MULTISWITCH(OP)                                          \
+  switch(l->type)                                                       \
+    {                                                                   \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      BINARY_LEFT_DONE(unsigned char, OP);                              \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONG:                                            \
+      BINARY_LEFT_DONE(long, OP);                                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINARY_LEFT_DONE(float, OP);                                      \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_LEFT_DONE(double, OP);                                     \
+      break;                                                            \
+                                                                        \
+    BINARY_MULTISWITCH_CHAR(OP)                                         \
+    BINARY_MULTISWITCH_USHORT(OP)                                       \
+    BINARY_MULTISWITCH_SHORT(OP)                                        \
+    BINARY_MULTISWITCH_UINT(OP)                                         \
+    BINARY_MULTISWITCH_INT(OP)                                          \
+    BINARY_MULTISWITCH_ULONG(OP)                                        \
+    BINARY_MULTISWITCH_LONGLONG(OP)                                     \
+                                                                        \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for l->type in BINARY_MULTISWITCH", type);                 \
+    }
 
 
 
@@ -61,26 +302,24 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    `l' and `s' pointers. */
 #define BINARY_INTERNAL(OP, OUT_TYPE)                                   \
                                                                         \
-  gal_data_t *l, *r, *left, *right;                                     \
+  gal_data_t *l, *r;                                                    \
                                                                         \
                                                                         \
   /* Read the variable arguments. */                                    \
-  left = va_arg(va, gal_data_t *);                                      \
-  right = va_arg(va, gal_data_t *);                                     \
+  l = va_arg(va, gal_data_t *);                                         \
+  r = va_arg(va, gal_data_t *);                                         \
                                                                         \
                                                                         \
-  /* Simple sanity check, then choose the common type. */               \
-  if( (flags & GAL_DATA_ARITH_NUMOK) && (left->size==1 || right->size==1 ) ) \
+  /* Simple sanity check on the input sizes */                          \
+  if( (flags & GAL_DATA_ARITH_NUMOK) && (l->size==1 || r->size==1 ) )   \
     type=0;      /* Everything is ok, just a place-holder. */           \
-  else if (gal_data_dsize_is_different(left, right))                    \
+  else if (gal_data_dsize_is_different(l, r))                           \
     error(EXIT_FAILURE, 0, "The datasets don't have the same "          \
           "dimension/size");                                            \
                                                                         \
                                                                         \
-  /* Set the two datasets to the same type if they were different. */   \
-  type=gal_data_out_type(left, right);                                  \
-  gal_data_to_same_type(left, right, &l, &r, type,                      \
-                        flags & GAL_DATA_ARITH_FREE );                  \
+  /* Find the best output type. */                                      \
+  type=gal_data_out_type(l, r);                                         \
                                                                         \
                                                                         \
   /* Output can point to any one of the two arrays. */                  \
@@ -94,51 +333,10 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
                                                                         \
                                                                         \
   /* In block to allow definitions. */                                  \
-  {                                                                     \
-    BINARY_DEFINITIONS;                                                 \
-    switch(l->type)                                                     \
-      {                                                                 \
-      case GAL_DATA_TYPE_UCHAR:                                         \
-        BINARY_OPERATOR_FOR_TYPE(ucf, ouc, luc, ruc, OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_CHAR:                                          \
-        BINARY_OPERATOR_FOR_TYPE(cf,  oc,  lc,  rc,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_USHORT:                                        \
-        BINARY_OPERATOR_FOR_TYPE(usf, ous, lus, rus, OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_SHORT:                                         \
-        BINARY_OPERATOR_FOR_TYPE(sf,  os,  ls,  rs,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_UINT:                                          \
-        BINARY_OPERATOR_FOR_TYPE(uif, oui, lui, rui, OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_INT:                                           \
-        BINARY_OPERATOR_FOR_TYPE(iif, oi,  li,  ri,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_ULONG:                                         \
-        BINARY_OPERATOR_FOR_TYPE(ulf, oul, lul, rul, OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_LONG:                                          \
-        BINARY_OPERATOR_FOR_TYPE(lf,  ol,  ll,  rl,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_LONGLONG:                                      \
-        BINARY_OPERATOR_FOR_TYPE(Lf,  oL,  lL,  rL,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_FLOAT:                                         \
-        BINARY_OPERATOR_FOR_TYPE(ff, of,  lff,  rf,  OP);               \
-                                                                        \
-      case GAL_DATA_TYPE_DOUBLE:                                        \
-        BINARY_OPERATOR_FOR_TYPE(df,  od,  ld,  rd,  OP);               \
-                                                                        \
-      default:                                                          \
-        error(EXIT_FAILURE, 0, "type %d not recognized in "             \
-              "data-arithmetic", type);                                 \
-      }                                                                 \
-  }                                                                     \
+  BINARY_MULTISWITCH(OP);                                               \
                                                                         \
-    /* Clean up. */                                                     \
-    if(flags & GAL_DATA_ARITH_FREE)                                     \
+  /* Clean up. */                                                       \
+  if(flags & GAL_DATA_ARITH_FREE)                                       \
     {                                                                   \
       if(o==l) gal_data_free(r);                                        \
       else if(o==r) gal_data_free(l);                                   \
diff --git a/lib/data.c b/lib/data.c
index 61b130c..cd5bc67 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -1155,6 +1155,14 @@ gal_data_arithmetic(char *operator, unsigned char flags, 
...)
   else if (!strcmp(operator, "-"))   { BINARY_INTERNAL(-, 0); }
   else if (!strcmp(operator, "*"))   { BINARY_INTERNAL(*, 0); }
   else if (!strcmp(operator, "/"))   { BINARY_INTERNAL(/, 0); }
+  else if (!strcmp(operator, "lt"))  { BINARY_INTERNAL(<, 0); }
+  else if (!strcmp(operator, "le"))  { BINARY_INTERNAL(<=, 0); }
+  else if (!strcmp(operator, "gt"))  { BINARY_INTERNAL(>, 0); }
+  else if (!strcmp(operator, "ge"))  { BINARY_INTERNAL(>=, 0); }
+  else if (!strcmp(operator, "eq"))  { BINARY_INTERNAL(==, 0); }
+  else if (!strcmp(operator, "neq")) { BINARY_INTERNAL(!=, 0); }
+  else if (!strcmp(operator, "and")) { BINARY_INTERNAL(&&, 0); }
+  else if (!strcmp(operator, "or"))  { BINARY_INTERNAL(||, 0); }
 
 #if 0
   else if(!strcmp(operator, "abs"))       takeabs(p);
@@ -1168,14 +1176,6 @@ gal_data_arithmetic(char *operator, unsigned char flags, 
...)
           || !strcmp(operator, "max")
           || !strcmp(operator, "average")
           || !strcmp(operator, "median")) alloppixs(p, operator);
-  else if(!strcmp(operator, "lt")
-          || !strcmp(operator, "le")
-          || !strcmp(operator, "gt")
-          || !strcmp(operator, "ge")
-          || !strcmp(operator, "eq")
-          || !strcmp(operator, "neq"))    conditionals(p, operator);
-  else if(!strcmp(operator, "and")
-          || !strcmp(operator, "or"))     andor(p, operator);
   else if(!strcmp(operator, "not"))       notfunc(p);
   else if(!strcmp(operator, "isblank"))   opisblank(p);
   else if(!strcmp(operator, "where"))     where(p);
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index f37e10b..d841833 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -33,6 +33,18 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <wcslib/wcs.h>
 #include <gsl/gsl_complex.h>
 
+/* When we are within Gnuastro's building process, `IN_GNUASTRO_BUILD' is
+   defined. In the build process, installation information (in particular
+   `GAL_CONFIG_ARITH_CHAR' and the rest of the types that we needed in the
+   arithmetic function) is kept in `config.h'. When building a user's
+   programs, this information is kept in `gnuastro/config.h'. Note that all
+   `.c' files must start with the inclusion of `config.h' and that
+   `gnuastro/config.h' is only created at installation time (not present
+   during the building of Gnuastro).*/
+#ifndef IN_GNUASTRO_BUILD
+#include <gnuastro/config.h>
+#endif
+
 /* C++ Preparations */
 #undef __BEGIN_C_DECLS
 #undef __END_C_DECLS



reply via email to

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