[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 531c263 008/125: Operators treated as macros,
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 531c263 008/125: Operators treated as macros, not string |
Date: |
Sun, 23 Apr 2017 22:36:25 -0400 (EDT) |
branch: master
commit 531c2636bf0ffc9bbe003fc322b36aed12fcae2c
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
Operators treated as macros, not string
The different operators are now recorgnized as macros in
`gal_data_arithmetic'. Until now, they were treated as strings which made
it a little slow and hard to generalize.
Also the `!=' operator is now called `ne' in Arithmetic, until now it was
called `neq'. This follows the names of the comparison operators in the
shell.
---
bin/arithmetic/args.h | 2 +-
bin/arithmetic/arithmetic.c | 97 ++++++++++++++++++++++++++++++++++++++++-----
doc/gnuastro.texi | 2 +-
lib/data-arithmetic.h | 94 +++++++++++++++++++++----------------------
lib/data.c | 39 ++++++++++--------
lib/gnuastro/data.h | 44 +++++++++++++++++++-
6 files changed, 198 insertions(+), 80 deletions(-)
diff --git a/bin/arithmetic/args.h b/bin/arithmetic/args.h
index 2be11b8..c9bf2a9 100644
--- a/bin/arithmetic/args.h
+++ b/bin/arithmetic/args.h
@@ -69,7 +69,7 @@ const char doc[] =
"Please see the manual for more information. "
"\n\nThe operators/functions recognized by "SPACK_NAME" are: +, -, *, /, "
"abs, pow, sqrt, log, log10, minvalue, maxvalue, min, max, average, median, "
- "lt, le, gt, ge, eq, neq, and, or, not, isblank. Please run `info gnuastro "
+ "lt, le, gt, ge, eq, ne, and, or, not, isblank. Please run `info gnuastro "
"\"Arithmetic operators\"' for detailed information on each operator. Note "
"that multiplication should be quoted (like \"*\", or '*') to avoid shell "
"expansion.\n"
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index ec457f3..d9e5919 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -67,6 +67,7 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
void
reversepolish(struct imgarithparams *p)
{
+ int op=0, nop=0;
struct gal_linkedlist_stll *token;
gal_data_t *d1=NULL, *d2=NULL, *d3=NULL;
unsigned char flags = ( GAL_DATA_ARITH_INPLACE | GAL_DATA_ARITH_FREE
@@ -90,20 +91,96 @@ reversepolish(struct imgarithparams *p)
add_operand(p, NULL, d1);
else
{
- /* Note that the first popped operand is the right/second given
- operand on the command-line. */
- if( !strcmp(token->v, "+") || !strcmp(token->v, "-")
- || !strcmp(token->v, "*") || !strcmp(token->v, "/") )
- {
- d2=pop_operand(p, token->v);
- d1=pop_operand(p, token->v);
- }
+ if (!strcmp(token->v, "+" ))
+ { op=GAL_DATA_OPERATOR_PLUS; nop=2; }
+ else if (!strcmp(token->v, "-" ))
+ { op=GAL_DATA_OPERATOR_MINUS; nop=2; }
+ else if (!strcmp(token->v, "*" ))
+ { op=GAL_DATA_OPERATOR_MULTIPLY; nop=2; }
+ else if (!strcmp(token->v, "/" ))
+ { op=GAL_DATA_OPERATOR_DIVIDE; nop=2; }
+
+ else if (!strcmp(token->v, "lt" ))
+ { op=GAL_DATA_OPERATOR_LT; nop=2; }
+ else if (!strcmp(token->v, "le"))
+ { op=GAL_DATA_OPERATOR_LE; nop=2; }
+ else if (!strcmp(token->v, "gt" ))
+ { op=GAL_DATA_OPERATOR_GT; nop=2; }
+ else if (!strcmp(token->v, "ge"))
+ { op=GAL_DATA_OPERATOR_LE; nop=2; }
+ else if (!strcmp(token->v, "eq"))
+ { op=GAL_DATA_OPERATOR_EQ; nop=2; }
+ else if (!strcmp(token->v, "ne"))
+ { op=GAL_DATA_OPERATOR_NE; nop=2; }
+ else if (!strcmp(token->v, "and"))
+ { op=GAL_DATA_OPERATOR_AND; nop=2; }
+ else if (!strcmp(token->v, "or"))
+ { op=GAL_DATA_OPERATOR_OR; nop=2; }
+ else if (!strcmp(token->v, "bitand"))
+ { op=GAL_DATA_OPERATOR_BITAND; nop=2; }
+ else if (!strcmp(token->v, "bitor"))
+ { op=GAL_DATA_OPERATOR_BITOR; nop=2; }
+
+ else if (!strcmp(token->v, "not"))
+ { op=GAL_DATA_OPERATOR_NOT; nop=1; }
+ else if (!strcmp(token->v, "isblank"))
+ { op=GAL_DATA_OPERATOR_ISBLANK; nop=1; }
+ else if (!strcmp(token->v, "where"))
+ { op=GAL_DATA_OPERATOR_WHERE; nop=3; }
+
+ else if (!strcmp(token->v, "abs"))
+ { op=GAL_DATA_OPERATOR_ABS; nop=1; }
+ else if (!strcmp(token->v, "pow"))
+ { op=GAL_DATA_OPERATOR_POW; nop=2; }
+ else if (!strcmp(token->v, "sqrt"))
+ { op=GAL_DATA_OPERATOR_SQRT; nop=1; }
+ else if (!strcmp(token->v, "log"))
+ { op=GAL_DATA_OPERATOR_LOG; nop=1; }
+ else if (!strcmp(token->v, "log10"))
+ { op=GAL_DATA_OPERATOR_LOG10; nop=1; }
+
+ else if (!strcmp(token->v, "minval"))
+ { op=GAL_DATA_OPERATOR_MINVAL; nop=1; }
+ else if (!strcmp(token->v, "maxval"))
+ { op=GAL_DATA_OPERATOR_MAXVAL; nop=1; }
+ else if (!strcmp(token->v, "min"))
+ { op=GAL_DATA_OPERATOR_MIN; nop=-1; }
+ else if (!strcmp(token->v, "max"))
+ { op=GAL_DATA_OPERATOR_MAX; nop=-1; }
+ else if (!strcmp(token->v, "average"))
+ { op=GAL_DATA_OPERATOR_AVERAGE; nop=-1; }
+ else if (!strcmp(token->v, "median"))
+ { op=GAL_DATA_OPERATOR_MEDIAN; nop=-1; }
else
error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
"interpretted as a FITS file, number, or operator",
token->v);
- add_operand(p, NULL,
- gal_data_arithmetic(token->v, flags, d1, d2, d3));
+
+ /* Pop the necessary number of operators. */
+ if(nop==1)
+ d1=pop_operand(p, token->v);
+ else if(nop==2)
+ {
+ d2=pop_operand(p, token->v);
+ d1=pop_operand(p, token->v);
+ }
+ else if(nop==3)
+ {
+ d3=pop_operand(p, token->v);
+ d2=pop_operand(p, token->v);
+ d1=pop_operand(p, token->v);
+ }
+ else if(nop==-1)
+ /* It might be possible to add a `next' pointer to the data
+ structure so it can act like a linked list too. In that
+ case, t */
+ error(EXIT_FAILURE, 0, "Operators with an unknown number of "
+ "operands are not yet implemented.");
+ else
+ error(EXIT_FAILURE, 0, "No operators need %d operands", nop);
+
+ /* Do the arithemtic operation. */
+ add_operand(p, NULL, gal_data_arithmetic(op, flags, d1, d2, d3));
}
}
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 28b6d2b..0487a20 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -7183,7 +7183,7 @@ Equality: similar to @code{lt} (`less than' operator),
but returning 1 when
the two popped operands are equal (to double precision floating point
accuracy).
address@hidden neq
address@hidden ne
Non-Equality: similar to @code{lt} (`less than' operator), but returning 1
when the two popped operands are @emph{not} equal (to double precision
floating point accuracy).
diff --git a/lib/data-arithmetic.h b/lib/data-arithmetic.h
index a0ef183..da5f766 100644
--- a/lib/data-arithmetic.h
+++ b/lib/data-arithmetic.h
@@ -217,7 +217,7 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
\
default: \
error(EXIT_FAILURE, 0, "type %d not recognized in " \
- "for o->type in BINARY_LEFT_RIGHT_DONE", type); \
+ "for o->type in BINARY_LEFT_RIGHT_DONE", o->type); \
}
@@ -253,14 +253,52 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
\
default: \
error(EXIT_FAILURE, 0, "type %d not recognized in " \
- "for r->type in BINARY_LEFT_DONE", type); \
+ "for r->type in BINARY_LEFT_DONE", r->type); \
}
-#define BINARY_MULTISWITCH(OP) \
+/* Prepare the inputs and output for binary operations and do the job.*/
+#define BINARY_INTERNAL(OP, OUT_TYPE) { \
+ \
+ /* Read the variable arguments. */ \
+ gal_data_t *l, *r; \
+ l = va_arg(va, gal_data_t *); \
+ r = va_arg(va, gal_data_t *); \
+ \
+ \
+ /* Simple sanity check on the input sizes */ \
+ if( !( (flags & GAL_DATA_ARITH_NUMOK) && (l->size==1 || r->size==1)) \
+ && gal_data_dsize_is_different(l, r) ) \
+ error(EXIT_FAILURE, 0, "The datasets don't have the same " \
+ "dimension/size"); \
+ \
+ \
+ /* Set the output type and size. */ \
+ out_type = OUT_TYPE ? OUT_TYPE : gal_data_out_type(l, r); \
+ out_size = l->size > r->size ? l->size : r->size; \
+ \
+ \
+ /* If we want inplace output, set the output pointer to one input. */ \
+ /* Note that the output type can be different from both inputs. */ \
+ if(flags & GAL_DATA_ARITH_INPLACE) \
+ { \
+ if(l->type==out_type && out_size==l->size) o = l; \
+ else if(r->type==out_type && out_size==r->size) o = r; \
+ } \
+ \
+ \
+ /* If the output pointer was not set for any reason, allocate it. */ \
+ if(o==NULL) \
+ o = gal_data_alloc(NULL, out_type, \
+ l->size>1 ? l->ndim : r->ndim, \
+ l->size>1 ? l->dsize : r->dsize, \
+ 0, l->mmapped || r->mmapped); \
+ \
+ \
+ /* Do the operations based on the different types. */ \
switch(l->type) \
{ \
case GAL_DATA_TYPE_UCHAR: \
@@ -289,51 +327,8 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
\
default: \
error(EXIT_FAILURE, 0, "type %d not recognized in " \
- "for l->type in BINARY_MULTISWITCH", type); \
- }
-
-
-
-
-
-/* Preparations for binary operators.
-
- Note that after `gal_data_to_same_type', we are only concerned with the
- `l' and `s' pointers. */
-#define BINARY_INTERNAL(OP, OUT_TYPE) \
- \
- gal_data_t *l, *r; \
- \
- \
- /* Read the variable arguments. */ \
- l = va_arg(va, gal_data_t *); \
- r = va_arg(va, gal_data_t *); \
- \
- \
- /* Simple sanity check on the input sizes */ \
- if( (flags & GAL_DATA_ARITH_NUMOK) && (l->size==1 || r->size==1 ) ) \
- type=0; /* Everything is ok, just a place-holder. */ \
- else if (gal_data_dsize_is_different(l, r)) \
- error(EXIT_FAILURE, 0, "The datasets don't have the same " \
- "dimension/size"); \
- \
- \
- /* Find the best output type. */ \
- type=gal_data_out_type(l, r); \
- \
- \
- /* Output can point to any one of the two arrays. */ \
- if(flags & GAL_DATA_ARITH_INPLACE) \
- o = l->size>1 ? l : r; \
- else \
- o = gal_data_alloc(NULL, type, \
- l->size>1 ? l->ndim : r->ndim, \
- l->size>1 ? l->dsize : r->dsize, \
- 0, l->mmapped || r->mmapped); \
- \
- \
- /* In block to allow definitions. */ \
- BINARY_MULTISWITCH(OP); \
+ "for l->type in BINARY_MULTISWITCH", l->type); \
+ } \
\
/* Clean up. */ \
if(flags & GAL_DATA_ARITH_FREE) \
@@ -341,7 +336,8 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
if(o==l) gal_data_free(r); \
else if(o==r) gal_data_free(l); \
else {gal_data_free(l); gal_data_free(r);} \
- }
+ } \
+}
diff --git a/lib/data.c b/lib/data.c
index cd5bc67..e34d9b1 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -1141,28 +1141,32 @@ gal_data_string_to_number(char *string)
************** Arithmetic ***************
*************************************************************/
gal_data_t *
-gal_data_arithmetic(char *operator, unsigned char flags, ...)
+gal_data_arithmetic(int operator, unsigned char flags, ...)
{
- int type;
va_list va;
+ int out_type;
+ size_t out_size;
gal_data_t *o=NULL;
/* Prepare the variable arguments (starting after the flags argument). */
va_start(va, flags);
/* Depending on the operator do the job: */
- if (!strcmp(operator, "+")) { BINARY_INTERNAL(+, 0); }
- else if (!strcmp(operator, "-")) { BINARY_INTERNAL(-, 0); }
- else if (!strcmp(operator, "*")) { BINARY_INTERNAL(*, 0); }
- else if (!strcmp(operator, "/")) { BINARY_INTERNAL(/, 0); }
- else if (!strcmp(operator, "lt")) { BINARY_INTERNAL(<, 0); }
- else if (!strcmp(operator, "le")) { BINARY_INTERNAL(<=, 0); }
- else if (!strcmp(operator, "gt")) { BINARY_INTERNAL(>, 0); }
- else if (!strcmp(operator, "ge")) { BINARY_INTERNAL(>=, 0); }
- else if (!strcmp(operator, "eq")) { BINARY_INTERNAL(==, 0); }
- else if (!strcmp(operator, "neq")) { BINARY_INTERNAL(!=, 0); }
- else if (!strcmp(operator, "and")) { BINARY_INTERNAL(&&, 0); }
- else if (!strcmp(operator, "or")) { BINARY_INTERNAL(||, 0); }
+ switch(operator)
+ {
+ case GAL_DATA_OPERATOR_PLUS: BINARY_INTERNAL(+, 0); break;
+ case GAL_DATA_OPERATOR_MINUS: BINARY_INTERNAL(-, 0); break;
+ case GAL_DATA_OPERATOR_MULTIPLY: BINARY_INTERNAL(*, 0); break;
+ case GAL_DATA_OPERATOR_DIVIDE: BINARY_INTERNAL(/, 0); break;
+
+ case GAL_DATA_OPERATOR_LT: BINARY_INTERNAL(<, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_LE: BINARY_INTERNAL(<=, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_GT: BINARY_INTERNAL(>, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_GE: BINARY_INTERNAL(>=, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_EQ: BINARY_INTERNAL(==, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_NE: BINARY_INTERNAL(!=, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_AND: BINARY_INTERNAL(&&, GAL_DATA_TYPE_UCHAR);
break;
+ case GAL_DATA_OPERATOR_OR: BINARY_INTERNAL(||, GAL_DATA_TYPE_UCHAR);
break;
#if 0
else if(!strcmp(operator, "abs")) takeabs(p);
@@ -1181,9 +1185,10 @@ gal_data_arithmetic(char *operator, unsigned char flags,
...)
else if(!strcmp(operator, "where")) where(p);
#endif
- else
- error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
- "interpretted as an operator", operator);
+ default:
+ error(EXIT_FAILURE, 0, "the argument \"%d\" could not be "
+ "interpretted as an operator", operator);
+ }
/* End the variable argument structure and return. */
va_end(va);
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index d841833..497ef5e 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -103,7 +103,7 @@ __BEGIN_C_DECLS /* From C++ preparations */
enum gal_data_alltypes
{
GAL_DATA_TYPE_BIT, /* Bit (TBIT). */
- GAL_DATA_TYPE_UCHAR, /* Unsigned char (TBYTE). */
+ GAL_DATA_TYPE_UCHAR, /* unsigned char (TBYTE). */
GAL_DATA_TYPE_CHAR, /* char (TSBYTE). */
GAL_DATA_TYPE_LOGICAL, /* char (TLOGICAL). */
GAL_DATA_TYPE_STRING, /* string (TSTRING). */
@@ -124,6 +124,46 @@ enum gal_data_alltypes
+enum gal_data_operators
+{
+ GAL_DATA_OPERATOR_PLUS, /* + */
+ GAL_DATA_OPERATOR_MINUS, /* - */
+ GAL_DATA_OPERATOR_MULTIPLY, /* * */
+ GAL_DATA_OPERATOR_DIVIDE, /* / */
+
+ 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_BITAND, /* & */
+ GAL_DATA_OPERATOR_BITOR, /* | */
+
+ GAL_DATA_OPERATOR_NOT, /* ! */
+ GAL_DATA_OPERATOR_ISBLANK, /* Similar to isnan() for floats. */
+ GAL_DATA_OPERATOR_WHERE, /* ?: */
+
+ 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_MINVAL, /* Minimum value of array. */
+ GAL_DATA_OPERATOR_MAXVAL, /* Maximum value of array. */
+ GAL_DATA_OPERATOR_MIN, /* Minimum per pixel of multiple arrays. */
+ GAL_DATA_OPERATOR_MAX, /* Maximum per pixel of multiple arrays. */
+ GAL_DATA_OPERATOR_AVERAGE, /* Average per pixel of multiple arrays. */
+ GAL_DATA_OPERATOR_MEDIAN, /* Median per pixel of multiple arrays. */
+};
+
+
+
+
+
/* Main data structure
If mmaped==0, it is assumed that the data is allocated (using
@@ -226,7 +266,7 @@ gal_data_string_to_number(char *string);
************** Arithmetic ***************
*************************************************************/
gal_data_t *
-gal_data_arithmetic(char *operator, unsigned char flags, ...);
+gal_data_arithmetic(int operator, unsigned char flags, ...);
- [gnuastro-commits] master updated (a5aeb7d -> 3339b92), Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 3e05560 003/125: Corrected bad use of type in MakeProfiles, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 847d97e 007/125: Minor header inclusion corrections, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 591461c 015/125: Corrected occurance of "remainder" with modulo, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 1ea9ea2 009/125: Data structure mmap information updated, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 531c263 008/125: Operators treated as macros, not string,
Mohammad Akhlaghi <=
- [gnuastro-commits] master ff9258a 006/125: Arithmetic with internal type conversion, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 5336d5c 024/125: Small but important corrections, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master c2fcb3e 020/125: Absolute value operator in gal_data_arithmetic, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master fdb6183 019/125: Where operator implemented in gal_data_arithmetic, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master 493bc6f 001/125: Defined new gnuastro/data.h header, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master c6462d1 016/125: Type conversion operators in Arithmetic, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master c10c4be 002/125: Moved type code and alloc functions into data.h, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master a4c5b9d 012/125: Binary operator arithmetic works on uncompiled types, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master ad2810d 029/125: Work started on getting text table information, Mohammad Akhlaghi, 2017/04/23
- [gnuastro-commits] master bc57ade 021/125: Minimum and maximum value operators implemented, Mohammad Akhlaghi, 2017/04/23