[SCIP] Patch for zimpl: sin/cos/tan/asin/acos/atan

Hartmut Henkel hartmut_henkel at gmx.de
Wed Feb 11 15:48:55 CET 2026


Hi,

all these functions were "Not implemented yet" in zimpl, but the nice
scaffolding was there, so it was straight-forward to activate them.

Having these functions also in zimpl allows e. g., to use scip for
digital FIR filter design through a few zpl lines.

I would be glad if you would consider the attached patch file.

Best Regards
Hartmut Henkel
-------------- next part --------------
# check.zpl

param pi    := 4 * atan(1);
param sin1  := sin(1);
param cos1  := cos(1);
param tan1  := tan(1);
param asin1 := asin(sin1);
param acos1 := acos(cos1);
param atan1 := atan(tan1);

var d >= 0;
var x_pi;
var x_sin;
var x_cos;
var x_tan;
var x_asin;
var x_acos;
var x_atan;

minimize slack: d;

subto c1a: x_pi   + d >= pi;
subto c1b: x_pi   - d <= pi;
subto c2a: x_sin  + d >= sin1;
subto c2b: x_sin  - d <= sin1;
subto c3a: x_cos  + d >= cos1;
subto c3b: x_cos  - d <= cos1;
subto c4a: x_tan  + d >= tan1;
subto c4b: x_tan  - d <= tan1;
subto c5a: x_asin + d >= asin1;
subto c5b: x_asin - d <= asin1;
subto c6a: x_acos + d >= acos1;
subto c6b: x_acos - d <= acos1;
subto c7a: x_atan + d >= atan1;
subto c7b: x_atan - d <= atan1;
-------------- next part --------------
diff --git a/src/zimpl/code.c b/src/zimpl/code.c
index cd69aed..3ac8261 100644
--- a/src/zimpl/code.c
+++ b/src/zimpl/code.c
@@ -531,7 +531,8 @@ bool code_prune_tree(CodeNode* node)
       i_expr_sqrt, i_expr_fac, i_expr_floor, i_expr_if_else, i_expr_intdiv, i_expr_length, i_expr_ln,
       i_expr_log, i_expr_ord, i_expr_prod, i_expr_round, i_expr_sum, i_expr_max,
       i_expr_max2, i_expr_sglmax, i_expr_min, i_expr_min2, i_expr_sglmin, i_expr_mul, 
-      i_expr_mod, i_expr_neg, i_expr_pow, i_expr_sub, i_expr_substr, NULL 
+      i_expr_mod, i_expr_neg, i_expr_pow, i_expr_sub, i_expr_substr,
+      i_expr_sin, i_expr_cos, i_expr_asin, i_expr_acos, i_expr_tan, i_expr_atan, NULL
    };
 
    bool is_all_const = true;
diff --git a/src/zimpl/inst.c b/src/zimpl/inst.c
index b9a6c62..574fdda 100644
--- a/src/zimpl/inst.c
+++ b/src/zimpl/inst.c
@@ -649,18 +649,7 @@ CodeNode* i_expr_sin(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
-
-   if (numb == NULL) //lint !e774 conditionalways true
-   {
-      code_errmsg(self);
-      zpl_exit(EXIT_FAILURE);
-   }      
-   code_value_numb(self, numb);
+   code_value_numb(self, numb_new_sin(code_eval_child_numb(self, 0)));
    
    return self;
 }
@@ -671,18 +660,7 @@ CodeNode* i_expr_cos(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
-
-   if (numb == NULL) //lint !e774 conditionalways true
-   {
-      code_errmsg(self);
-      zpl_exit(EXIT_FAILURE);
-   }      
-   code_value_numb(self, numb);
+   code_value_numb(self, numb_new_cos(code_eval_child_numb(self, 0)));
    
    return self;
 }
@@ -693,18 +671,7 @@ CodeNode* i_expr_tan(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
-
-   if (numb == NULL) //lint !e774 conditionalways true
-   {
-      code_errmsg(self);
-      zpl_exit(EXIT_FAILURE);
-   }      
-   code_value_numb(self, numb);
+   code_value_numb(self, numb_new_tan(code_eval_child_numb(self, 0)));
    
    return self;
 }
