gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e0e8679 017/125: Removed `anyblank' from datas


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e0e8679 017/125: Removed `anyblank' from datastructure, several new operators
Date: Sun, 23 Apr 2017 22:36:27 -0400 (EDT)

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

    Removed `anyblank' from datastructure, several new operators
    
    The `data-arithmetic-unary.[ch]' library files were changed to
    `data-arithmetic-other.[ch]', since it will host functions for a more wider
    class of operators. This was mainly prompted by the new
    `data_arithmetic_unary_function_f' and `data-arithmetic_binary_function_f'
    functions.
    
    The `gal_data_string_to_number' can now be told to only read the number as
    a floating point by adding an `f' to the end of the string.
    
    `gal_data_operator_string' is a new function to return the string
    equivalent of an operator, mainly useful for error messages.
---
 bin/arithmetic/arithmetic.c                        |  30 --
 lib/Makefile.am                                    |   4 +-
 lib/data-arithmetic-onlyint.c                      | 108 ++---
 lib/data-arithmetic-other.c                        | 465 +++++++++++++++++++++
 ...-arithmetic-unary.h => data-arithmetic-other.h} |   8 +
 lib/data-arithmetic-unary.c                        | 150 -------
 lib/data.c                                         | 138 ++++--
 lib/fits.c                                         |  23 +-
 lib/gnuastro/data.h                                |  71 ++--
 lib/mesh.c                                         |   3 +-
 10 files changed, 694 insertions(+), 306 deletions(-)

diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index fea2328..8c6569c 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -228,36 +228,6 @@ reversepolish(struct imgarithparams *p)
         }
     }
 
-
-
-
-#if 0
-
-          else if(!strcmp(token->v, "abs"))       takeabs(p);
-          else if(!strcmp(token->v, "pow"))       topower(p, NULL);
-          else if(!strcmp(token->v, "sqrt"))      takesqrt(p);
-          else if(!strcmp(token->v, "log"))       takelog(p);
-          else if(!strcmp(token->v, "log10"))     takelog10(p);
-          else if(!strcmp(token->v, "minvalue"))  findmin(p);
-          else if(!strcmp(token->v, "maxvalue"))  findmax(p);
-          else if(!strcmp(token->v, "min")
-                  || !strcmp(token->v, "max")
-                  || !strcmp(token->v, "average")
-                  || !strcmp(token->v, "median")) alloppixs(p, token->v);
-          else if(!strcmp(token->v, "lt")
-                  || !strcmp(token->v, "le")
-                  || !strcmp(token->v, "gt")
-                  || !strcmp(token->v, "ge")
-                  || !strcmp(token->v, "eq")
-                  || !strcmp(token->v, "neq"))    conditionals(p, token->v);
-          else if(!strcmp(token->v, "and")
-                  || !strcmp(token->v, "or"))     andor(p, token->v);
-          else if(!strcmp(token->v, "not"))       notfunc(p);
-          else if(!strcmp(token->v, "isblank"))   opisblank(p);
-          else if(!strcmp(token->v, "where"))     where(p);
-#endif
-
-
   /* If there is more than one node in the operands stack then the user has
      given too many operands which is an error. */
   if(p->operands->next!=NULL)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 09f2c9c..0284569 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -42,7 +42,7 @@ 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-binary.c data-arithmetic-onlyint.c                    \
-  data-arithmetic-unary.c data-copy.c fits.c git.c linkedlist.c mesh.c  \
+  data-arithmetic-other.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
 
@@ -71,7 +71,7 @@ pkginclude_HEADERS = gnuastro/config.h $(headersdir)/array.h  
          \
 # will not distributed, so we need to explicitly tell Automake to
 # distribute them here.
 EXTRA_DIST = gnuastro.pc.in data-arithmetic.h data-arithmetic-binary.h \
-  data-arithmetic-onlyint.h data-arithmetic-unary.h data-copy.h         \
+  data-arithmetic-onlyint.h data-arithmetic-other.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
 
diff --git a/lib/data-arithmetic-onlyint.c b/lib/data-arithmetic-onlyint.c
index 9b247d0..9f617a9 100644
--- a/lib/data-arithmetic-onlyint.c
+++ b/lib/data-arithmetic-onlyint.c
@@ -36,17 +36,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /*************      Possibly set onlyint types to convert    *************/
 /************************************************************************/
 #if GAL_CONFIG_BIN_OP_UCHAR == 1
-#define ONLYINT_LEFT_RIGHT_DONE_UCHAR(LT, RT, OP)                        \
+#define ONLYINT_LEFT_RIGHT_DONE_UCHAR(LT, RT, OP)                       \
     case GAL_DATA_TYPE_UCHAR:                                           \
-      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned char, OP);              \
+      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned char, OP);             \
       break;
-#define ONLYINT_LEFT_DONE_UCHAR(LT, OP)                                  \
+#define ONLYINT_LEFT_DONE_UCHAR(LT, OP)                                 \
     case GAL_DATA_TYPE_UCHAR:                                           \
-      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned char, OP);                    \
+      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned char, OP);                   \
       break;
-#define ONLYINT_MULTISWITCH_UCHAR(OP)                                    \
+#define ONLYINT_MULTISWITCH_UCHAR(OP)                                   \
     case GAL_DATA_TYPE_UCHAR:                                           \
-      ONLYINT_LEFT_DONE(unsigned char, OP);                              \
+      ONLYINT_LEFT_DONE(unsigned char, OP);                             \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_UCHAR(LT, RT, OP)
@@ -59,17 +59,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_CHAR == 1
-#define ONLYINT_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                         \
+#define ONLYINT_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)                        \
   case GAL_DATA_TYPE_CHAR:                                              \
-    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, char, OP);                         \
+    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, char, OP);                        \
     break;
-#define ONLYINT_LEFT_DONE_CHAR(LT, OP)                                   \
+#define ONLYINT_LEFT_DONE_CHAR(LT, OP)                                  \
     case GAL_DATA_TYPE_CHAR:                                            \
-      ONLYINT_LEFT_RIGHT_DONE(LT, char, OP);                             \
+      ONLYINT_LEFT_RIGHT_DONE(LT, char, OP);                            \
       break;
-#define ONLYINT_MULTISWITCH_CHAR(OP)                                     \
+#define ONLYINT_MULTISWITCH_CHAR(OP)                                    \
     case GAL_DATA_TYPE_CHAR:                                            \
-      ONLYINT_LEFT_DONE(char, OP);                                       \
+      ONLYINT_LEFT_DONE(char, OP);                                      \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_CHAR(LT, RT, OP)
@@ -82,17 +82,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_USHORT == 1
-#define ONLYINT_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)                       \
+#define ONLYINT_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)                      \
   case GAL_DATA_TYPE_USHORT:                                            \
-    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned short, OP);               \
+    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned short, OP);              \
     break;
-#define ONLYINT_LEFT_DONE_USHORT(LT, OP)                                 \
+#define ONLYINT_LEFT_DONE_USHORT(LT, OP)                                \
     case GAL_DATA_TYPE_USHORT:                                          \
-      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned short, OP);                   \
+      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned short, OP);                  \
       break;
-#define ONLYINT_MULTISWITCH_USHORT(OP)                                   \
+#define ONLYINT_MULTISWITCH_USHORT(OP)                                  \
     case GAL_DATA_TYPE_USHORT:                                          \
-      ONLYINT_LEFT_DONE(unsigned short, OP);                             \
+      ONLYINT_LEFT_DONE(unsigned short, OP);                            \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_USHORT(LT, RT, OP)
@@ -105,17 +105,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_SHORT == 1
-#define ONLYINT_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                        \
+#define ONLYINT_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)                       \
   case GAL_DATA_TYPE_SHORT:                                             \
-    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, short, OP);                        \
+    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, short, OP);                       \
     break;
-#define ONLYINT_LEFT_DONE_SHORT(LT, OP)                                  \
+#define ONLYINT_LEFT_DONE_SHORT(LT, OP)                                 \
     case GAL_DATA_TYPE_SHORT:                                           \
-      ONLYINT_LEFT_RIGHT_DONE(LT, short, OP);                            \
+      ONLYINT_LEFT_RIGHT_DONE(LT, short, OP);                           \
       break;
-#define ONLYINT_MULTISWITCH_SHORT(OP)                                    \
+#define ONLYINT_MULTISWITCH_SHORT(OP)                                   \
     case GAL_DATA_TYPE_SHORT:                                           \
-      ONLYINT_LEFT_DONE(short, OP);                                      \
+      ONLYINT_LEFT_DONE(short, OP);                                     \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_SHORT(LT, RT, OP)
@@ -128,17 +128,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_UINT == 1
-#define ONLYINT_LEFT_RIGHT_DONE_UINT(LT, RT, OP)                         \
+#define ONLYINT_LEFT_RIGHT_DONE_UINT(LT, RT, OP)                        \
   case GAL_DATA_TYPE_UINT:                                              \
-    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned int, OP);                 \
+    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned int, OP);                \
     break;
-#define ONLYINT_LEFT_DONE_UINT(LT, OP)                                   \
+#define ONLYINT_LEFT_DONE_UINT(LT, OP)                                  \
     case GAL_DATA_TYPE_UINT:                                            \
-      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned int, OP);                     \
+      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned int, OP);                    \
       break;
-#define ONLYINT_MULTISWITCH_UINT(OP)                                     \
+#define ONLYINT_MULTISWITCH_UINT(OP)                                    \
     case GAL_DATA_TYPE_UINT:                                            \
-      ONLYINT_LEFT_DONE(unsigned int, OP);                               \
+      ONLYINT_LEFT_DONE(unsigned int, OP);                              \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_UINT(LT, RT, OP)
@@ -151,17 +151,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_INT == 1
-#define ONLYINT_LEFT_RIGHT_DONE_INT(LT, RT, OP)                          \
+#define ONLYINT_LEFT_RIGHT_DONE_INT(LT, RT, OP)                         \
   case GAL_DATA_TYPE_INT:                                               \
-    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, int, OP);                          \
+    ONLYINT_OPERATOR_FOR_TYPE(LT, RT, int, OP);                         \
     break;
-#define ONLYINT_LEFT_DONE_INT(LT, OP)                                    \
+#define ONLYINT_LEFT_DONE_INT(LT, OP)                                   \
     case GAL_DATA_TYPE_INT:                                             \
-      ONLYINT_LEFT_RIGHT_DONE(LT, int, OP);                              \
+      ONLYINT_LEFT_RIGHT_DONE(LT, int, OP);                             \
       break;
-#define ONLYINT_MULTISWITCH_INT(OP)                                      \
+#define ONLYINT_MULTISWITCH_INT(OP)                                     \
     case GAL_DATA_TYPE_INT:                                             \
-      ONLYINT_LEFT_DONE(int, OP);                                        \
+      ONLYINT_LEFT_DONE(int, OP);                                       \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_INT(LT, RT, OP)
@@ -174,17 +174,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_ULONG == 1
-#define ONLYINT_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)                        \
+#define ONLYINT_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)                       \
     case GAL_DATA_TYPE_ULONG:                                           \
-      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned long, OP);              \
+      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, unsigned long, OP);             \
       break;
-#define ONLYINT_LEFT_DONE_ULONG(LT, OP)                                  \
+#define ONLYINT_LEFT_DONE_ULONG(LT, OP)                                 \
     case GAL_DATA_TYPE_ULONG:                                           \
-      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned long, OP);                    \
+      ONLYINT_LEFT_RIGHT_DONE(LT, unsigned long, OP);                   \
       break;
-#define ONLYINT_MULTISWITCH_ULONG(OP)                                    \
+#define ONLYINT_MULTISWITCH_ULONG(OP)                                   \
     case GAL_DATA_TYPE_ULONG:                                           \
-      ONLYINT_LEFT_DONE(unsigned long, OP);                              \
+      ONLYINT_LEFT_DONE(unsigned long, OP);                             \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_ULONG(LT, RT, OP)
@@ -197,17 +197,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_LONG == 1
-#define ONLYINT_LEFT_RIGHT_DONE_LONG(LT, RT, OP)                         \
+#define ONLYINT_LEFT_RIGHT_DONE_LONG(LT, RT, OP)                        \
     case GAL_DATA_TYPE_LONG:                                            \
-      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, long, OP);                       \
+      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, long, OP);                      \
       break;
-#define ONLYINT_LEFT_DONE_LONG(LT, OP)                                   \
+#define ONLYINT_LEFT_DONE_LONG(LT, OP)                                  \
     case GAL_DATA_TYPE_LONG:                                            \
-      ONLYINT_LEFT_RIGHT_DONE(LT, long, OP);                             \
+      ONLYINT_LEFT_RIGHT_DONE(LT, long, OP);                            \
       break;
-#define ONLYINT_MULTISWITCH_LONG(OP)                                     \
+#define ONLYINT_MULTISWITCH_LONG(OP)                                    \
     case GAL_DATA_TYPE_LONG:                                            \
-      ONLYINT_LEFT_DONE(long, OP);                                       \
+      ONLYINT_LEFT_DONE(long, OP);                                      \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_LONG(LT, RT, OP)
@@ -220,17 +220,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 #if GAL_CONFIG_BIN_OP_LONGLONG == 1
-#define ONLYINT_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)                     \
+#define ONLYINT_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)                    \
     case GAL_DATA_TYPE_LONGLONG:                                        \
-      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, LONGLONG, OP);                   \
+      ONLYINT_OPERATOR_FOR_TYPE(LT, RT, LONGLONG, OP);                  \
       break;
-#define ONLYINT_LEFT_DONE_LONGLONG(LT, OP)                               \
+#define ONLYINT_LEFT_DONE_LONGLONG(LT, OP)                              \
     case GAL_DATA_TYPE_LONGLONG:                                        \
-      ONLYINT_LEFT_RIGHT_DONE(LT, long long, OP);                        \
+      ONLYINT_LEFT_RIGHT_DONE(LT, long long, OP);                       \
       break;
-#define ONLYINT_MULTISWITCH_LONGLONG(OP)                                 \
+#define ONLYINT_MULTISWITCH_LONGLONG(OP)                                \
     case GAL_DATA_TYPE_LONGLONG:                                        \
-      ONLYINT_LEFT_DONE(LONGLONG, OP);                                   \
+      ONLYINT_LEFT_DONE(LONGLONG, OP);                                  \
       break;
 #else
 #define ONLYINT_LEFT_RIGHT_DONE_LONGLONG(LT, RT, OP)
diff --git a/lib/data-arithmetic-other.c b/lib/data-arithmetic-other.c
new file mode 100644
index 0000000..268a37a
--- /dev/null
+++ b/lib/data-arithmetic-other.c
@@ -0,0 +1,465 @@
+/*********************************************************************
+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 <math.h>
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+
+#include <gnuastro/data.h>
+
+
+
+
+
+
+
+
+
+/***********************************************************************/
+/***************        Unary functions/operators         **************/
+/***********************************************************************/
+/* Change input data structure type. */
+gal_data_t *
+data_arithmetic_change_type(gal_data_t *data, int operator,
+                            unsigned char flags)
+{
+  int type=0;
+  gal_data_t *out;
+
+  /* Set the output type. */
+  switch(operator)
+    {
+    case GAL_DATA_OPERATOR_TO_UCHAR:    type=GAL_DATA_TYPE_UCHAR;    break;
+    case GAL_DATA_OPERATOR_TO_CHAR:     type=GAL_DATA_TYPE_UCHAR;    break;
+    case GAL_DATA_OPERATOR_TO_USHORT:   type=GAL_DATA_TYPE_USHORT;   break;
+    case GAL_DATA_OPERATOR_TO_SHORT:    type=GAL_DATA_TYPE_SHORT;    break;
+    case GAL_DATA_OPERATOR_TO_UINT:     type=GAL_DATA_TYPE_UINT;     break;
+    case GAL_DATA_OPERATOR_TO_INT:      type=GAL_DATA_TYPE_INT;      break;
+    case GAL_DATA_OPERATOR_TO_ULONG:    type=GAL_DATA_TYPE_ULONG;    break;
+    case GAL_DATA_OPERATOR_TO_LONG:     type=GAL_DATA_TYPE_LONG;     break;
+    case GAL_DATA_OPERATOR_TO_LONGLONG: type=GAL_DATA_TYPE_LONGLONG; break;
+    case GAL_DATA_OPERATOR_TO_FLOAT:    type=GAL_DATA_TYPE_FLOAT;    break;
+    case GAL_DATA_OPERATOR_TO_DOUBLE:   type=GAL_DATA_TYPE_DOUBLE;   break;
+
+    default:
+      error(EXIT_FAILURE, 0, "operator value of %d not recognized in "
+            "`data_arithmetic_change_type'", operator);
+    }
+
+  /* Copy to the new type. */
+  out=gal_data_copy_to_new_type(data, type);
+
+  /* Delete the input structure if the user asked for it. */
+  if(flags & GAL_DATA_ARITH_FREE)
+    gal_data_free(data);
+
+  /* Return */
+  return out;
+}
+
+
+
+
+
+/* Return an array of value 1 for any zero valued element and zero for any
+   non-zero valued element. */
+#define TYPE_CASE_FOR_NOT(TYPE, IN, IN_FINISH) {                        \
+    case TYPE:                                                          \
+      do *o++ = !*IN; while(++IN<IN_FINISH);                            \
+      break;                                                            \
+  }
+
+gal_data_t *
+data_arithmetic_not(gal_data_t *data, unsigned char flags)
+{
+  gal_data_t *out;
+
+  /* 'value' will only be read from one of these based on the
+     datatype. Which the caller assigned. If there is any problem, it is
+     their responsability, not this function's.*/
+  unsigned char     *uc = data->array,   *ucf = data->array + data->size, *o;
+  char               *c = data->array,    *cf = data->array + data->size;
+  unsigned short    *us = data->array,   *usf = data->array + data->size;
+  short              *s = data->array,    *sf = data->array + data->size;
+  unsigned int      *ui = data->array,   *uif = data->array + data->size;
+  int               *in = data->array,   *inf = data->array + data->size;
+  unsigned long     *ul = data->array,   *ulf = data->array + data->size;
+  long               *l = data->array,    *lf = data->array + data->size;
+  LONGLONG           *L = data->array,    *Lf = data->array + data->size;
+  float              *f = data->array,    *ff = data->array + data->size;
+  double             *d = data->array,    *df = data->array + data->size;
+
+
+  /* Allocate the output array. */
+  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, data->ndim, data->dsize,
+                     data->wcs, 0, data->minmapsize);
+  o=out->array;
+
+
+  /* Go over the pixels and set the output values. */
+  switch(data->type)
+    {
+
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UCHAR,    uc,  ucf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_CHAR,     c,   cf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LOGICAL,  c,   cf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_USHORT,   us,  usf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_SHORT,    s,   sf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UINT,     ui,  uif)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_INT,      in,  inf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_ULONG,    ul,  ulf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONG,     l,   lf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONGLONG, L,   Lf)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_FLOAT,    f,   ff)
+    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_DOUBLE,   d,   df)
+
+    case GAL_DATA_TYPE_BIT:
+      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
+            "datatype, please get in touch with us to implement it.");
+
+    default:
+      error(EXIT_FAILURE, 0, "type value (%d) not recognized "
+            "in `data_arithmetic_not'", data->type);
+    }
+
+  /* Delete the input structure if the user asked for it. */
+  if(flags & GAL_DATA_ARITH_FREE)
+    gal_data_free(data);
+
+  /* Return */
+  return out;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************************************************************/
+/***************          Checking functions              **************/
+/***********************************************************************/
+
+/* Some functions are only for a floating point operand, so if the input
+   isn't floating point, inform the user to change the type explicitly,
+   doing it implicitly/internally puts too much responsability on the
+   program. */
+static void
+check_float_input(gal_data_t *in, int operator, char *numstr)
+{
+  switch(in->type)
+    {
+    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_DOUBLE:
+      break;
+    default:
+      error(EXIT_FAILURE, 0, "the %s operator can only accept single or "
+            "double precision floating point numbers as its operand. The "
+            "%s operand has type %s. You can use the `float' or `double' "
+            "operators before this operator to explicity convert to the "
+            "desired precision floating point type. If the operand was "
+            "originally a typed number (string of characters), add an `f' "
+            "after it so it is directly read into the proper precision "
+            "floating point number (based on the number of non-zero "
+            "decimals it has)", gal_data_operator_string(operator), numstr,
+            gal_data_type_string(in->type));
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************************************************************/
+/***************             Unary functions              **************/
+/***********************************************************************/
+
+
+#define UNIFUNC_RUN_FUNCTION(IT, OP){                                   \
+    IT *ia=in->array, *oa=o->array, *of=oa + o->size;                   \
+    do *oa++ = OP(*ia++); while(oa<of);                                 \
+  }
+
+
+
+
+
+#define UNIFUNC_F_OPERATOR_DONE(OP)                                     \
+  switch(in->type)                                                      \
+    {                                                                   \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      UNIFUNC_RUN_FUNCTION(float, OP);                                  \
+      break;                                                            \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      UNIFUNC_RUN_FUNCTION(double, OP);                                 \
+      break;                                                            \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for l->type in UNIFUNC_F_OPERATOR_DONE", in->type);        \
+    }
+
+
+
+
+
+gal_data_t *
+data_arithmetic_unary_function_f(int operator, unsigned char flags,
+                                 gal_data_t *in)
+{
+  gal_data_t *o;
+
+  /* Check the input type. */
+  check_float_input(in, operator, "first");
+
+  /* If we want inplace output, set the output pointer to the input
+     pointer, for every pixel, the operation will be independent. */
+  if(flags & GAL_DATA_ARITH_INPLACE)
+    o = in;
+  else
+    o = gal_data_alloc(NULL, in->type, in->ndim, in->dsize, in->wcs,
+                       0, in->minmapsize);
+
+  /* Start setting the operator and operands. */
+  switch(operator)
+    {
+    case GAL_DATA_OPERATOR_SQRT:   UNIFUNC_F_OPERATOR_DONE( sqrt  ); break;
+    case GAL_DATA_OPERATOR_LOG:    UNIFUNC_F_OPERATOR_DONE( log   ); break;
+    case GAL_DATA_OPERATOR_LOG10:  UNIFUNC_F_OPERATOR_DONE( log10 ); break;
+    default:
+      error(EXIT_FAILURE, 0, "Operator code %d not recognized in "
+            "data_arithmetic_binary_function", operator);
+    }
+
+
+  /* Clean up. Note that if the input arrays can be freed, and any of right
+     or left arrays needed conversion, `UNIFUNC_CONVERT_TO_COMPILED_TYPE'
+     has already freed the input arrays, and we only have `r' and `l'
+     allocated in any case. Alternatively, when the inputs shouldn't be
+     freed, the only allocated spaces are the `r' and `l' arrays if their
+     types weren't compiled for binary operations, we can tell this from
+     the pointers: if they are different from the original pointers, they
+     were allocated. */
+  if( (flags & GAL_DATA_ARITH_FREE) && o!=in)
+    gal_data_free(in);
+
+  /* Return */
+  return o;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************************************************************/
+/***************            Binary functions              **************/
+/***********************************************************************/
+
+
+#define BINFUNC_RUN_FUNCTION(OT, RT, LT, OP){                           \
+    LT *la=l->array;                                                    \
+    RT *ra=r->array;                                                    \
+    OT *oa=o->array, *of=oa + o->size;                                  \
+    if(l->size==r->size) do *oa = OP(*la++, *ra++); while(++oa<of);     \
+    else if(l->size==1)  do *oa = OP(*la,   *ra++); while(++oa<of);     \
+    else                 do *oa = OP(*la++, *ra  ); while(++oa<of);     \
+  }
+
+
+
+
+
+#define BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(RT, LT, OP)                   \
+  switch(o->type)                                                       \
+    {                                                                   \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINFUNC_RUN_FUNCTION(float, RT, LT, OP);                          \
+      break;                                                            \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINFUNC_RUN_FUNCTION(double, RT, LT, OP);                         \
+      break;                                                            \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for o->type in BINFUNC_F_OPERATOR_LEFT_RIGHT_SET",         \
+            o->type);                                                   \
+    }
+
+
+
+
+
+#define BINFUNC_F_OPERATOR_LEFT_SET(LT, OP)                             \
+  switch(r->type)                                                       \
+    {                                                                   \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(float, LT, OP);                 \
+      break;                                                            \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(double, LT, OP);                \
+      break;                                                            \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for r->type in BINFUNC_F_OPERATOR_LEFT_SET", r->type);    \
+    }
+
+
+
+
+
+#define BINFUNC_F_OPERATOR_SET(OP)                                      \
+  switch(l->type)                                                       \
+    {                                                                   \
+    case GAL_DATA_TYPE_FLOAT:                                           \
+      BINFUNC_F_OPERATOR_LEFT_SET(float, OP);                           \
+      break;                                                            \
+    case GAL_DATA_TYPE_DOUBLE:                                          \
+      BINFUNC_F_OPERATOR_LEFT_SET(double, OP);                          \
+      break;                                                            \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type %d not recognized in "               \
+            "for l->type in BINFUNC_F_OPERATOR_SET", l->type);          \
+    }
+
+
+
+
+
+gal_data_t *
+data_arithmetic_binary_function_f(int operator, unsigned char flags,
+                                  gal_data_t *l, gal_data_t *r)
+{
+  int final_otype;
+  gal_data_t *o=NULL;
+  size_t out_size, minmapsize;
+
+
+  /* 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 input datasets don't have the same "
+          "dimension/size in data_arithmetic_binary_function");
+
+  /* Check for the types of the left and right operands. */
+  check_float_input(l, operator, "first");
+  check_float_input(r, operator, "second");
+
+  /* Set the output type. */
+  final_otype = gal_data_out_type(l, r);
+
+  /* Set the output sizes. */
+  minmapsize = ( l->minmapsize < r->minmapsize
+                 ? l->minmapsize : r->minmapsize );
+  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==final_otype && out_size==l->size)   o = l;
+      else if(r->type==final_otype && 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, final_otype,
+                       l->size>1 ? l->ndim  : r->ndim,
+                       l->size>1 ? l->dsize : r->dsize,
+                       l->size>1 ? l->wcs : r->wcs, 0, minmapsize );
+
+
+  /* Start setting the operator and operands. */
+  switch(operator)
+    {
+    case GAL_DATA_OPERATOR_POW:  BINFUNC_F_OPERATOR_SET( pow  ); break;
+    default:
+      error(EXIT_FAILURE, 0, "Operator code %d not recognized in "
+            "data_arithmetic_binary_function", operator);
+    }
+
+
+  /* Clean up. Note that if the input arrays can be freed, and any of right
+     or left arrays needed conversion, `BINFUNC_CONVERT_TO_COMPILED_TYPE'
+     has already freed the input arrays, and we only have `r' and `l'
+     allocated in any case. Alternatively, when the inputs shouldn't be
+     freed, the only allocated spaces are the `r' and `l' arrays if their
+     types weren't compiled for binary operations, we can tell this from
+     the pointers: if they are different from the original pointers, they
+     were allocated. */
+  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); }
+    }
+
+  /* Return */
+  return o;
+}
diff --git a/lib/data-arithmetic-unary.h b/lib/data-arithmetic-other.h
similarity index 81%
rename from lib/data-arithmetic-unary.h
rename to lib/data-arithmetic-other.h
index 847e9d2..f437e98 100644
--- a/lib/data-arithmetic-unary.h
+++ b/lib/data-arithmetic-other.h
@@ -30,5 +30,13 @@ data_arithmetic_change_type(gal_data_t *data, int operator,
 gal_data_t *
 data_arithmetic_not(gal_data_t *data, unsigned char flags);
 
+gal_data_t *
+data_arithmetic_unary_function_f(int operator, unsigned char flags,
+                                 gal_data_t *in);
+
+gal_data_t *
+data_arithmetic_binary_function_f(int operator, unsigned char flags,
+                                  gal_data_t *l, gal_data_t *r);
+
 
 #endif
diff --git a/lib/data-arithmetic-unary.c b/lib/data-arithmetic-unary.c
deleted file mode 100644
index 2f3ace2..0000000
--- a/lib/data-arithmetic-unary.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*********************************************************************
-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 <stdio.h>
-#include <errno.h>
-#include <error.h>
-#include <stdlib.h>
-
-#include <gnuastro/data.h>
-
-
-
-
-
-
-
-
-
-/* Change input data structure type. */
-gal_data_t *
-data_arithmetic_change_type(gal_data_t *data, int operator,
-                            unsigned char flags)
-{
-  int type=0;
-  gal_data_t *out;
-
-  /* Set the output type. */
-  switch(operator)
-    {
-    case GAL_DATA_OPERATOR_TO_UCHAR:    type=GAL_DATA_TYPE_UCHAR;    break;
-    case GAL_DATA_OPERATOR_TO_CHAR:     type=GAL_DATA_TYPE_UCHAR;    break;
-    case GAL_DATA_OPERATOR_TO_USHORT:   type=GAL_DATA_TYPE_USHORT;   break;
-    case GAL_DATA_OPERATOR_TO_SHORT:    type=GAL_DATA_TYPE_SHORT;    break;
-    case GAL_DATA_OPERATOR_TO_UINT:     type=GAL_DATA_TYPE_UINT;     break;
-    case GAL_DATA_OPERATOR_TO_INT:      type=GAL_DATA_TYPE_INT;      break;
-    case GAL_DATA_OPERATOR_TO_ULONG:    type=GAL_DATA_TYPE_ULONG;    break;
-    case GAL_DATA_OPERATOR_TO_LONG:     type=GAL_DATA_TYPE_LONG;     break;
-    case GAL_DATA_OPERATOR_TO_LONGLONG: type=GAL_DATA_TYPE_LONGLONG; break;
-    case GAL_DATA_OPERATOR_TO_FLOAT:    type=GAL_DATA_TYPE_FLOAT;    break;
-    case GAL_DATA_OPERATOR_TO_DOUBLE:   type=GAL_DATA_TYPE_DOUBLE;   break;
-
-    default:
-      error(EXIT_FAILURE, 0, "operator value of %d not recognized in "
-            "`data_arithmetic_change_type'", operator);
-    }
-
-  /* Copy to the new type. */
-  out=gal_data_copy_to_new_type(data, type);
-
-  /* Delete the input structure if the user asked for it. */
-  if(flags & GAL_DATA_ARITH_FREE)
-    gal_data_free(data);
-
-  /* Return */
-  return out;
-}
-
-
-
-
-
-/* Return an array of value 1 for any zero valued element and zero for any
-   non-zero valued element. */
-#define TYPE_CASE_FOR_NOT(TYPE, IN, IN_FINISH) {                        \
-    case TYPE:                                                          \
-      do *o++ = !*IN; while(++IN<IN_FINISH);                            \
-      break;                                                            \
-  }
-
-gal_data_t *
-data_arithmetic_not(gal_data_t *data, unsigned char flags)
-{
-  gal_data_t *out;
-
-  /* 'value' will only be read from one of these based on the
-     datatype. Which the caller assigned. If there is any problem, it is
-     their responsability, not this function's.*/
-  unsigned char     *uc = data->array,   *ucf = data->array + data->size, *o;
-  char               *c = data->array,    *cf = data->array + data->size;
-  unsigned short    *us = data->array,   *usf = data->array + data->size;
-  short              *s = data->array,    *sf = data->array + data->size;
-  unsigned int      *ui = data->array,   *uif = data->array + data->size;
-  int               *in = data->array,   *inf = data->array + data->size;
-  unsigned long     *ul = data->array,   *ulf = data->array + data->size;
-  long               *l = data->array,    *lf = data->array + data->size;
-  LONGLONG           *L = data->array,    *Lf = data->array + data->size;
-  float              *f = data->array,    *ff = data->array + data->size;
-  double             *d = data->array,    *df = data->array + data->size;
-
-
-  /* Allocate the output array. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, data->ndim, data->dsize,
-                     data->wcs, 0, data->minmapsize);
-  o=out->array;
-
-
-  /* Go over the pixels and set the output values. */
-  switch(data->type)
-    {
-
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UCHAR,    uc,  ucf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_CHAR,     c,   cf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LOGICAL,  c,   cf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_USHORT,   us,  usf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_SHORT,    s,   sf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UINT,     ui,  uif)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_INT,      in,  inf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_ULONG,    ul,  ulf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONG,     l,   lf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONGLONG, L,   Lf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_FLOAT,    f,   ff)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_DOUBLE,   d,   df)
-
-    case GAL_DATA_TYPE_BIT:
-      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
-            "datatype, please get in touch with us to implement it.");
-
-    default:
-      error(EXIT_FAILURE, 0, "type value (%d) not recognized "
-            "in `data_arithmetic_not'", data->type);
-    }
-
-  /* Delete the input structure if the user asked for it. */
-  if(flags & GAL_DATA_ARITH_FREE)
-    gal_data_free(data);
-
-  /* Return */
-  return out;
-}
diff --git a/lib/data.c b/lib/data.c
index f935c01..996b553 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -38,7 +38,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <checkset.h>
 #include <data-copy.h>
