From c4ced3eea5a8ca43c8e5fe4b360b712bd02e3503 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (laptop)" <j.wuttke@fz-juelich.de>
Date: Wed, 21 Jan 2009 09:55:32 +0100
Subject: [PATCH] towards conv-integration

---
 src/curve.cpp  | 71 ++++++--------------------------------------------
 src/curve.h    |  2 +-
 src/expr.cpp   | 29 +++++++++++++++++++--
 src/frida2.cpp |  2 +-
 src/mystd.cpp  | 61 +++++++++++++++++++++++++++++++++++++++++++
 src/mystd.h    |  6 +++++
 src/readln.cpp |  4 +--
 src/readln.h   |  7 ++---
 8 files changed, 108 insertions(+), 74 deletions(-)

diff --git a/src/curve.cpp b/src/curve.cpp
index b2112038..7fa99817 100644
--- a/src/curve.cpp
+++ b/src/curve.cpp
@@ -291,6 +291,9 @@ void NCurveFile::SetConvolution( bool onoff )
 
 void NCurveFile::SetConvTuningPars( string which )
 {
+    // per-file ???
+    throw string( "convolution tuning parameters not operational" );
+    
     static int mode = -1;
     static double epsabs = 1e-10, epsrel = 1e-10;
     COlc *fc;
@@ -617,9 +620,9 @@ void NCurveFile::SetIntTuningPars( string which )
 
 //! Outer wrapper: dialog, loop over files and parameters
 
-void NCurveFile::Integrate(void)
+void NCurveFile::IntegralProperty(void)
 {
-    if( NRead::empty() )
+    if( NRead::stack_empty() )
         cout << "Generate integral file:\n"
             "   <list of numbers>   extract curve parameters\n"
             "   *                   extract all curve parameters\n"
@@ -630,7 +633,7 @@ void NCurveFile::Integrate(void)
     if      ( mode==" " )
         return;
     else if ( mode=="i" ){
-        if( NRead::empty() )
+        if( NRead::stack_empty() )
             cout << "integration bounds: -inf,inf are allowed\n";
         numint_bound_low = dask( "Integrate from", numint_bound_low );
         numint_bound_hig = dask( "Integrate to", numint_bound_hig );
@@ -732,64 +735,6 @@ void NCurveFile::IntegrateFile( const COlc *fin, const int k,
 };
 
 
-//! Generic integration routine.
-
-#include <gsl/gsl_integration.h>
-
-double Integrate( double (*func_) (double, void*), void *data_, 
-                  const double low, const double hig,
-                  const uint mode, const double epsabs, const double epsrel )
-{
-    gsl_function F;
-    F.function = func_;
-    F.params = data_;
-#define nwork 20000
-    gsl_integration_workspace *work = gsl_integration_workspace_alloc( nwork );
-    double val, err;
-    int rule;
-    size_t neval;
-
-    if      ( isinf(low)==-1 && isinf(hig)==+1 )
-        gsl_integration_qagi( &F, 
-                             epsabs, epsrel, nwork,
-                             work, &val, &err );
-    else if ( isinf(low)==-1 )
-        gsl_integration_qagil( &F, hig,
-                             epsabs, epsrel, nwork,
-                             work, &val, &err );
-    else if ( isinf(hig)==+1 )
-        gsl_integration_qagiu( &F, low,
-                             epsabs, epsrel, nwork,
-                             work, &val, &err );
-    else if ( mode==0 )
-        gsl_integration_qng( &F, low, hig,
-                             epsabs, epsrel,
-                             &val, &err, &neval );
-    else if ( mode>0 && mode<7 ){
-        switch( mode ){
-        case 1: rule = GSL_INTEG_GAUSS61; break;
-        case 2: rule = GSL_INTEG_GAUSS51; break;
-        case 3: rule = GSL_INTEG_GAUSS41; break;
-        case 4: rule = GSL_INTEG_GAUSS31; break;
-        case 5: rule = GSL_INTEG_GAUSS21; break;
-        case 6: rule = GSL_INTEG_GAUSS15; break;
-        }
-        gsl_integration_qag( &F, low, hig,
-                             epsabs, epsrel, nwork,
-                             rule, work, &val, &err );
-    }
-    else if ( mode==7 )
-        gsl_integration_qags( &F, low, hig,
-                              epsabs, epsrel, nwork,
-                              work, &val, &err );
-    else
-        throw string( "invalid mode in NumericIntegral" );
-
-    gsl_integration_workspace_free( work );
-    return val;
-}
-
-
 //! Numeric interation of one curve.
 
 double NCurveFile::NumericIntegral(
@@ -802,8 +747,8 @@ double NCurveFile::NumericIntegral(
     data.k = k;
     data.j = j;
 
-    return Integrate( &myeval, &data, low, hig,
-                      numint_mode, numint_epsabs, numint_epsrel );
+    return mystd::Integrate( &myeval, &data, low, hig,
+                             numint_mode, numint_epsabs, numint_epsrel );
 }
 
 //***************************************************************************//
diff --git a/src/curve.h b/src/curve.h
index 92470fdd..ad026e0c 100644
--- a/src/curve.h
+++ b/src/curve.h
@@ -34,7 +34,7 @@ namespace NCurveFile {
     void Fit( void );
 
     void SetIntTuningPars( string which );
-    void Integrate( void );
+    void IntegralProperty( void );
 
     void CumulativeDistribution( void );
 };
diff --git a/src/expr.cpp b/src/expr.cpp
index 644a716f..07fdc5b8 100644
--- a/src/expr.cpp
+++ b/src/expr.cpp
@@ -12,6 +12,7 @@
 #include "mystd.h"
 #include "olm.h" // for cross-references
 #include "expr.h"
+#include "readln.h"
 
 bool debug = false;
 #define DEB(args) if ( debug ) printf args
@@ -339,6 +340,17 @@ string CRef::ref_info(void) const
 //* class CTree                                                             *//
 //***************************************************************************//
 
+typedef struct {
+    const COlc *fc;
+    uint k;
+    uint j;
+} ConvDatTyp;
+
+double tree_conv_eval( double tt, void *data )
+{
+    ConvDatTyp *mydata = (ConvDatTyp*) data;
+    return 1;
+}
 
 //! Evaluate tree and convert result to integer, for use as index.
 
@@ -472,7 +484,7 @@ void CTree::tree_val( CTOut *ret, const CContext *ctx ) const
                 arg[0]->tree_val( &r, ctx );
                 for ( uint i=0; i<n; ++i )
                     ret->vd[i] = r.to_d(i);
-            } else {
+            } else if ( NRead::iofmac("\\cv_mode")==-1 ) {
                 // Convolute theory with resolution.
                 // Simplest version: non-equidistant x_out and x_res.
                 CTOut r;
@@ -493,7 +505,20 @@ void CTree::tree_val( CTOut *ret, const CContext *ctx ) const
                     for ( uint i=0; i<n; ++i )
                         ret->vd[i] += r.to_d(i) * sv->y[iv] / conv_norm;
                 }
+            } else {
+                ConvDatTyp conv_data;
+                for ( uint i=0; i<n; ++i ) {
+                    ret->vd[i] =
+                        mystd::Integrate( &tree_conv_eval,
+                                          (void *) &conv_data,
+                                          sv->x[0], sv->x[nv-1],
+                                          NRead::iofmac( "\\cv_mode" ),
+                                          NRead::dofmac( "\\cv_epsabs" ),
+                                          NRead::dofmac( "\\cv_epsrel" ) ) /
+                        conv_norm;
+                }
             }
+
         } else if ( typ == _DIRAC ) {
             CTOut r;
             // center of delta function given by arg[0]:
@@ -752,7 +777,7 @@ void NCalc::Calculator()
     PTree T;
     double v;
 
-    if ( NRead::empty() ) {
+    if ( NRead::stack_empty() ) {
         // interactive calculator
         while (1) {
             s = sask("calc> ");
diff --git a/src/frida2.cpp b/src/frida2.cpp
index c1b502c1..c99994f9 100644
--- a/src/frida2.cpp
+++ b/src/frida2.cpp
@@ -138,7 +138,7 @@ int main()
                 NCurveFile::SetConvolution( false );
 
             } else if (cmd == "ci") {
-                NCurveFile::Integrate();
+                NCurveFile::IntegralProperty();
             } else if (cmd == "cp") {
                 NCurveFile::ShowPar();
 
diff --git a/src/mystd.cpp b/src/mystd.cpp
index 055289ea..9b9fdb9c 100644
--- a/src/mystd.cpp
+++ b/src/mystd.cpp
@@ -5,6 +5,7 @@
 //* http://frida.sourceforge.net                                           *//
 //**************************************************************************//
 
+#include <stdlib.h> // otherwise buggy compiler error from gsl
 #include <string.h>
 #include <math.h>
 #include <sys/time.h>
@@ -482,3 +483,63 @@ int mystd::freadln(FILE *fd, string *s)
         *s += c;
     }
 }
+
+//**************************************************************************//
+//*  GSL integration                                                       *//
+//**************************************************************************//
+
+#include <gsl/gsl_integration.h>
+
+double mystd::Integrate( double (*func_) (double, void*), void *data_, 
+                         const double low, const double hig,
+                         const uint mode, const double epsabs,
+                         const double epsrel )
+{
+    gsl_function F;
+    F.function = func_;
+    F.params = data_;
+#define nwork 20000
+    gsl_integration_workspace *work = gsl_integration_workspace_alloc( nwork );
+    double val, err;
+    int rule;
+    size_t neval;
+
+    if      ( isinf(low)==-1 && isinf(hig)==+1 )
+        gsl_integration_qagi( &F, 
+                             epsabs, epsrel, nwork,
+                             work, &val, &err );
+    else if ( isinf(low)==-1 )
+        gsl_integration_qagil( &F, hig,
+                             epsabs, epsrel, nwork,
+                             work, &val, &err );
+    else if ( isinf(hig)==+1 )
+        gsl_integration_qagiu( &F, low,
+                             epsabs, epsrel, nwork,
+                             work, &val, &err );
+    else if ( mode==0 )
+        gsl_integration_qng( &F, low, hig,
+                             epsabs, epsrel,
+                             &val, &err, &neval );
+    else if ( mode>0 && mode<7 ){
+        switch( mode ){
+        case 1: rule = GSL_INTEG_GAUSS61; break;
+        case 2: rule = GSL_INTEG_GAUSS51; break;
+        case 3: rule = GSL_INTEG_GAUSS41; break;
+        case 4: rule = GSL_INTEG_GAUSS31; break;
+        case 5: rule = GSL_INTEG_GAUSS21; break;
+        case 6: rule = GSL_INTEG_GAUSS15; break;
+        }
+        gsl_integration_qag( &F, low, hig,
+                             epsabs, epsrel, nwork,
+                             rule, work, &val, &err );
+    }
+    else if ( mode==7 )
+        gsl_integration_qags( &F, low, hig,
+                              epsabs, epsrel, nwork,
+                              work, &val, &err );
+    else
+        throw string( "invalid mode in NumericIntegral" );
+
+    gsl_integration_workspace_free( work );
+    return val;
+}
diff --git a/src/mystd.h b/src/mystd.h
index b73e5b0f..14e97244 100644
--- a/src/mystd.h
+++ b/src/mystd.h
@@ -58,4 +58,10 @@ namespace mystd {
                      const char* mod, string *fname=0);
     int freadln(ifstream *f, string *s);
     int freadln(FILE *fd, string *s);
+
+    // integration
+    double Integrate( double (*func_) (double, void*), void *data_, 
+                      const double low, const double hig,
+                      const uint mode, const double epsabs,
+                      const double epsrel );
 }
diff --git a/src/readln.cpp b/src/readln.cpp
index adb4d3f7..94b4bb0e 100644
--- a/src/readln.cpp
+++ b/src/readln.cpp
@@ -48,7 +48,7 @@ namespace NRead {
     int iofmac( const string& in );
     double dofmac( const string& in );
     string wofmac( const string& in );
-    bool empty();
+    bool stack_empty();
 
     // internals, used only in this file:
     bool initialized=0;
@@ -173,7 +173,7 @@ string NRead::wofmac( const string& in )
 
 //! Anything left on input stack?
 
-bool NRead::empty()
+bool NRead::stack_empty()
 {
     return halfline=="";
 }
diff --git a/src/readln.h b/src/readln.h
index 5565b210..fddb8b1e 100644
--- a/src/readln.h
+++ b/src/readln.h
@@ -4,14 +4,11 @@ namespace NRead {
     /** everything must be declared a second time in readln.cpp **/
 
     string readln(const string&); // all read requests pass here ?
-    string readwd(const string&); // all read requests pass here ?
+    string readwd(const string&);
     void clear(void);
-//	inline string readln(char *prompt) { return readln(string(prompt)); };
-//	inline string readwd(char *prompt) { return readwd(string(prompt)); };
     string exemac(const string in);
-    inline string exemac(const char *in) { return exemac(string(in)); };
     int iofmac( const string& in );
     double dofmac( const string& in );
     string wofmac( const string& in );
-    bool empty( void );
+    bool stack_empty( void );
 };
-- 
GitLab