@@ -715,13 +682,9 @@ CodeNode* i_expr_asin(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
+   Numb* const numb = numb_new_asin(code_eval_child_numb(self, 0));
 
-   if (numb == NULL) //lint !e774 conditionalways true
+   if (numb == NULL)
    {
       code_errmsg(self);
       zpl_exit(EXIT_FAILURE);
@@ -737,13 +700,9 @@ CodeNode* i_expr_acos(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
+   Numb* const numb = numb_new_acos(code_eval_child_numb(self, 0));
 
-   if (numb == NULL) //lint !e774 conditionalways true
+   if (numb == NULL)
    {
       code_errmsg(self);
       zpl_exit(EXIT_FAILURE);
@@ -759,13 +718,9 @@ CodeNode* i_expr_atan(CodeNode* self)
 
    assert(code_is_valid(self));
 
-   fprintf(stderr, "Not implemented yet\n");
-
-   /* ??? numb = numb_new_log(code_eval_child_numb(self, 0)); */
-   
-   Numb* numb = NULL;
+   Numb* const numb = numb_new_atan(code_eval_child_numb(self, 0));
 
-   if (numb == NULL) //lint !e774 conditionalways true
+   if (numb == NULL)
    {
       code_errmsg(self);
       zpl_exit(EXIT_FAILURE);
diff --git a/src/zimpl/mono.h b/src/zimpl/mono.h
index 47ee283..e00cecc 100644
--- a/src/zimpl/mono.h
+++ b/src/zimpl/mono.h
@@ -33,7 +33,8 @@ extern "C" {
 enum mono_function {
    MFUN_SQRT = -2, MFUN_NONE = 0,  MFUN_TRUE = 1, MFUN_FALSE = 2, MFUN_LOG = 3,
    MFUN_EXP  = 4,  MFUN_LN   = 5,  MFUN_SIN  = 6, MFUN_COS   = 7, MFUN_TAN = 8,
-   MFUN_ABS  = 9,  MFUN_SGN  = 10, MFUN_POW = 11, MFUN_SGNPOW = 12
+   MFUN_ABS  = 9,  MFUN_SGN  = 10, MFUN_POW = 11, MFUN_SGNPOW = 12,
+   MFUN_ASIN = 13, MFUN_ACOS = 14, MFUN_ATAN = 15
 };
 
 typedef enum   mono_function MFun;
diff --git a/src/zimpl/numb.h b/src/zimpl/numb.h
index e1e8a1a..ed65a07 100644
--- a/src/zimpl/numb.h
+++ b/src/zimpl/numb.h
@@ -104,6 +104,18 @@ extern Numb*        numb_new_sqrt(Numb const* numb) expects_NONNULL;
 extern Numb*        numb_new_exp(Numb const* numb) expects_NONNULL returns_NONNULL;
 //lint -sem(        numb_new_ln, 1p == 1, @P >= malloc(1) || @P == 0) 
 extern Numb*        numb_new_ln(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_sin, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_sin(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_cos, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_cos(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_tan, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_tan(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_asin, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_asin(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_acos, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_acos(Numb const* numb) expects_NONNULL;
+//lint -sem(        numb_new_atan, 1p == 1, @P >= malloc(1) || @P == 0) 
+extern Numb*        numb_new_atan(Numb const* numb) expects_NONNULL;
 //lint -sem(        numb_new_rand, 1p == 1, 2p == 1, @P >= malloc(1)) 
 extern Numb*        numb_new_rand(Numb const* mini, Numb const* maxi) expects_NONNULL returns_NONNULL;
 //lint -sem(        numb_todbl, pure, 1p == 1) 
diff --git a/src/zimpl/numbdbl.c b/src/zimpl/numbdbl.c
index 83e7398..57ae478 100644
--- a/src/zimpl/numbdbl.c
+++ b/src/zimpl/numbdbl.c
@@ -528,7 +528,6 @@ Numb* numb_new_sqrt(Numb const* numb_a)
 
 Numb* numb_new_exp(Numb const* numb_a)
 {
-   char temp[32];
    Numb* numb = numb_new();
    
    assert(numb != NULL);
@@ -539,6 +538,106 @@ Numb* numb_new_exp(Numb const* numb_a)
    return numb;
 }
 
+
+Numb* numb_new_sin(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = sin(numb_a->value.numb);
+
+   return numb;
+}
+
+Numb* numb_new_cos(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = cos(numb_a->value.numb);
+
+   return numb;
+}
+
+Numb* numb_new_tan(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = tan(numb_a->value.numb);
+
+   return numb;
+}
+
+Numb* numb_new_asin(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = asin(numb_a->value.numb);
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (numb->value.numb != numb->value.numb) 
+   {
+      char temp[256];
+
+      snprintf(temp, 255, "*** Error 701: asin(%f)", numb_a->value.numb);
+      perror(temp);
+      return NULL;
+   }
+   return numb;
+}
+
+Numb* numb_new_acos(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = acos(numb_a->value.numb);
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (numb->value.numb != numb->value.numb) 
+   {
+      char temp[256];
+
+      snprintf(temp, 255, "*** Error 701: acos(%f)", numb_a->value.numb);
+      perror(temp);
+      return NULL;
+   }
+   return numb;
+}
+
+Numb* numb_new_atan(Numb const* numb_a)
+{
+   Numb* numb = numb_new();
+   
+   assert(numb != NULL);
+   assert(numb_is_valid(numb_a));
+
+   numb->value.numb = atan(numb_a->value.numb);
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (numb->value.numb != numb->value.numb) 
+   {
+      char temp[256];
+
+      snprintf(temp, 255, "*** Error 701: atan(%f)", numb_a->value.numb);
+      perror(temp);
+      return NULL;
+   }
+   return numb;
+}
+
 Numb* numb_new_ln(Numb const* numb_a)
 {
    Numb* numb = numb_new();
@@ -553,7 +652,7 @@ Numb* numb_new_ln(Numb const* numb_a)
    {
       char temp[256];
       
-      sprintf(temp, "*** Error 702: ln(%f)", numb->value.numb);
+      snprintf(temp, 255, "*** Error 702: ln(%f)", numb->value.numb);
       perror(temp);
       return NULL;
    }
diff --git a/src/zimpl/numbgmp.c b/src/zimpl/numbgmp.c
index 3177695..76c7935 100644
--- a/src/zimpl/numbgmp.c
+++ b/src/zimpl/numbgmp.c
@@ -680,6 +680,102 @@ Numb* numb_new_exp(Numb const* numb)
    return numb_new_ascii(temp);
 }
 
+Numb* numb_new_sin(Numb const* numb)
+{
+   char temp[32];
+   
+   assert(numb_is_valid(numb));
+
+   snprintf(temp, 31, "%.16e", sin(mpq_get_d(numb->value.numb)));
+
+   return numb_new_ascii(temp);
+}
+
+Numb* numb_new_cos(Numb const* numb)
+{
+   char temp[32];
+   
+   assert(numb_is_valid(numb));
+
+   snprintf(temp, 31, "%.16e", cos(mpq_get_d(numb->value.numb)));
+
+   return numb_new_ascii(temp);
+}
+
+Numb* numb_new_tan(Numb const* numb)
+{
+   char temp[32];
+   
+   assert(numb_is_valid(numb));
+
+   snprintf(temp, 31, "%.16e", tan(mpq_get_d(numb->value.numb)));
+
+   return numb_new_ascii(temp);
+}
+
+Numb* numb_new_asin(Numb const* numb)
+{
+   char   temp[256];
+   double d;
+   
+   assert(numb_is_valid(numb));
+
+   d = asin(mpq_get_d(numb->value.numb));
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (d != d) /*lint !e777 */ /* == isnan(d) || isinf(d) */
+   {
+      snprintf(temp, 255, "*** Error 701: asin(%f)", mpq_get_d(numb->value.numb));
+      perror(temp);
+      return NULL;
+   }
+   snprintf(temp, 255, "%.16e", d);
+
+   return numb_new_ascii(temp);
+}
+
+Numb* numb_new_acos(Numb const* numb)
+{
+   char   temp[256];
+   double d;
+   
+   assert(numb_is_valid(numb));
+
+   d = acos(mpq_get_d(numb->value.numb));
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (d != d) /*lint !e777 */ /* == isnan(d) || isinf(d) */
+   {
+      snprintf(temp, 255, "*** Error 701: acos(%f)", mpq_get_d(numb->value.numb));
+      perror(temp);
+      return NULL;
+   }
+   snprintf(temp, 255, "%.16e", d);
+
+   return numb_new_ascii(temp);
+}
+
+Numb* numb_new_atan(Numb const* numb)
+{
+   char   temp[256];
+   double d;
+   
+   assert(numb_is_valid(numb));
+
+   d = atan(mpq_get_d(numb->value.numb));
+
+   /* !finite == !isfinite == isnan || isinf */
+   if (d != d) /*lint !e777 */ /* == isnan(d) || isinf(d) */
+   {
+      snprintf(temp, 255, "*** Error 701: atan(%f)", mpq_get_d(numb->value.numb));
+      perror(temp);
+      return NULL;
+   }
+   snprintf(temp, 255, "%.16e", d);
+
+   return numb_new_ascii(temp);
+}
+
 Numb* numb_new_ln(Numb const* numb)
 {
    char   temp[256];
diff --git a/src/zimpl/ratlpfwrite.c b/src/zimpl/ratlpfwrite.c
index 028de8a..0e9e57c 100644
--- a/src/zimpl/ratlpfwrite.c
+++ b/src/zimpl/ratlpfwrite.c
@@ -261,6 +261,15 @@ static void write_term(
          case MFUN_TAN :
             fprintf(fp, " + tan(");
             break;
+         case MFUN_ASIN :
+            fprintf(fp, " + asin(");
+            break;
+         case MFUN_ACOS :
+            fprintf(fp, " + acos(");
+            break;
+         case MFUN_ATAN :
+            fprintf(fp, " + atan(");
+            break;
          case MFUN_ABS :
             fprintf(fp, " + abs(");
             break;


More information about the Scip mailing list