-#include <data-arithmetic-unary.h>
+#include <data-arithmetic-other.h>
 #include <data-arithmetic-binary.h>
 #include <data-arithmetic-onlyint.h>
 
@@ -386,7 +386,6 @@ gal_data_alloc(void *array, int type, size_t ndim, long 
*dsize,
      contents. */
   out->ndim=ndim;
   out->type=type;
-  out->anyblank=0;
   out->minmapsize=minmapsize;
 
 
@@ -587,9 +586,9 @@ gal_data_alloc_blank(int type)
 void
 gal_data_apply_mask(gal_data_t *in, gal_data_t *mask)
 {
+  int hasblank=0;
   float *mpt, *m, *mf;
   gal_data_t *converted;
-  int hasblank=0;
 
   unsigned char     *uc   = in->array, *ucf   = uc  + in->size;
   char              *c    = in->array, *cf    = c   + in->size;
@@ -643,7 +642,6 @@ gal_data_apply_mask(gal_data_t *in, gal_data_t *mask)
   mf=(m=mpt)+in->size; do if(*m++ != 0.0f) hasblank=1; while(m<mf);
   if(hasblank)
     {
-      in->anyblank=1;
       switch(in->type)
         {
         case GAL_DATA_TYPE_BIT:
@@ -652,56 +650,56 @@ gal_data_apply_mask(gal_data_t *in, gal_data_t *mask)
                 "us to see how we can implement it.");
 
         case GAL_DATA_TYPE_UCHAR:
-          do *uc = *mpt++ == 0.0f ? *uc : GAL_DATA_BLANK_UCHAR; 
while(++uc<ucf);
+          do *uc = *mpt++==0.0f ? *uc : GAL_DATA_BLANK_UCHAR; while(++uc<ucf);
           break;
 
           /* CFITSIO says "int for keywords, char for table columns". Here we
              are only assuming table columns. So in practice this also applies
              to TSBYTE.*/
         case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-          do *c = *mpt++ == 0.0f ? *c : GAL_DATA_BLANK_CHAR; while(++c<cf);
+          do *c = *mpt++==0.0f ? *c : GAL_DATA_BLANK_CHAR; while(++c<cf);
           break;
 
         case GAL_DATA_TYPE_STRING:
-          do *str = *mpt++ == 0.0f ? *str : GAL_DATA_BLANK_STRING;
+          do *str = *mpt++==0.0f ? *str : GAL_DATA_BLANK_STRING;
           while(++str<strf);
           break;
 
         case GAL_DATA_TYPE_USHORT:
-          do *us = *mpt++ == 0.0f ? *us : GAL_DATA_BLANK_USHORT;
+          do *us = *mpt++==0.0f ? *us : GAL_DATA_BLANK_USHORT;
           while(++us<usf);
           break;
 
         case GAL_DATA_TYPE_SHORT:
-          do *s = *mpt++ == 0.0f ? *s : GAL_DATA_BLANK_SHORT; while(++s<sf);
+          do *s = *mpt++==0.0f ? *s : GAL_DATA_BLANK_SHORT; while(++s<sf);
           break;
 
         case GAL_DATA_TYPE_UINT:
-          do *ui = *mpt++ == 0.0f ? *ui : GAL_DATA_BLANK_UINT; while(++ui<uif);
+          do *ui = *mpt++==0.0f ? *ui : GAL_DATA_BLANK_UINT; while(++ui<uif);
           break;
 
         case GAL_DATA_TYPE_INT:
-          do *ii = *mpt++ == 0.0f ? *ii : GAL_DATA_BLANK_INT; while(++ii<iif);
+          do *ii = *mpt++==0.0f ? *ii : GAL_DATA_BLANK_INT; while(++ii<iif);
           break;
 
         case GAL_DATA_TYPE_ULONG:
-          do *ul = *mpt++ == 0.0f ? *ul : GAL_DATA_BLANK_ULONG; 
while(++ul<ulf);
+          do *ul = *mpt++==0.0f ? *ul : GAL_DATA_BLANK_ULONG; while(++ul<ulf);
           break;
 
         case GAL_DATA_TYPE_LONG:
-          do *l = *mpt++ == 0.0f ? *l : GAL_DATA_BLANK_LONG; while(++l<lf);
+          do *l = *mpt++==0.0f ? *l : GAL_DATA_BLANK_LONG; while(++l<lf);
           break;
 
         case GAL_DATA_TYPE_LONGLONG:
-          do *L = *mpt++ == 0.0f ? *L : GAL_DATA_BLANK_LONGLONG; while(++L<Lf);
+          do *L = *mpt++==0.0f ? *L : GAL_DATA_BLANK_LONGLONG; while(++L<Lf);
           break;
 
         case GAL_DATA_TYPE_FLOAT:
-          do *f = *mpt++ == 0.0f ? *f : GAL_DATA_BLANK_FLOAT; while(++f<ff);
+          do *f = *mpt++==0.0f ? *f : GAL_DATA_BLANK_FLOAT; while(++f<ff);
           break;
 
         case GAL_DATA_TYPE_DOUBLE:
-          do *d = *mpt++ == 0.0f ? *d : GAL_DATA_BLANK_DOUBLE; while(++d<df);
+          do *d = *mpt++==0.0f ? *d : GAL_DATA_BLANK_DOUBLE; while(++d<df);
           break;
 
         case GAL_DATA_TYPE_COMPLEX:
@@ -713,7 +711,7 @@ gal_data_apply_mask(gal_data_t *in, gal_data_t *mask)
 
         case GAL_DATA_TYPE_DCOMPLEX:
           do
-            if(*mpt++ == 0.0f)
+            if(*mpt++==0.0f)
               GSL_SET_COMPLEX(dcx, GAL_DATA_BLANK_DOUBLE,
                               GAL_DATA_BLANK_DOUBLE);
           while(++dcx<dcxf);
@@ -1346,11 +1344,11 @@ gal_data_to_same_type(gal_data_t *f,   gal_data_t *s,
 gal_data_t *
 gal_data_string_to_number(char *string)
 {
-  int type;
   long dsize[1]={1};
   int fnz=-1, lnz=0;     /* `F'irst (or `L'ast) `N'on-`Z'ero. */
   void *ptr, *numarr;
   char *tailptr, *cp;
+  int type, forcedfloat=0;
 
   /* Define the pointers. */
   unsigned char     uc;
@@ -1366,13 +1364,12 @@ gal_data_string_to_number(char *string)
   double             d;
 
   /* First see if the number is a double. */
-  errno=0;
   d=strtod(string, &tailptr);
-  if(*tailptr!='\0')
-    return NULL;
+  if(*tailptr=='f') { if(tailptr[1]=='\0') forcedfloat=1; else return NULL; }
+  else if (*tailptr!='\0')  return NULL;
 
   /* See if the number is actually an integer: */
-  if( ceil(d) == d )
+  if( forcedfloat==0 && ceil(d) == d )
     {
       /* If the number is negative, put it in the signed types (based on
          its value). If its zero or positive, then put it in the unsigned
@@ -1457,6 +1454,76 @@ gal_data_string_to_number(char *string)
 /*************************************************************
  **************      Arithmetic operations     ***************
  *************************************************************/
+char *
+gal_data_operator_string(int operator)
+{
+  switch(operator)
+    {
+    case GAL_DATA_OPERATOR_PLUS:         return "+";
+    case GAL_DATA_OPERATOR_MINUS:        return "-";
+    case GAL_DATA_OPERATOR_MULTIPLY:     return "*";
+    case GAL_DATA_OPERATOR_DIVIDE:       return "/";
+    case GAL_DATA_OPERATOR_MODULO:       return "%";
+
+    case GAL_DATA_OPERATOR_LT:           return "<";
+    case GAL_DATA_OPERATOR_LE:           return "<=";
+    case GAL_DATA_OPERATOR_GT:           return ">";
+    case GAL_DATA_OPERATOR_GE:           return ">=";
+    case GAL_DATA_OPERATOR_EQ:           return "==";
+    case GAL_DATA_OPERATOR_NE:           return "!=";
+    case GAL_DATA_OPERATOR_AND:          return "and";
+    case GAL_DATA_OPERATOR_OR:           return "or";
+    case GAL_DATA_OPERATOR_NOT:          return "not";
+    case GAL_DATA_OPERATOR_ISBLANK:      return "isblank";
+    case GAL_DATA_OPERATOR_WHERE:        return "where";
+
+    case GAL_DATA_OPERATOR_BITAND:       return "bitand";
+    case GAL_DATA_OPERATOR_BITOR:        return "bitor";
+    case GAL_DATA_OPERATOR_BITXOR:       return "bitxor";
+    case GAL_DATA_OPERATOR_BITLSH:       return "lshift";
+    case GAL_DATA_OPERATOR_BITRSH:       return "rshift";
+    case GAL_DATA_OPERATOR_BITOCM:       return "bitocm";
+
+    case GAL_DATA_OPERATOR_ABS:          return "abs";
+    case GAL_DATA_OPERATOR_POW:          return "pow";
+    case GAL_DATA_OPERATOR_SQRT:         return "sqrt";
+    case GAL_DATA_OPERATOR_LOG:          return "log";
+    case GAL_DATA_OPERATOR_LOG10:        return "log10";
+
+    case GAL_DATA_OPERATOR_MINVAL:       return "minval";
+    case GAL_DATA_OPERATOR_MAXVAL:       return "maxval";
+    case GAL_DATA_OPERATOR_MIN:          return "min";
+    case GAL_DATA_OPERATOR_MAX:          return "max";
+    case GAL_DATA_OPERATOR_AVERAGE:      return "average";
+    case GAL_DATA_OPERATOR_MEDIAN:       return "median";
+
+    case GAL_DATA_OPERATOR_TO_UCHAR:     return "uchar";
+    case GAL_DATA_OPERATOR_TO_CHAR:      return "char";
+    case GAL_DATA_OPERATOR_TO_USHORT:    return "ushort";
+    case GAL_DATA_OPERATOR_TO_SHORT:     return "short";
+    case GAL_DATA_OPERATOR_TO_UINT:      return "uint";
+    case GAL_DATA_OPERATOR_TO_INT:       return "int";
+    case GAL_DATA_OPERATOR_TO_ULONG:     return "ulong";
+    case GAL_DATA_OPERATOR_TO_LONG:      return "long";
+    case GAL_DATA_OPERATOR_TO_LONGLONG:  return "longlong";
+    case GAL_DATA_OPERATOR_TO_FLOAT:     return "float";
+    case GAL_DATA_OPERATOR_TO_DOUBLE:    return "double";
+
+    default:
+      error(EXIT_FAILURE, 0, "Operator code %d not recognized in "
+            "gal_data_operator_to_string", operator);
+    }
+
+  error(EXIT_FAILURE, 0, "A bug! Please contact us to fix the problem. "
+        "for some reason, control of the `gal_data_operator_to_string' "
+        "function has reached its end! This should not have happened");
+  return NULL;
+}
+
+
+
+
+
 gal_data_t *
 gal_data_arithmetic(int operator, unsigned char flags, ...)
 {
@@ -1474,7 +1541,6 @@ gal_data_arithmetic(int operator, unsigned char flags, 
...)
     case GAL_DATA_OPERATOR_MINUS:
     case GAL_DATA_OPERATOR_MULTIPLY:
     case GAL_DATA_OPERATOR_DIVIDE:
-    case GAL_DATA_OPERATOR_MODULO:
     case GAL_DATA_OPERATOR_LT:
     case GAL_DATA_OPERATOR_LE:
     case GAL_DATA_OPERATOR_GT:
@@ -1496,8 +1562,23 @@ gal_data_arithmetic(int operator, unsigned char flags, 
...)
     case GAL_DATA_OPERATOR_ISBLANK:
       d1 = va_arg(va, gal_data_t *);
       out = gal_data_flag_blank(d1);
-      if(flags & GAL_DATA_ARITH_FREE)
-        gal_data_free(d1);
+      if(flags & GAL_DATA_ARITH_FREE) gal_data_free(d1);
+      break;
+
+    /* Unary function operators. */
+    case GAL_DATA_OPERATOR_SQRT:
+    case GAL_DATA_OPERATOR_LOG:
+    case GAL_DATA_OPERATOR_LOG10:
+      d1 = va_arg(va, gal_data_t *);
+      out=data_arithmetic_unary_function_f(operator, flags, d1);
+      break;
+
+    /* Binary function operators. */
+    case GAL_DATA_OPERATOR_POW:
+      d1 = va_arg(va, gal_data_t *);
+      d2 = va_arg(va, gal_data_t *);
+      out=data_arithmetic_binary_function_f(operator, flags, d1, d2);
+      break;
 
     /* Binary operators that only work on integer types. */
     case GAL_DATA_OPERATOR_BITAND:
@@ -1505,13 +1586,12 @@ gal_data_arithmetic(int operator, unsigned char flags, 
...)
     case GAL_DATA_OPERATOR_BITXOR:
     case GAL_DATA_OPERATOR_BITLSH:
     case GAL_DATA_OPERATOR_BITRSH:
+    case GAL_DATA_OPERATOR_MODULO:
       d1 = va_arg(va, gal_data_t *);
       d2 = va_arg(va, gal_data_t *);
       out=data_arithmetic_onlyint_binary(operator, flags, d1, d2);
       break;
 
-    /* Ones component (bitwise) operator.*/
-
 
     /* Conversion operators. */
     case GAL_DATA_OPERATOR_TO_UCHAR:
@@ -1532,10 +1612,6 @@ gal_data_arithmetic(int operator, unsigned char flags, 
...)
 
 #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")
diff --git a/lib/fits.c b/lib/fits.c
index 00cbdbd..4fa4c23 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1202,6 +1202,7 @@ gal_fits_read_img_hdu(char *filename, char *hdu, char 
*maskname,
                       char *mhdu, size_t minmapsize)
 {
   void *blank;
+  int anyblank;
   size_t i, ndim;
   fitsfile *fptr;
   int status=0, type;
@@ -1242,9 +1243,13 @@ gal_fits_read_img_hdu(char *filename, char *hdu, char 
*maskname,
   free(dsize);
 
 
+  /* See if there is any blank pixels in the image (necessary for CFITSIO). */
+  anyblank=gal_data_has_blank(img);
+
+
   /* Read the image into the allocated array: */
   fits_read_pix(fptr, gal_fits_type_to_datatype(type), fpixel,
-                img->size, blank, img->array, &img->anyblank, &status);
+                img->size, blank, img->array, &anyblank, &status);
   if(status) gal_fits_io_error(status, NULL);
   free(fpixel);
   free(blank);
@@ -1342,7 +1347,6 @@ gal_fits_read_float_kernel(char *inputname, char *inhdu, 
float **outkernel,
       else          sum+=*f;
     }
   while(++f<fp);
-  kernel->anyblank=0;
   f=kernel->array; do *f++ *= 1/sum; while(f<fp);
 
   /* Flip the kernel about the center (necessary for non-symmetric
@@ -1389,13 +1393,16 @@ gal_fits_write_img_fitsptr(gal_data_t *data, char 
*filename, char *extname)
 
   /* If we have blank pixels, we need to define a BLANK keyword when we are
      dealing with integer types. */
-  if(data->anyblank)
-    if( data->type==GAL_DATA_TYPE_UCHAR || data->type==GAL_DATA_TYPE_CHAR
-        || data->type==GAL_DATA_TYPE_USHORT || data->type==GAL_DATA_TYPE_SHORT
-        || data->type==GAL_DATA_TYPE_UINT || data->type==GAL_DATA_TYPE_INT
-        || data->type==GAL_DATA_TYPE_ULONG || data->type==GAL_DATA_TYPE_LONG
-        || data->type==GAL_DATA_TYPE_LONGLONG)
+  if(gal_data_has_blank(data))
+    switch(data->type)
       {
+      case GAL_DATA_TYPE_FLOAT:
+      case GAL_DATA_TYPE_DOUBLE:
+        /* Do nothing! Since there are much fewer floating point types
+           (that don't need any BLANK keyword), we are checking them.*/
+        break;
+
+      default:
         blank=gal_data_alloc_blank(data->type);
         if(fits_write_key(fptr, datatype, "BLANK", blank,
                           "Pixels with no data.", &status) )
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 1ee8c28..5e07f90 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -129,39 +129,50 @@ enum gal_data_alltypes
 
 
 
-
+/* Operators not yet implemented in `gal_data_arithmetic':
+
+     GAL_DATA_OPERATOR_WHERE
+     GAL_DATA_OPERATOR_BITOCM
+     GAL_DATA_OPERATOR_ABS
+     GAL_DATA_OPERATOR_MINVAL
+     GAL_DATA_OPERATOR_MAXVAL
+     GAL_DATA_OPERATOR_MIN
+     GAL_DATA_OPERATOR_MAX
+     GAL_DATA_OPERATOR_AVERAGE
+     GAL_DATA_OPERATOR_MEDIAN
+*/
 enum gal_data_operators
 {
-  GAL_DATA_OPERATOR_PLUS,         /*   +    */
-  GAL_DATA_OPERATOR_MINUS,        /*   -    */
-  GAL_DATA_OPERATOR_MULTIPLY,     /*   *    */
-  GAL_DATA_OPERATOR_DIVIDE,       /*   /    */
-  GAL_DATA_OPERATOR_MODULO,       /*   %    */
-
-  GAL_DATA_OPERATOR_LT,           /*   <    */
-  GAL_DATA_OPERATOR_LE,           /*   <=   */
-  GAL_DATA_OPERATOR_GT,           /*   >    */
-  GAL_DATA_OPERATOR_GE,           /*   >=   */
-  GAL_DATA_OPERATOR_EQ,           /*   ==   */
-  GAL_DATA_OPERATOR_NE,           /*   !=   */
-  GAL_DATA_OPERATOR_AND,          /*   &&   */
-  GAL_DATA_OPERATOR_OR,           /*   ||   */
-  GAL_DATA_OPERATOR_NOT,          /*   !    */
+  GAL_DATA_OPERATOR_PLUS,         /*   +     */
+  GAL_DATA_OPERATOR_MINUS,        /*   -     */
+  GAL_DATA_OPERATOR_MULTIPLY,     /*   *     */
+  GAL_DATA_OPERATOR_DIVIDE,       /*   /     */
+  GAL_DATA_OPERATOR_MODULO,       /*   %     */
+
+  GAL_DATA_OPERATOR_LT,           /*   <     */
+  GAL_DATA_OPERATOR_LE,           /*   <=    */
+  GAL_DATA_OPERATOR_GT,           /*   >     */
+  GAL_DATA_OPERATOR_GE,           /*   >=    */
+  GAL_DATA_OPERATOR_EQ,           /*   ==    */
+  GAL_DATA_OPERATOR_NE,           /*   !=    */
+  GAL_DATA_OPERATOR_AND,          /*   &&    */
+  GAL_DATA_OPERATOR_OR,           /*   ||    */
+  GAL_DATA_OPERATOR_NOT,          /*   !     */
   GAL_DATA_OPERATOR_ISBLANK,      /* Similar to isnan() for floats. */
-  GAL_DATA_OPERATOR_WHERE,        /*   ?:   */
+  GAL_DATA_OPERATOR_WHERE,        /*   ?:    */
 
-  GAL_DATA_OPERATOR_BITAND,       /*   &    */
-  GAL_DATA_OPERATOR_BITOR,        /*   |    */
-  GAL_DATA_OPERATOR_BITXOR,       /*   ^    */
-  GAL_DATA_OPERATOR_BITLSH,       /*   <<   */
-  GAL_DATA_OPERATOR_BITRSH,       /*   >>   */
-  GAL_DATA_OPERATOR_BITOCM,       /*   ~    */
+  GAL_DATA_OPERATOR_BITAND,       /*   &     */
+  GAL_DATA_OPERATOR_BITOR,        /*   |     */
+  GAL_DATA_OPERATOR_BITXOR,       /*   ^     */
+  GAL_DATA_OPERATOR_BITLSH,       /*   <<    */
+  GAL_DATA_OPERATOR_BITRSH,       /*   >>    */
+  GAL_DATA_OPERATOR_BITOCM,       /*   ~     */
 
-  GAL_DATA_OPERATOR_ABS,          /* abs()  */
-  GAL_DATA_OPERATOR_POW,          /* pow()  */
-  GAL_DATA_OPERATOR_SQRT,         /* sqrt() */
-  GAL_DATA_OPERATOR_LOG,          /* log()  */
-  GAL_DATA_OPERATOR_LOG10,        /* log()  */
+  GAL_DATA_OPERATOR_ABS,          /* abs()   */
+  GAL_DATA_OPERATOR_POW,          /* pow()   */
+  GAL_DATA_OPERATOR_SQRT,         /* sqrt()  */
+  GAL_DATA_OPERATOR_LOG,          /* log()   */
+  GAL_DATA_OPERATOR_LOG10,        /* log10() */
 
   GAL_DATA_OPERATOR_MINVAL,       /* Minimum value of array.               */
   GAL_DATA_OPERATOR_MAXVAL,       /* Maximum value of array.               */
@@ -214,7 +225,6 @@ typedef struct
   size_t        size;  /* Total number of data-elements.             */
   char     *mmapname;  /* File name of the mmap.                     */
   size_t  minmapsize;  /* Minimum number of bytes to mmap the array. */
-  int       anyblank;  /* ==1: has blank values.                     */
   int           nwcs;  /* for WCSLIB: no. coord. representations.    */
   struct wcsprm *wcs;  /* WCS information for this dataset.          */
 } gal_data_t;
@@ -312,6 +322,9 @@ gal_data_string_to_number(char *string);
 /*************************************************************
  **************           Arithmetic           ***************
  *************************************************************/
+char *
+gal_data_operator_string(int operator);
+
 gal_data_t *
 gal_data_arithmetic(int operator, unsigned char flags, ...);
 
diff --git a/lib/mesh.c b/lib/mesh.c
index 1f89a6f..76ed614 100644
--- a/lib/mesh.c
+++ b/lib/mesh.c
@@ -461,7 +461,6 @@ gal_mesh_value_file(struct gal_mesh_params *mp, char 
*filename,
      image is written as a float FITS file, so anyblank is irrelevant, so
      is `size'.*/
   data.ndim=2;
-  data.anyblank=0;
   data.dsize=dsize;
   data.type=GAL_DATA_TYPE_FLOAT;
 
@@ -473,7 +472,7 @@ gal_mesh_value_file(struct gal_mesh_params *mp, char 
*filename,
          used for this job. In cgarray the meshs are ordered
          differently. */
       if(mp->garray1==mp->cgarray1) gal_mesh_full_garray(mp, 0);
-      data.wcs=NULL; /* This is not the original image size to have same WCS */
+      data.wcs=NULL; /* Not the original image size, to have same WCS */
       data.array=mp->fgarray1;
       data.dsize[0]=mp->gs0*mp->nch2;
       data.dsize[1]=mp->gs1*mp->nch1;



reply via email to

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