gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 3ad83a4 010/125: data-arithmetic and data-copy


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 3ad83a4 010/125: data-arithmetic and data-copy separated from data.c
Date: Sun, 23 Apr 2017 22:36:26 -0400 (EDT)

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

    data-arithmetic and data-copy separated from data.c
    
    To break down the load on the compiler, the `gal_data_arithmetic' and
    `gal_data_copy_to_new_type' were moved to the separate
    `lib/data-arithmetic.c' and `lib/data-copy.c'. So these two macro-intensive
    functions will be compiled separately.
    
    Other changes in this commit are:
    
     - The output type is no longer a mandatory option for Arithmetic, because
       now, the input image type will be used.
    
     - Also, the implementation of `gal_data_copy_to_new_type' was changed to
       be similar to how `gal_data_arithmetic' works.
    
     - `gal_data_alloc' now accepts WCS structure also.
    
     - A new macro was added to `data.h' to only do native arithmetic on float
       types to significantly speed up compilation during
       debugging/programming.
---
 bin/arithmetic/arithmetic.c                        |  22 +-
 bin/arithmetic/astarithmetic.conf                  |   1 -
 bin/arithmetic/ui.c                                |   4 -
 lib/Makefile.am                                    |  40 ++-
 ...{data-arithmetic.h => data-arithmetic-binary.h} | 171 +++++++---
 lib/data-arithmetic.c                              |  63 ++++
 lib/data-arithmetic.h                              | 331 +------------------
 lib/data-changetype.c                              | 363 ---------------------
 lib/data-changetype.h                              |  60 ----
 lib/data-copy.c                                    | 149 +++++++++
 lib/{data-arithmetic.c => data-copy.h}             |  11 +-
 lib/data.c                                         | 188 ++---------
 lib/fits.c                                         |   2 +-
 lib/gnuastro/data.h                                |   8 +-
 14 files changed, 418 insertions(+), 995 deletions(-)

diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index a777749..13883f6 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -221,26 +221,28 @@ reversepolish(struct imgarithparams *p)
     error(EXIT_FAILURE, 0, "too many operands");
 
 
-  /* Copy the WCS structure into the final dataset. */
-  p->operands->data->wcs=p->refdata.wcs;
-
-
   /* Set the output type. */
-  if(p->outtype==p->operands->data->type)
-    d1=p->operands->data;
-  else
+  if(p->up.typeset && p->outtype!=p->operands->data->type)
     {
       d1=gal_data_copy_to_new_type(p->operands->data, p->outtype);
       gal_data_free(p->operands->data);
     }
-  gal_fits_write_img(p->operands->data, p->cp.output, "Arithmetic", NULL,
-                     SPACK_STRING);
+  else
+    d1=p->operands->data;
+
+
+  /* Put a copy of the WCS structure from the reference image, it will be
+     freed while freeing d1. */
+  d1->wcs=p->refdata.wcs;
+
+
+  /* Write the data structure to a FITS image. */
+  gal_fits_write_img(d1, p->cp.output, "Arithmetic", NULL, SPACK_STRING);
 
 
   /* Clean up: */
   gal_data_free(d1);
   free(p->refdata.dsize);
