gnuastro-commits
[Top][All Lists]

## [gnuastro-commits] master 376edc9 1/5: Simple conditional operators adde

 From: Mohammad Akhlaghi Subject: [gnuastro-commits] master 376edc9 1/5: Simple conditional operators added to Arithmetic Date: Fri, 26 Aug 2016 17:37:28 +0000 (UTC)

```branch: master

Simple conditional operators added to Arithmetic

Arithmetic can now also work with the simple conditional operators of `<',
`>', `==', `<=', and `>='. The book has also been updated to explain their
operations.
---
doc/gnuastro.texi           |   75 +++++++++++++++++++++++-----------
src/arithmetic/arithmetic.c |   95 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 146 insertions(+), 24 deletions(-)

diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 567c526..78ebd2d 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -6824,16 +6824,16 @@ referenced Wikipedia article provides some excellent
explanation on
this notation but here we will give a short summary for
self-sufficiency.

-In the postfix notation, the operator is placed after the operands, as
-we will see below this removes the need to define parenthesis for most
-ordinary operators. For example, instead of writing @command{5+6}, we
-write @command{5 6 +}. To easily understand how this notation works,
-you can think of each operand a node in a first-in-first-out
-stack. Every time an operator is confronted, it pops the number of
-operands it needs from the top of the stack (so they don't exist in
-the stack any more), does its operation and pushes the result back on
-top of the stack. So if you want the average of 5 and 6, you would
-write: @command{5 6 + 2 /}. The operations that are done are:
+In the postfix notation, the operator is placed after the operands, as we
+will see below this removes the need to define parenthesis for most
+ordinary operators. For example, instead of writing @command{5+6}, we write
address@hidden 6 +}. To easily understand how this notation works, you can
+think of each operand as a node in a first-in-first-out stack. Every time
+an operator is confronted, it pops the number of operands it needs from the
+top of the stack (so they don't exist in the stack any more), does its
+operation and pushes the result back on top of the stack. So if you want
+the average of 5 and 6, you would write: @command{5 6 + 2 /}. The
+operations that are done are:

@enumerate
@item
@@ -6853,24 +6853,24 @@ the stack (top-most is @command{2}, then @command{11})
and divide the
second one by the first.
@end enumerate

-In Gnuastro's Arithmetic, the operands can be FITS images or
-numbers. As you can see, very complicated procedures can be created
-without the need for parenthesis. Even functions which take an
-arbitrary number of arguments can be defined in this notation. For
-example the Postscript address@hidden the EPS and PDF part of
address@hidden file types} for a little more on the Postscript
-language.} (the programming language for PDF files) uses this notation
-style
+In Gnuastro's Arithmetic, the operands can be FITS images or numbers. As
+you can see, very complicated procedures can be created without the need
+for parenthesis. Even functions which take an arbitrary number of arguments
+can be defined in this notation. For example the Postscript
address@hidden the EPS and PDF part of @ref{Recognized file types}
+for a little more on the Postscript language.} (the programming language in
+Postscript and compiled into PDF files) uses this notation.

@node Arithmetic operators, Invoking astarithmetic, Reverse polish notation,
Arithmetic
@subsection Arithmetic operators

-The recognized operators in Arithmetic are listed below. See
address@hidden polish notation} for more on how the operators and
-operands should be ordered on the command-line. The operands to all
-operators can be a data array (for example a FITS image) or a number,
-the output will be an array or number according to the inputs. For
-example a number multiplied by an array will produce an array.
+The recognized operators in Arithmetic are listed below. See @ref{Reverse
+polish notation} for more on how the operators and operands should be
+ordered on the command-line. The operands to all operators can be a data
+array (for example a FITS image) or a number, the output will be an array
+or number according to the inputs. For example a number multiplied by an
+array will produce an array. The conditional operators will return pixel,
+or numerical values of 0 (false) or 1 (true).

@table @command

@@ -6956,6 +6956,33 @@ the average of the respective pixels in all operands in
the stack
Similar to @command{min}, but the pixels of the output will contain
the median of the respective pixels in all operands in the stack.

+Smaller than: If the second popped (or left operand in infix notation, see
address@hidden polish notation}) value is smaller than the right operand,
+then this function will return a value of 1, otherwise it will return a
+value of 0. If both operands are images, then all the pixels will be
+compared with their counter parts in the other image. If only one operand
+is an image, then all the pixels will be compared with the number. Finally
+if both are numbers, then the output is also just one number (0 or 1).
+
+Larger than: similar to the @code{<} (smaller than operator), but returning
+1 when the second popped operand is larger than the first.
+
+Equality: similar to the @code{<} (smaller than operator), but returning 1
+when the second popped operand is equal (to double precison floating point
+accuracy) to the first.
+
+Smaller or equal: similar to the @code{<} (smaller than operator), but
+returning 1 when the second popped operand is smaller or equal to the
+first.
+
+Larger or equal: similar to the @code{<} (smaller than operator), but
+returning 1 when the second popped operand is larger or equal to the first.
+
@end table

@cartouche
diff --git a/src/arithmetic/arithmetic.c b/src/arithmetic/arithmetic.c
index 4ede5cb..31e7bfc 100644
--- a/src/arithmetic/arithmetic.c
+++ b/src/arithmetic/arithmetic.c
@@ -760,6 +760,96 @@ findmax(struct imgarithparams *p)

+int
+smaller(double left, double right)
+{ return left<right; }
+
+int
+larger(double left, double right)
+{ return left>right; }
+
+int
+equal(double left, double right)
+{ return left==right; }
+
+int
+smallerequal(double left, double right)
+{ return left<=right; }
+
+int
+largerequal(double left, double right)
+{ return left>=right; }
+
+
+
+
+
+void
+conditionals(struct imgarithparams *p, char *operator)
+{
+  size_t size;
+  double fnum, snum;            /* First or second number.    */
+  double *farr, *sarr;          /* First or second array.     */
+  double *f, *s, *ff, *ss;
+  int (*thisfunction)(double, double)=NULL;
+
+  /* Pop out the number of operands needed. */
+  pop_operand(p, &fnum, &farr, operator);
+  pop_operand(p, &snum, &sarr, operator);
+
+  /* Set the total number of pixels, note that we can't do this in the
+     definition of the variable because p->s0 and p->s1 will be set in
+     pop_operand for the first image. */
+  size=p->s0*p->s1;
+
+  if(!strcmp(operator, "<"))       thisfunction = &smaller;
+  else if(!strcmp(operator, ">"))  thisfunction = &larger;
+  else if(!strcmp(operator, "==")) thisfunction = &equal;
+  else if(!strcmp(operator, "<=")) thisfunction = &smallerequal;
+  else if(!strcmp(operator, ">=")) thisfunction = &largerequal;
+  else
+          "can address the problem. The value of `operator' in "
+          "conditionals (%s) is not recognized",
+          PACKAGE_BUGREPORT, operator);
+
+  /* Do the operation: */
+  if(farr && sarr)              /* Both are arrays. */
+    {
+      /* Do the operation, note that the output is stored in the first
+         input. Also note that since the linked list is
+         first-in-first-out, the second operand should be put first
+         here. */
+      ff=(f=farr)+size;
+      ss=(s=sarr)+size;
+      do *s = thisfunction(*s, *f++); while(++s<ss);
+
+      /* Push the output onto the stack. */
+
+      /* Clean up. */
+      free(farr);
+    }
+  else if(farr)                 /* Only the first is an array. */
+    {
+      ff=(f=farr)+size;
+      do *f = thisfunction(snum, *f); while(++f<ff);
+    }
+  else if(sarr)                 /* Only the first is an array. */
+    {
+      ss=(s=sarr)+size;
+      do *s = thisfunction(*s, fnum); while(++s<ss);
+    }
+  else                          /* Both are numbers.           */
+    add_operand(p, NOOPTFILENAME, thisfunction(snum, fnum), NOOPTARRAY);
+}
+
+
+
+
+

@@ -822,6 +912,11 @@ reversepolish(struct imgarithparams *p)
|| !strcmp(token->v, "max")
|| !strcmp(token->v, "average")
|| !strcmp(token->v, "median")) alloppixs(p, token->v);
+          else if(!strcmp(token->v, "<")
+                  || !strcmp(token->v, ">")
+                  || !strcmp(token->v, "==")
+                  || !strcmp(token->v, "<=")
+                  || !strcmp(token->v, ">=")) conditionals(p, token->v);
else
error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
"interpretted as an operator", token->v);

```