[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;
- [gnuastro-commits] master bc57ade 021/125: Minimum and maximum value operators implemented, (continued)
- [gnuastro-commits] master bc57ade 021/125: Minimum and maximum value operators implemented, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 2dea9a7 011/125: All binary operator types set at configure time, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master ff0b76d 018/125: New Data types section in book, bitwise not added, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master c62b01e 031/125: Corrected incrementation issue with and and or operators, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 0a32a82 027/125: Any number of searched columns from FITS are read, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master d0aa78e 005/125: Arithmetic operation on data structures in library, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 0ad0906 014/125: Bitwise operators available in arithmetic operations, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 3ad83a4 010/125: data-arithmetic and data-copy separated from data.c, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 6c6382a 013/125: Use of function instead of macros for binary operators, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master ce73959 030/125: Reading FITS keywords into linked list not array, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master e0e8679 017/125: Removed `anyblank' from datastructure, several new operators,
Mohammad Akhlaghi <=
- [gnuastro-commits] master 6d68470 033/125: Column info format for writing ASCII tables, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 0fd75fe 040/125: With no columns, Table program will print all columns, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 8090e6d 038/125: Corrections to FITS table reading, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 1156793 035/125: ASCII table information fully ready for selection, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 3c7773f 037/125: Table library prints ASCII columns with blanks, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 1dca684 047/125: Minor corrections to Gnuastro plain text table format, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 620146e 028/125: Library function for writing columns to txt file, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 9ec7556 039/125: Table's output file type set common sense, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master de80e97 046/125: Further explanations on Gnuastro's plain text tables, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master a5a7c45 048/125: Correction in Gnuastro text table format, Mohammad Akhlaghi, 2017/04/23