-  wcsfree(p->refdata.wcs);
 
 
   /* Clean up. Note that the tokens were taken from the command-line
diff --git a/bin/arithmetic/astarithmetic.conf 
b/bin/arithmetic/astarithmetic.conf
index b877df2..ff8224f 100644
--- a/bin/arithmetic/astarithmetic.conf
+++ b/bin/arithmetic/astarithmetic.conf
@@ -27,5 +27,4 @@
  hdu            0
 
 # Output:
- type       float
  minmapsize    1000000000
\ No newline at end of file
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 4a18be8..71c6950 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -203,10 +203,6 @@ checkifset(struct imgarithparams *p)
   if(p->cp.minmapsizeset==0)
     GAL_CONFIGFILES_REPORT_NOTSET("minmapsize");
 
-  /* Output parameters: */
-  if(p->up.typeset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("type");
-
   /* Make sure the number of HDUs is not less than the total number of
      FITS images. If there are more HDUs than there are FITS images,
      there is no problem (since they can come from the configuration
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e850b46..f106b92 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,22 +19,34 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
+
+
+
 ## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
 ## for internally compiled utilities and libraries. It must not be included
 ## during the tests since the bootstrapped libraries are not installed.
 AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
 
 
+
+
+
 # Define the main compiled library file and its Libtool version.
 lib_LTLIBRARIES = libgnuastro.la
 libgnuastro_la_LDFLAGS = -version-info $(GAL_LT_VERSION)
 
 
+
+
+
 # Specify the library .c files
-libgnuastro_la_SOURCES = array.c box.c checkset.c configfiles.c data.c \
-  data-arithmetic.c data-changetype.c fits.c git.c linkedlist.c mesh.c \
-  mode.c polygon.c qsort.c spatialconvolve.c statistics.c threads.c    \
-  timing.c txtarray.c wcs.c
+libgnuastro_la_SOURCES = array.c box.c checkset.c configfiles.c data.c  \
+  data-arithmetic.c data-copy.c fits.c git.c linkedlist.c mesh.c mode.c \
+  polygon.c qsort.c spatialconvolve.c statistics.c threads.c timing.c   \
+  txtarray.c wcs.c
+
+
+
 
 
 # Installed headers, note that we are not blindly including all `.h' files
@@ -49,14 +61,21 @@ pkginclude_HEADERS = gnuastro/config.h 
$(headersdir)/array.h            \
   $(headersdir)/threads.h $(headersdir)/wcs.h $(headersdir)/txtarray.h
 
 
+
+
+
 # Files to distribute in the tarball. These are internal headers and don't
 # need to be installed. Headers are only mentioned within the source files,
 # and if they are not explicitly mentioned somewhere in the Makefile, they
 # will not distributed, so we need to explicitly tell Automake to
 # distribute them here.
-EXTRA_DIST = gnuastro.pc.in data-arithmetic.h data-changetype.h         \
-  config.h.in checkset.h commonargs.h commonparams.h configfiles.h      \
-  fixedstringmacros.h mode.h neighbors.h timing.h $(headersdir)/README
+EXTRA_DIST = gnuastro.pc.in data-arithmetic.h data-arithmetic-binary.h  \
+  data-copy.h config.h.in checkset.h commonargs.h commonparams.h        \
+  configfiles.h fixedstringmacros.h mode.h neighbors.h timing.h         \
+  $(headersdir)/README
+
+
+
 
 
 # Definitions for Gnuastro's the pkg-config file (inspired from GSL's
@@ -66,6 +85,9 @@ pkgconfigdir = $(libdir)/pkgconfig
 CLEANFILES = gnuastro.pc gnuastro/config.h
 
 
+
+
+
 # Build Gnuastro's pkg-config file and `config.h' based on the
 # information in the Makefile after the Makefile has been built.
 gnuastro/config.h: Makefile config.h.in
@@ -86,6 +108,10 @@ gnuastro/config.h: Makefile config.h.in
        chmod a-w address@hidden
        mv address@hidden $@
 
+
+
+
+
 gnuastro.pc: Makefile $(srcdir)/gnuastro.pc.in
        rm -f $@ address@hidden
        $(SED)                                      \
diff --git a/lib/data-arithmetic.h b/lib/data-arithmetic-binary.h
similarity index 86%
copy from lib/data-arithmetic.h
copy to lib/data-arithmetic-binary.h
index e7b35cd..c9d7336 100644
--- a/lib/data-arithmetic.h
+++ b/lib/data-arithmetic-binary.h
@@ -5,7 +5,7 @@ This is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
+Copyright (C) 2015, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -26,18 +26,11 @@ 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);       \
-  }
-
-
 
 
+/************************************************************************/
+/*************      Possibly set binary types to convert    *************/
+/************************************************************************/
 #if GAL_CONFIG_ARITH_CHAR == 1
 #define BINARY_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                         \
   case GAL_DATA_TYPE_CHAR:                                              \
@@ -59,6 +52,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_USHORT == 1
 #define BINARY_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)                         \
   case GAL_DATA_TYPE_USHORT:                                              \
@@ -80,6 +75,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_SHORT == 1
 #define BINARY_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                         \
   case GAL_DATA_TYPE_SHORT:                                              \
@@ -101,6 +98,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_UINT == 1
 #define BINARY_LEFT_RIGHT_DONE_UINT(LT, RT, OP)                         \
   case GAL_DATA_TYPE_UINT:                                              \
@@ -122,6 +121,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_INT == 1
 #define BINARY_LEFT_RIGHT_DONE_INT(LT, RT, OP)                         \
   case GAL_DATA_TYPE_INT:                                              \
@@ -143,6 +144,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_ULONG == 1
 #define BINARY_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)                        \
     case GAL_DATA_TYPE_ULONG:                                           \
@@ -164,6 +167,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+
 #if GAL_CONFIG_ARITH_LONGLONG == 1
 #define BINARY_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)                     \
     case GAL_DATA_TYPE_LONGLONG:                                        \
@@ -187,25 +192,109 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-#define BINARY_LEFT_RIGHT_DONE(LT, RT, OP)                              \
-  switch(o->type)                                                       \
-    {                                                                   \
-                                                                        \
+#if GAL_ONLY_FLOAT_FOR_FAST_DEBUG == 1
+
+#define BINARY_LEFT_RIGHT_DONE_UCHAR(LT, RT, OP)
+#define BINARY_LEFT_DONE_UCHAR(LT, OP)
+#define BINARY_MULTISWITCH_UCHAR(OP)
+
+#define BINARY_LEFT_RIGHT_DONE_LONG(LT, RT, OP)
+#define BINARY_LEFT_DONE_LONG(LT, OP)
+#define BINARY_MULTISWITCH_LONG(OP)
+
+#define BINARY_LEFT_RIGHT_DONE_DOUBLE(LT, RT, OP)
+#define BINARY_LEFT_DONE_DOUBLE(LT, OP)
+#define BINARY_MULTISWITCH_DOUBLE(OP)
+
+#else
+
+#define BINARY_LEFT_RIGHT_DONE_UCHAR(LT, RT, OP)                        \
     case GAL_DATA_TYPE_UCHAR:                                           \
       BINARY_OPERATOR_FOR_TYPE(LT, RT, unsigned char, OP);              \
-      break;                                                            \
-                                                                        \
+      break;
+#define BINARY_LEFT_DONE_UCHAR(LT, OP)                                  \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      BINARY_LEFT_RIGHT_DONE(LT, unsigned char, OP);                    \
+      break;
+#define BINARY_MULTISWITCH_UCHAR(OP)                                    \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      BINARY_LEFT_DONE(unsigned char, OP);                              \
+      break;
+
+#define BINARY_LEFT_RIGHT_DONE_LONG(LT, RT, OP)                         \
     case GAL_DATA_TYPE_LONG:                                            \
       BINARY_OPERATOR_FOR_TYPE(LT, RT, long, OP);                       \
-      break;                                                            \
+      break;
+#define BINARY_LEFT_DONE_LONG(LT, OP)                                   \
+    case GAL_DATA_TYPE_LONG:                                            \
+      BINARY_LEFT_RIGHT_DONE(LT, long, OP);                             \
+      break;
+#define BINARY_MULTISWITCH_LONG(OP)                                     \
+    case GAL_DATA_TYPE_LONG:                                            \
+      BINARY_LEFT_DONE(long, OP);                                       \
+      break;
+
+#define BINARY_LEFT_RIGHT_DONE_DOUBLE(LT, RT, OP)                       \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_OPERATOR_FOR_TYPE(LT, RT, double, OP);                     \
+      break;
+#define BINARY_LEFT_DONE_DOUBLE(LT, OP)                                 \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_LEFT_RIGHT_DONE(LT, double, OP);                           \
+      break;
+#define BINARY_MULTISWITCH_DOUBLE(OP)                                   \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINARY_LEFT_DONE(double, OP);                                     \
+      break;
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/************************************************************************/
+/*************          Binary conversion macros        *****************/
+/************************************************************************/
+#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);       \
+  }
+
+
+
+
+
+#define BINARY_LEFT_RIGHT_DONE(LT, RT, OP)                              \
+  switch(o->type)                                                       \
+    {                                                                   \
                                                                         \
     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_UCHAR(LT, RT, OP)                            \
+    BINARY_LEFT_RIGHT_DONE_LONG(LT, RT, OP)                             \
+    BINARY_LEFT_RIGHT_DONE_DOUBLE(LT, RT, OP)                           \
                                                                         \
     BINARY_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                             \
     BINARY_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                            \
@@ -227,21 +316,15 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #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_UCHAR(LT, OP)                                      \
+    BINARY_LEFT_DONE_LONG(LT, OP)                                       \
+    BINARY_LEFT_DONE_DOUBLE(LT, OP)                                     \
+                                                                        \
                                                                         \
     BINARY_LEFT_DONE_CHAR(LT, OP)                                       \
     BINARY_LEFT_DONE_USHORT(LT, OP)                                     \
@@ -300,28 +383,20 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
     o = gal_data_alloc(NULL, out_type,                                  \
                        l->size>1 ? l->ndim  : r->ndim,                  \
                        l->size>1 ? l->dsize : r->dsize,                 \
-                       0, ( l->minmapsize<r->minmapsize                 \
-                            ? l->minmapsize : r->minmapsize) );         \
-                                                                        \
+                       l->size>1 ? l->wcs : r->wcs, 0,                  \
+                       ( l->minmapsize<r->minmapsize                    \
+                         ? l->minmapsize : r->minmapsize ) );           \
                                                                         \
   /* Do the operations based on the different types. */                 \
   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_UCHAR(OP)                                        \
+    BINARY_MULTISWITCH_LONG(OP)                                         \
+    BINARY_MULTISWITCH_DOUBLE(OP)                                       \
                                                                         \
     BINARY_MULTISWITCH_CHAR(OP)                                         \
     BINARY_MULTISWITCH_USHORT(OP)                                       \
@@ -339,9 +414,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
   /* Clean up. */                                                       \
   if(flags & GAL_DATA_ARITH_FREE)                                       \
     {                                                                   \
-      if(o==l) gal_data_free(r);                                        \
-      else if(o==r) gal_data_free(l);                                   \
-      else {gal_data_free(l); gal_data_free(r);}                        \
+      if     (o==l)            gal_data_free(r);                        \
+      else if(o==r)            gal_data_free(l);                        \
+      else                   { gal_data_free(l); gal_data_free(r); }    \
     }                                                                   \
 }
 
diff --git a/lib/data-arithmetic.c b/lib/data-arithmetic.c
index 8c08a71..77acfa2 100644
--- a/lib/data-arithmetic.c
+++ b/lib/data-arithmetic.c
@@ -24,5 +24,68 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <errno.h>
 #include <error.h>
+#include <stdarg.h>
+#include <stdlib.h>
 
 #include <gnuastro/data.h>
+
+#include <data-arithmetic-binary.h>
+
+
+
+
+
+gal_data_t *
+gal_data_arithmetic(int operator, unsigned char flags, ...)
+{
+  va_list va;
+  int out_type;
+  size_t out_size;
+  gal_data_t *o=NULL;
+
+  /* Prepare the variable arguments (starting after the flags argument). */
+  va_start(va, flags);
+
+  /* Depending on the operator do the job: */
+  switch(operator)
+    {
+    case GAL_DATA_OPERATOR_PLUS:     BINARY_INTERNAL(+, 0); break;
+    case GAL_DATA_OPERATOR_MINUS:    BINARY_INTERNAL(-,  0); break;
+    case GAL_DATA_OPERATOR_MULTIPLY: BINARY_INTERNAL(*,  0); break;
+    case GAL_DATA_OPERATOR_DIVIDE:   BINARY_INTERNAL(/,  0); break;
+
+    case GAL_DATA_OPERATOR_LT:  BINARY_INTERNAL(<,  GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_LE:  BINARY_INTERNAL(<=, GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_GT:  BINARY_INTERNAL(>,  GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_GE:  BINARY_INTERNAL(>=, GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_EQ:  BINARY_INTERNAL(==, GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_NE:  BINARY_INTERNAL(!=, GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_AND: BINARY_INTERNAL(&&, GAL_DATA_TYPE_UCHAR); 
break;
+    case GAL_DATA_OPERATOR_OR:  BINARY_INTERNAL(||, GAL_DATA_TYPE_UCHAR); 
break;
+
+#if 0
+  else if(!strcmp(operator, "abs"))       takeabs(p);
+  else if(!strcmp(operator, "pow"))       topower(p, NULL);
+  else if(!strcmp(operator, "sqrt"))      takesqrt(p);
+  else if(!strcmp(operator, "log"))       takelog(p);
+  else if(!strcmp(operator, "log10"))     takelog10(p);
+  else if(!strcmp(operator, "minvalue"))  findmin(p);
+  else if(!strcmp(operator, "maxvalue"))  findmax(p);
+  else if(!strcmp(operator, "min")
+          || !strcmp(operator, "max")
+          || !strcmp(operator, "average")
+          || !strcmp(operator, "median")) alloppixs(p, operator);
+  else if(!strcmp(operator, "not"))       notfunc(p);
+  else if(!strcmp(operator, "isblank"))   opisblank(p);
+  else if(!strcmp(operator, "where"))     where(p);
+#endif
+
+    default:
+      error(EXIT_FAILURE, 0, "the argument \"%d\" could not be "
+            "interpretted as an operator", operator);
+    }
+
+  /* End the variable argument structure and return. */
+  va_end(va);
+  return o;
+}
diff --git a/lib/data-arithmetic.h b/lib/data-arithmetic.h
index e7b35cd..821a559 100644
--- a/lib/data-arithmetic.h
+++ b/lib/data-arithmetic.h
@@ -5,7 +5,7 @@ This is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
+Copyright (C) 2015, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -20,333 +20,12 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef __GAL_ARITHMETIC_H__
-#define __GAL_ARITHMETIC_H__
-
-
-
-
-#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", o->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", r->type);                \
-    }
-
-
-
-
-
-/* Prepare the inputs and output for binary operations and do the job.*/
-#define BINARY_INTERNAL(OP, OUT_TYPE) {                                 \
-                                                                        \
-  /* Read the variable arguments. */                                    \
-  gal_data_t *l, *r;                                                    \
-  l = va_arg(va, gal_data_t *);                                         \
-  r = va_arg(va, gal_data_t *);                                         \
-                                                                        \
-                                                                        \
-  /* Simple sanity check on the input sizes */                          \
-  if( !( (flags & GAL_DATA_ARITH_NUMOK) && (l->size==1 || r->size==1))  \
-      && gal_data_dsize_is_different(l, r) )                            \
-    error(EXIT_FAILURE, 0, "The datasets don't have the same "          \
-          "dimension/size");                                            \
-                                                                        \
-                                                                        \
-  /* Set the output type and size. */                                   \
-  out_type = OUT_TYPE ? OUT_TYPE : gal_data_out_type(l, r);             \
-  out_size = l->size > r->size ? l->size : r->size;                     \
-                                                                        \
-                                                                        \
-  /* If we want inplace output, set the output pointer to one input. */ \
-  /* Note that the output type can be different from both inputs.    */ \
-  if(flags & GAL_DATA_ARITH_INPLACE)                                    \
-    {                                                                   \
-      if(l->type==out_type && out_size==l->size)        o = l;          \
-      else if(r->type==out_type && out_size==r->size)   o = r;          \
-    }                                                                   \
-                                                                        \
-                                                                        \
-  /* If the output pointer was not set for any reason, allocate it. */  \
-  /* For `mmapsize', note that since its `size_t', it will always be */ \
-  /* Positive. The `-1' that is recommended to give when you want the */\
-  /* value in RAM is actually the largest possible memory location. */  \
-  /* So we just have to choose the smaller minmapsize of the two to */  \
-  /* decide if the output array should be in RAM or not. */             \
-  if(o==NULL)                                                           \
-    o = gal_data_alloc(NULL, out_type,                                  \
-                       l->size>1 ? l->ndim  : r->ndim,                  \
-                       l->size>1 ? l->dsize : r->dsize,                 \
-                       0, ( l->minmapsize<r->minmapsize                 \
-                            ? l->minmapsize : r->minmapsize) );         \
-                                                                        \
-                                                                        \
-  /* Do the operations based on the different types. */                 \
-  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", l->type);              \
-    }                                                                   \
-                                                                        \
-  /* Clean up. */                                                       \
-  if(flags & GAL_DATA_ARITH_FREE)                                       \
-    {                                                                   \
-      if(o==l) gal_data_free(r);                                        \
-      else if(o==r) gal_data_free(l);                                   \
-      else {gal_data_free(l); gal_data_free(r);}                        \
-    }                                                                   \
-}
-
+#ifndef __GAL_DATA_ARITHMETIC_H__
+#define __GAL_DATA_ARITHMETIC_H__
 
 
+gal_data_t *
+gal_data_arithmetic(int operator, unsigned char flags, ...);
 
 
 #endif
diff --git a/lib/data-changetype.c b/lib/data-changetype.c
deleted file mode 100644
index 81ef3de..0000000
--- a/lib/data-changetype.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*********************************************************************
-changetype -- Changing the array of one data type to another.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
-
-Gnuastro is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#include <config.h>
-
-#include <errno.h>
-#include <error.h>
-
-#include <gnuastro/data.h>
-
-#include <data-changetype.h>
-
-
-
-
-
-
-
-
-
-
-#define BASIC_DEFINITIONS                                          \
-  unsigned char  *iuc=in->array, *iiuc=in->array;                  \
-  char           *ic=in->array,  *iic=in->array;                   \
-  unsigned short *ius=in->array, *iius=in->array;                  \
-  short          *is=in->array,  *iis=in->array;                   \
-  unsigned int   *iui=in->array, *iiui=in->array;                  \
-  int            *ii=in->array,  *iii=in->array;                   \
-  unsigned long  *iul=in->array, *iiul=in->array;                  \
-  long           *il=in->array,  *iil=in->array;                   \
-  LONGLONG       *iL=in->array,  *iiL=in->array;                   \
-  float          *iif=in->array;                                   \
-  double         *id=in->array;
-
-
-
-
-
-#define IN_INTEGER                                                 \
-    case GAL_DATA_TYPE_UCHAR:                                      \
-      do *o=*iuc++; while(++o<of);                                 \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iiuc++ == GAL_DATA_BLANK_UCHAR ? blank : *ob;  \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_CHAR:                                       \
-      do *o=*ic++; while(++o<of);                                  \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iic++ == GAL_DATA_BLANK_CHAR ? blank : *ob;    \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_USHORT:                                     \
-      do *o=*ius++; while(++o<of);                                 \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iius++ == GAL_DATA_BLANK_USHORT ? blank : *ob; \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_SHORT:                                      \
-      do *o=*is++; while(++o<of);                                  \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iis++ == GAL_DATA_BLANK_SHORT ? blank : *ob;   \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_UINT:                                       \
-      do *o=*iui++; while(++o<of);                                 \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iiui++ == GAL_DATA_BLANK_UINT ? blank : *ob;   \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_INT:                                        \
-      do *o=*ii++; while(++o<of);                                  \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iii++ == GAL_DATA_BLANK_INT ? blank : *ob;     \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_ULONG:                                      \
-      do *o=*iul++; while(++o<of);                                 \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iiul++ == GAL_DATA_BLANK_ULONG ? blank : *ob;  \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_LONG:                                       \
-      do *o=*il++; while(++o<of);                                  \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iil++ == GAL_DATA_BLANK_LONG ? blank : *ob;    \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_LONGLONG:                                   \
-      do *o=*iL++; while(++o<of);                                  \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = *iiL++==GAL_DATA_BLANK_LONGLONG ? blank : *ob;  \
-          while(++ob<of); }                                        \
-      return;
-
-
-
-
-
-#define OUT_INT_IN_FLOAT                                           \
-    case GAL_DATA_TYPE_FLOAT:                                      \
-      do *o=roundf(*iif++); while(++o<of);                         \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = isnan(*iiif++) ? GAL_DATA_BLANK_UCHAR : *ob;    \
-          while(++ob<of); }                                        \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_DOUBLE:                                     \
-      do *o=round(*id++); while(++o<of);                           \
-      if(in->anyblank && in->type!=out->type)                      \
-        { do *ob = isnan(*iid++) ? GAL_DATA_BLANK_UCHAR : *ob;     \
-          while(++ob<of); }                                        \
-      return;
-
-
-
-
-
-#define OUT_FLOAT_IN_FLOAT                                         \
-    case GAL_DATA_TYPE_FLOAT:                                      \
-      do *o=*iif++; while(++o<of);                                 \
-      return;                                                      \
-                                                                   \
-    case GAL_DATA_TYPE_DOUBLE:                                     \
-      do *o=*id++; while(++o<of);                                  \
-      return;
-
-
-
-
-
-#define DEFAULT_PRINT_ERROR                                        \
-    case GAL_DATA_TYPE_STRING:                                     \
-      error(EXIT_FAILURE, 0, "type conversion can't be done on "   \
-            "string arrays.");                                     \
-                                                                   \
-    default:                                                       \
-      error(EXIT_FAILURE, 0, "type %d was not recognized in "      \
-            "`change_type_out_is_%s' (data.c)", in->type, tforerr);
-
-
-
-
-
-#define CHANGE_OUT_IS_INTEGER                                      \
-  BASIC_DEFINITIONS;                                               \
-  float *iiif=in->array;                                           \
-  double *iid=in->array;                                           \
-                                                                   \
-  switch(in->type)                                                 \
-    {                                                              \
-      IN_INTEGER;                                                  \
-                                                                   \
-      OUT_INT_IN_FLOAT;                                            \
-                                                                   \
-      DEFAULT_PRINT_ERROR;                                         \
-    }
-
-
-
-
-
-#define CHANGE_OUT_IS_FLOATING                                     \
-  BASIC_DEFINITIONS;                                               \
-                                                                   \
-  switch(in->type)                                                 \
-    {                                                              \
-      IN_INTEGER;                                                  \
-                                                                   \
-      OUT_FLOAT_IN_FLOAT;                                          \
-                                                                   \
-      DEFAULT_PRINT_ERROR;                                         \
-    }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void
-gal_changetype_out_is_uchar(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="uchar";
-  unsigned char *o = out->array, *ob = out->array;
-  unsigned char blank=GAL_DATA_BLANK_UCHAR, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_char(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="char";
-  char *o = out->array, *ob = out->array;
-  char blank=GAL_DATA_BLANK_CHAR, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-void
-gal_changetype_out_is_ushort(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="ushort";
-  unsigned short *o = out->array, *ob = out->array;
-  unsigned short blank=GAL_DATA_BLANK_USHORT, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_short(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="short";
-  short *o = out->array, *ob = out->array;
-  short blank=GAL_DATA_BLANK_SHORT, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-void
-gal_changetype_out_is_uint(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="uint";
-  unsigned int *o = out->array, *ob = out->array;
-  unsigned int blank=GAL_DATA_BLANK_UINT, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_int(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="int";
-  int *o = out->array, *ob = out->array;
-  int blank=GAL_DATA_BLANK_INT, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_ulong(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="ulong";
-  unsigned long *o = out->array, *ob = out->array;
-  unsigned long blank=GAL_DATA_BLANK_LONG, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_long(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="long";
-  long *o = out->array, *ob = out->array;
-  long blank=GAL_DATA_BLANK_LONG, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_longlong(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="longlong";
-  LONGLONG *o = out->array, *ob = out->array;
-  LONGLONG blank=GAL_DATA_BLANK_LONGLONG, *of = o + out->size;
-
-  CHANGE_OUT_IS_INTEGER;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_float(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="float";
-  float *o = out->array, *ob = out->array;
-  float blank=GAL_DATA_BLANK_FLOAT, *of = o + out->size;
-
-  CHANGE_OUT_IS_FLOATING;
-}
-
-
-
-
-
-void
-gal_changetype_out_is_double(gal_data_t *in, gal_data_t *out)
-{
-  char *tforerr="double";
-  double *o = out->array, *ob = out->array;
-  double blank=GAL_DATA_BLANK_DOUBLE, *of = o + out->size;
-
-  CHANGE_OUT_IS_FLOATING;
-}
diff --git a/lib/data-changetype.h b/lib/data-changetype.h
deleted file mode 100644
index 8385fed..0000000
--- a/lib/data-changetype.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*********************************************************************
-changetype -- Changing the array of one data type to another.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
-
-Gnuastro is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation, either version 3 of the License, or (at your
-option) any later version.
-
-Gnuastro is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
-**********************************************************************/
-#ifndef __GAL_CHANGETYPE_H__
-#define __GAL_CHANGETYPE_H__
-
-void
-gal_changetype_out_is_uchar(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_char(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_ushort(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_short(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_uint(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_int(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_ulong(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_long(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_longlong(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_float(gal_data_t *in, gal_data_t *out);
-
-void
-gal_changetype_out_is_double(gal_data_t *in, gal_data_t *out);
-
-
-#endif
diff --git a/lib/data-copy.c b/lib/data-copy.c
new file mode 100644
index 0000000..2142e96
--- /dev/null
+++ b/lib/data-copy.c
@@ -0,0 +1,149 @@
+/*********************************************************************
+Arithmetic operations on data structures.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+Copyright (C) 2016, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <errno.h>
+#include <error.h>
+
+#include <gnuastro/data.h>
+
+
+
+
+
+/* Generic function for all types. */
+#define COPY_OTYPE_ITYPE_SET(otype, itype) {                            \
+    itype *ia=in->array;                                                \
+    otype *oa=out->array, *of=oa+out->size;                             \
+    do *oa=*ia++; while(++oa<of);                                       \
+  }
+
+
+
+
+
+/* Output type is set, now choose the input type. */
+#define COPY_OTYPE_SET(otype)                                           \
+  switch(in->type)                                                      \
+    {                                                                   \
+    case GAL_DATA_TYPE_UCHAR:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned char);                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_CHAR:                                            \
+      COPY_OTYPE_ITYPE_SET(otype, char);                                \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_USHORT:                                          \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned short);                      \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_SHORT:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, short);                               \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_ULONG:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, unsigned long);                       \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONG:                                            \
+      COPY_OTYPE_ITYPE_SET(otype, long);                                \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_LONGLONG:                                        \
+      COPY_OTYPE_ITYPE_SET(otype, LONGLONG);                            \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      COPY_OTYPE_ITYPE_SET(otype, float);                               \
+      break;                                                            \
+                                                                        \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      COPY_OTYPE_ITYPE_SET(otype, double);                              \
+      break;                                                            \
+                                                                        \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized for "              \
+            "for newtype in COPY_OTYPE_SET", in->type);                 \
+    }
+
+
+
+
+
+gal_data_t *
+gal_data_copy_to_new_type(gal_data_t *in, int newtype)
+{
+  gal_data_t *out;
+
+  /* Allocate space for the output type */
+  out=gal_data_alloc(NULL, newtype, in->ndim, in->dsize, in->wcs,
+                     0, in->minmapsize);
+
+  /* Fill in the output array: */
+  switch(newtype)
+    {
+    case GAL_DATA_TYPE_UCHAR:
+      COPY_OTYPE_SET(unsigned char);
+      break;
+
+    case GAL_DATA_TYPE_CHAR:
+      COPY_OTYPE_SET(char);
+      break;
+
+    case GAL_DATA_TYPE_USHORT:
+      COPY_OTYPE_SET(unsigned short);
+      break;
+
+    case GAL_DATA_TYPE_SHORT:
+      COPY_OTYPE_SET(short);
+      break;
+
+    case GAL_DATA_TYPE_ULONG:
+      COPY_OTYPE_SET(unsigned long);
+      break;
+
+    case GAL_DATA_TYPE_LONG:
+      COPY_OTYPE_SET(long);
+      break;
+
+    case GAL_DATA_TYPE_LONGLONG:
+      COPY_OTYPE_SET(LONGLONG);
+      break;
+
+    case GAL_DATA_TYPE_FLOAT:
+      COPY_OTYPE_SET(float);
+      break;
+
+    case GAL_DATA_TYPE_DOUBLE:
+      COPY_OTYPE_SET(double);
+      break;
+
+    default:
+      error(EXIT_FAILURE, 0, "type %d not recognized for "
+            "for newtype in gal_data_copy_to_new_type", newtype);
+    }
+
+  /* Return the created array */
+  return out;
+}
diff --git a/lib/data-arithmetic.c b/lib/data-copy.h
similarity index 83%
copy from lib/data-arithmetic.c
copy to lib/data-copy.h
index 8c08a71..a1e4258 100644
--- a/lib/data-arithmetic.c
+++ b/lib/data-copy.h
@@ -5,7 +5,7 @@ This is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
+Copyright (C) 2015, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -20,9 +20,10 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#include <config.h>
+#ifndef __GAL_DATA_COPY_H__
+#define __GAL_DATA_COPY_H__
 
-#include <errno.h>
-#include <error.h>
+gal_data_t *
+gal_data_copy_to_new_type(gal_data_t *in, int newtype);
 
-#include <gnuastro/data.h>
+#endif
diff --git a/lib/data.c b/lib/data.c
index d8b36c7..155c93c 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -27,7 +27,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <fcntl.h>
 #include <float.h>
 #include <ctype.h>
-#include <stdarg.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -37,7 +36,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/data.h>
 
 #include <checkset.h>
-#include <data-changetype.h>
+#include <data-copy.h>
 #include <data-arithmetic.h>
 
 
@@ -345,7 +344,7 @@ gal_data_mmap(gal_data_t *data)
    (largest possible size_t value), in this way, no file will be larger. */
 gal_data_t *
 gal_data_alloc(void *array, int type, size_t ndim, long *dsize,
-               int clear, size_t minmapsize)
+               struct wcsprm *wcs, int clear, size_t minmapsize)
 {
   size_t i;
   gal_data_t *out;
@@ -359,15 +358,24 @@ gal_data_alloc(void *array, int type, size_t ndim, long 
*dsize,
           sizeof *out);
 
 
-  /* Set the basic information we know so far */
+  /* Set the basic information we know so far. Note that we need a blank
+     WCS structure allocated outside of WCSLIB, then WCSLIB will copy the
+     contents. */
   out->ndim=ndim;
   out->type=type;
-  out->minmapsize=minmapsize;
-
-
-  /* Initialize the other values */
   out->anyblank=0;
-  out->wcs=NULL;
+  out->minmapsize=minmapsize;
+  if(wcs)
+    {
+      errno=0;
+      out->wcs=malloc(sizeof *out->wcs);
+      if(out->wcs==NULL)
+        error(EXIT_FAILURE, errno, "%zu bytes for out->wcs in "
+              "gal_data_alloc", sizeof *out->wcs);
+      wcscopy(1, wcs, out->wcs);
+    }
+  else
+    out->wcs=NULL;
 
 
   /* Allocate space for the dsize array: */
@@ -378,8 +386,7 @@ gal_data_alloc(void *array, int type, size_t ndim, long 
*dsize,
           ndim*sizeof *out->dsize);
 
 
-
-  /* Fill in the dsize values: */
+  /* Fill in the `dsize' array and in the meantime set `size': */
   out->size=1;
   for(i=0;i<ndim;++i)
     {
@@ -883,86 +890,6 @@ gal_data_copy(gal_data_t *in)
 
 
 
-gal_data_t *
-gal_data_copy_to_new_type(gal_data_t *in, int newtype)
-{
-  gal_data_t *out;
-
-  /* Allocate space for the output type */
-  out=gal_data_alloc(NULL, newtype, in->ndim, in->dsize, 0, in->minmapsize);
-
-  /* Copy the WCS structure, we need to have a blank WCS structure
-     allocated outside of WCSLIB, then copy the contents. */
-  if(in->wcs)
-    {
-      errno=0;
-      out->wcs=malloc(sizeof *out->wcs);
-      if(out->wcs==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for out->wcs in "
-              "gal_data_copy_to_new_type", sizeof *out->wcs);
-      wcscopy(1, in->wcs, out->wcs);
-    }
-
-  /* Fill in the output data array while doing the conversion */
-  switch(newtype)
-    {
-    case GAL_DATA_TYPE_UCHAR:
-      gal_changetype_out_is_uchar(in, out);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-      gal_changetype_out_is_char(in, out);
-      break;
-
-    case GAL_DATA_TYPE_USHORT:
-      gal_changetype_out_is_ushort(in, out);
-      break;
-
-    case GAL_DATA_TYPE_SHORT:
-      gal_changetype_out_is_short(in, out);
-      break;
-
-    case GAL_DATA_TYPE_UINT:
-      gal_changetype_out_is_uint(in, out);
-      break;
-
-    case GAL_DATA_TYPE_INT:
-      gal_changetype_out_is_int(in, out);
-      break;
-
-    case GAL_DATA_TYPE_ULONG:
-      gal_changetype_out_is_ulong(in, out);
-      break;
-
-    case GAL_DATA_TYPE_LONG:
-      gal_changetype_out_is_long(in, out);
-      break;
-
-    case GAL_DATA_TYPE_LONGLONG:
-      gal_changetype_out_is_longlong(in, out);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT:
-      gal_changetype_out_is_float(in, out);
-      break;
-
-    case GAL_DATA_TYPE_DOUBLE:
-      gal_changetype_out_is_double(in, out);
-      break;
-
-    default:
-      error(EXIT_FAILURE, 0, "type %d not recognized in "
-            "gal_data_copy_to_new_type", newtype);
-    }
-
-  /* Return the created array */
-  return out;
-}
-
-
-
-
-
 int
 gal_data_out_type(gal_data_t *first, gal_data_t *second)
 {
@@ -1115,82 +1042,5 @@ gal_data_string_to_number(char *string)
 
   /* Return the pointer to the data structure. */
   numarr=gal_data_alloc_number(type, ptr);
-  return gal_data_alloc(numarr, type, 1, dsize, 0, -1);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*************************************************************
- **************           Arithmetic           ***************
- *************************************************************/
-gal_data_t *
-gal_data_arithmetic(int operator, unsigned char flags, ...)
-{
-  va_list va;
-  int out_type;
-  size_t out_size;
-  gal_data_t *o=NULL;
-
-  /* Prepare the variable arguments (starting after the flags argument). */
-  va_start(va, flags);
-
-  /* Depending on the operator do the job: */
-  switch(operator)
-    {
-    case GAL_DATA_OPERATOR_PLUS:     BINARY_INTERNAL(+, 0); break;
-    case GAL_DATA_OPERATOR_MINUS:    BINARY_INTERNAL(-,  0); break;
-    case GAL_DATA_OPERATOR_MULTIPLY: BINARY_INTERNAL(*,  0); break;
-    case GAL_DATA_OPERATOR_DIVIDE:   BINARY_INTERNAL(/,  0); break;
-
-    case GAL_DATA_OPERATOR_LT:  BINARY_INTERNAL(<,  GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_LE:  BINARY_INTERNAL(<=, GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_GT:  BINARY_INTERNAL(>,  GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_GE:  BINARY_INTERNAL(>=, GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_EQ:  BINARY_INTERNAL(==, GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_NE:  BINARY_INTERNAL(!=, GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_AND: BINARY_INTERNAL(&&, GAL_DATA_TYPE_UCHAR); 
break;
-    case GAL_DATA_OPERATOR_OR:  BINARY_INTERNAL(||, GAL_DATA_TYPE_UCHAR); 
break;
-
-#if 0
-  else if(!strcmp(operator, "abs"))       takeabs(p);
-  else if(!strcmp(operator, "pow"))       topower(p, NULL);
-  else if(!strcmp(operator, "sqrt"))      takesqrt(p);
-  else if(!strcmp(operator, "log"))       takelog(p);
-  else if(!strcmp(operator, "log10"))     takelog10(p);
-  else if(!strcmp(operator, "minvalue"))  findmin(p);
-  else if(!strcmp(operator, "maxvalue"))  findmax(p);
-  else if(!strcmp(operator, "min")
-          || !strcmp(operator, "max")
-          || !strcmp(operator, "average")
-          || !strcmp(operator, "median")) alloppixs(p, operator);
-  else if(!strcmp(operator, "not"))       notfunc(p);
-  else if(!strcmp(operator, "isblank"))   opisblank(p);
-  else if(!strcmp(operator, "where"))     where(p);
-#endif
-
-    default:
-      error(EXIT_FAILURE, 0, "the argument \"%d\" could not be "
-            "interpretted as an operator", operator);
-    }
-
-  /* End the variable argument structure and return. */
-  va_end(va);
-  return o;
+  return gal_data_alloc(numarr, type, 1, dsize, NULL, 0, -1);
 }
diff --git a/lib/fits.c b/lib/fits.c
index dfd8836..00cbdbd 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1237,7 +1237,7 @@ gal_fits_read_img_hdu(char *filename, char *hdu, char 
*maskname,
 
 
   /* Allocate the space for the array and for the blank values. */
-  img=gal_data_alloc(NULL, type, (long)ndim, dsize, 0, minmapsize);
+  img=gal_data_alloc(NULL, type, (long)ndim, dsize, NULL, 0, minmapsize);
   blank=gal_data_alloc_blank(type);
   free(dsize);
 
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 600bbc7..8545033 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -68,6 +68,12 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 /* Macros: */
 
+/* If this macro is 1, the only native type for arithmetic will be
+   float. Having the four different types set as native can greatly
+   lengthen the compilation time and slow-down the
+   debugging/developement. */
+#define GAL_DATA_ARITH_ONLY_FLOAT_FOR_FAST_DEBUG 0
+
 /* The maximum dimensionality of datasets. */
 #define GAL_DATA_MAXDIM    999
 
@@ -217,7 +223,7 @@ gal_data_calloc_array(int type, size_t size);
 
 gal_data_t *
 gal_data_alloc(void *array, int type, size_t ndim, long *dsize,
-               int clear, size_t minmapsize);
+               struct wcsprm *wcs, int clear, size_t minmapsize);
 
 void
 gal_data_free(gal_data_t *data);



reply via email to

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