- diff() is now only defined on classes ex and basic, where it handles
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 2 Feb 2000 18:49:29 +0000 (18:49 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 2 Feb 2000 18:49:29 +0000 (18:49 +0000)
  higher derivatives.  derivative() is now the method to be implemented
  by the user that does single derivatives, it is protected.
- Implemented some very clumpsy automatic generation of ginaccint.
  It is ugly because we have to compile libginac without namespace GiNaC.
- Fixed some wrong logic in numeric::power().

47 files changed:
Makefile.in
NEWS
check/Makefile.in
cint/Makefile.am
cint/Makefile.in
cint/ginaccint.1
cint/ginaccint.bin.cpp [moved from cint/ginaccint.cpp with 76% similarity]
cint/ginaccint.in [new file with mode: 0644]
configure
configure.in
doc/Makefile.in
doc/reference/Makefile.in
doc/tutorial/Makefile.in
doc/tutorial/ginac.texi
ginac/Makefile.am
ginac/Makefile.in
ginac/add.cpp
ginac/add.h
ginac/basic.cpp
ginac/basic.h
ginac/constant.cpp
ginac/constant.h
ginac/container.pl
ginac/diff.cpp [deleted file]
ginac/ex.cpp
ginac/expairseq.cpp
ginac/expairseq.h
ginac/function.pl
ginac/indexed.cpp
ginac/indexed.h
ginac/inifcns_gamma.cpp
ginac/inifcns_trans.cpp
ginac/inifcns_zeta.cpp
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/pseries.h
ginac/symbol.cpp
ginac/symbol.h
ginac/utils.h
ginsh/Makefile.in

index e5818e3..a61a6e7 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -358,7 +359,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
diff --git a/NEWS b/NEWS
index 5ac7e54..6dba354 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,5 +13,8 @@ This file records noteworthy changes.
   info_flags::integer and -::cinteger work similarly, the same
   holds for types like info_flags::rational_polynomial.
 
-0.5.0 ()
+0.5.0 (?? February 2000)
 * Expressions can be written ("archived") to files and read therefrom.
+* Addition of GiNaC-cint, which lets you write complete programs in
+  an interactive shell-like manner in your favoured programming
+  language (C++).
index 539353c..ce23045 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -253,7 +254,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
index bc1690f..0ad1bd5 100644 (file)
@@ -1,19 +1,19 @@
 ## Process this file with automake to produce Makefile.in
 
-bin_PROGRAMS = ginaccint
-noinst_LIBRARIES = libginac.a
-ginaccint_SOURCES = ginaccint.cpp dummies.cpp dummies.h
+bin_PROGRAMS = ginaccint.bin ginaccint
+noinst_LTLIBRARIES = libginac.la
+ginaccint_bin_SOURCES = ginaccint.bin.cpp dummies.cpp dummies.h
 man_MANS = ginaccint.1
 
 # Build a modified library in the ginac-subdir and put it into the cint-subdir:
-libginac.a:
+libginac.la:
        (cd ../ginac && \
          $(MAKE) clean; \
          $(MAKE) CXXFLAGS="$$CXXFLAGS -DNO_NAMESPACE_GINAC" && \
          $(MAKE) install-libLTLIBRARIES prefix=`pwd`/../cint libdir=`pwd`/../cint && \
          $(MAKE) clean)
 
-ginaccint: libginac.a ginaccint.cpp
+ginaccint.bin: libginac.la ginaccint.bin.cpp
        $(MAKE) -f Makefile.makecint
 
 EXTRA_DIST = dummies.pl
@@ -23,4 +23,9 @@ $(srcdir)/dummies.h $(srcdir)/dummies.cpp: $(srcdir)/dummies.pl
        cd $(srcdir) && perl dummies.pl
 
 # Force build of headers before compilation
-$(srcdir)/ginaccint.cpp: $(srcdir)/dummies.h
+$(srcdir)/ginaccint.bin.cpp: $(srcdir)/dummies.h
+
+# Force make clean to call Makecint's own Makefile
+makecint_clean:
+       (if [ -f Makefile.makecint ]; then $(MAKE) -f Makefile.makecint clean; fi)
+clean: makecint_clean
index c1b96b2..c4a8267 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -103,29 +104,34 @@ TUTORIAL_TARGETS = @TUTORIAL_TARGETS@
 VERSION = @VERSION@
 YACC = @YACC@
 
-bin_PROGRAMS = ginaccint
-noinst_LIBRARIES = libginac.a
-ginaccint_SOURCES = ginaccint.cpp dummies.cpp dummies.h
+bin_PROGRAMS = ginaccint.bin ginaccint
+noinst_LTLIBRARIES = libginac.la
+ginaccint_bin_SOURCES = ginaccint.bin.cpp dummies.cpp dummies.h
 man_MANS = ginaccint.1
 
 EXTRA_DIST = dummies.pl
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
-CONFIG_CLEAN_FILES = 
-LIBRARIES =  $(noinst_LIBRARIES)
+CONFIG_CLEAN_FILES =  ginaccint
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
 
 
 DEFS = @DEFS@ -I. -I$(srcdir) -I..
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-libginac_a_LIBADD = 
-libginac_a_SOURCES = libginac.a.c
-libginac_a_OBJECTS =  libginac.a.o
-AR = ar
+libginac_la_LDFLAGS = 
+libginac_la_LIBADD = 
+libginac_la_SOURCES = libginac.la.c
+libginac_la_OBJECTS =  libginac.la.lo
 PROGRAMS =  $(bin_PROGRAMS)
 
-ginaccint_OBJECTS =  ginaccint.o dummies.o
+ginaccint_bin_OBJECTS =  ginaccint.bin.o dummies.o
+ginaccint_bin_LDADD = $(LDADD)
+ginaccint_bin_DEPENDENCIES = 
+ginaccint_bin_LDFLAGS = 
+ginaccint_SOURCES = ginaccint.c
+ginaccint_OBJECTS =  ginaccint.o
 ginaccint_LDADD = $(LDADD)
 ginaccint_DEPENDENCIES = 
 ginaccint_LDFLAGS = 
@@ -143,16 +149,17 @@ man1dir = $(mandir)/man1
 MANS = $(man_MANS)
 
 NROFF = nroff
-DIST_COMMON =  Makefile.am Makefile.in
+DIST_COMMON =  Makefile.am Makefile.in ginaccint.in
 
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
 GZIP_ENV = --best
-DEP_FILES =  .deps/dummies.P .deps/ginaccint.P .deps/libginac.a.P
-SOURCES = libginac.a.c $(ginaccint_SOURCES)
-OBJECTS = libginac.a.o $(ginaccint_OBJECTS)
+DEP_FILES =  .deps/dummies.P .deps/ginaccint.P .deps/ginaccint.bin.P \
+.deps/libginac.la.P
+SOURCES = libginac.la.c $(ginaccint_bin_SOURCES) ginaccint.c
+OBJECTS = libginac.la.lo $(ginaccint_bin_OBJECTS) ginaccint.o
 
 all: all-redirect
 .SUFFIXES:
@@ -164,15 +171,17 @@ Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
        cd $(top_builddir) \
          && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
+ginaccint: $(top_builddir)/config.status ginaccint.in
+       cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
-mostlyclean-noinstLIBRARIES:
+mostlyclean-noinstLTLIBRARIES:
 
-clean-noinstLIBRARIES:
-       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
 
-distclean-noinstLIBRARIES:
+distclean-noinstLTLIBRARIES:
 
-maintainer-clean-noinstLIBRARIES:
+maintainer-clean-noinstLTLIBRARIES:
 
 .s.o:
        $(COMPILE) -c $<
@@ -230,6 +239,10 @@ uninstall-binPROGRAMS:
        list='$(bin_PROGRAMS)'; for p in $$list; do \
          rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
        done
+
+ginaccint: $(ginaccint_OBJECTS) $(ginaccint_DEPENDENCIES)
+       @rm -f ginaccint
+       $(LINK) $(ginaccint_LDFLAGS) $(ginaccint_OBJECTS) $(ginaccint_LDADD) $(LIBS)
 .cpp.o:
        $(CXXCOMPILE) -c $<
 .cpp.lo:
@@ -316,7 +329,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@@ -393,7 +406,7 @@ install-am: all-am
 install: install-am
 uninstall-am: uninstall-binPROGRAMS uninstall-man
 uninstall: uninstall-am
-all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS)
 all-redirect: all-am
 install-strip:
        $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
@@ -410,26 +423,26 @@ distclean-generic:
        -rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
 maintainer-clean-generic:
-mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+mostlyclean-am:  mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
                mostlyclean-libtool mostlyclean-binPROGRAMS \
                mostlyclean-tags mostlyclean-depend mostlyclean-generic
 
 mostlyclean: mostlyclean-am
 
-clean-am:  clean-noinstLIBRARIES clean-compile clean-libtool \
+clean-am:  clean-noinstLTLIBRARIES clean-compile clean-libtool \
                clean-binPROGRAMS clean-tags clean-depend clean-generic \
                mostlyclean-am
 
 clean: clean-am
 
-distclean-am:  distclean-noinstLIBRARIES distclean-compile \
+distclean-am:  distclean-noinstLTLIBRARIES distclean-compile \
                distclean-libtool distclean-binPROGRAMS distclean-tags \
                distclean-depend distclean-generic clean-am
        -rm -f libtool
 
 distclean: distclean-am
 
-maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+maintainer-clean-am:  maintainer-clean-noinstLTLIBRARIES \
                maintainer-clean-compile maintainer-clean-libtool \
                maintainer-clean-binPROGRAMS maintainer-clean-tags \
                maintainer-clean-depend maintainer-clean-generic \
@@ -439,8 +452,8 @@ maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
 
 maintainer-clean: maintainer-clean-am
 
-.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
-clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
 mostlyclean-compile distclean-compile clean-compile \
 maintainer-clean-compile mostlyclean-libtool distclean-libtool \
 clean-libtool maintainer-clean-libtool mostlyclean-binPROGRAMS \
@@ -457,14 +470,14 @@ maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
 # Build a modified library in the ginac-subdir and put it into the cint-subdir:
-libginac.a:
+libginac.la:
        (cd ../ginac && \
          $(MAKE) clean; \
          $(MAKE) CXXFLAGS="$$CXXFLAGS -DNO_NAMESPACE_GINAC" && \
          $(MAKE) install-libLTLIBRARIES prefix=`pwd`/../cint libdir=`pwd`/../cint && \
          $(MAKE) clean)
 
-ginaccint: libginac.a ginaccint.cpp
+ginaccint.bin: libginac.la ginaccint.bin.cpp
        $(MAKE) -f Makefile.makecint
 
 # Files which are generated by perl scripts
@@ -472,7 +485,12 @@ $(srcdir)/dummies.h $(srcdir)/dummies.cpp: $(srcdir)/dummies.pl
        cd $(srcdir) && perl dummies.pl
 
 # Force build of headers before compilation
-$(srcdir)/ginaccint.cpp: $(srcdir)/dummies.h
+$(srcdir)/ginaccint.bin.cpp: $(srcdir)/dummies.h
+
+# Force make clean to call Makecint's own Makefile
+makecint_clean:
+       (if [ -f Makefile.makecint ]; then $(MAKE) -f Makefile.makecint clean; fi)
+clean: makecint_clean
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
index c74405a..0ce268b 100644 (file)
@@ -40,13 +40,29 @@ or a semicolon
 .RB ( ; )
 is encountered.
 
+.SS SPECIAL COMMANDS
+.IP "\fB.cint\fR"
+Switch to cint interactive mode.
+.IP "\fB.function\fR"
 
-.SS FUNCTION DEFINITIONS
-GiNaC-cint must be put into a special mode in order to define a
-function.  This is done with the command
-.RB .function .
-After that any function definition in valid C++ syntax may be typed
-in.  It becomes immediatly available for usage.
+Allow a function definition in interactive mode.  GiNaC-cint must be
+put into a special mode in order to define a function. After that any
+function definition in valid C++ syntax may be typed in.  It becomes
+immediatly available for usage.
+
+.IP "\fBquit;\fR"
+Exit from GiNaC-Cint.  Same as 
+.BR "exit;" ,
+.BR "bye;" ,
+.BR ".q" ,
+.BR ".quit" ,
+.BR ".exit " or
+.BR ".bye" .
+
+.IP "\fBOut\fP\fInum\fP"
+Returns the expression whose output was marked
+.BR "\fBOut\fP\fInum\fP" 
+as a handle.
 
 .SH EXAMPLES
 .nf
@@ -55,20 +71,32 @@ GiNaC> ex a = pow(x,2)-x-2;
 GiNaC> ex b = pow(x+1,2);
 GiNaC> ex s = a/b;
 GiNaC> s.diff(x);
-out1   -2*(1+x)^(-3)*(-2-x+x^2)+(-1+2*x)*(1+x)^(-2)
+Out1 = -2*(1+x)^(-3)*(-2-x+x^2)+(-1+2*x)*(1+x)^(-2)
 GiNaC> s.normal();
-out2   (-2+x)*(1+x)^(-1)
+Out2 = (-2+x)*(1+x)^(-1)
+GiNaC> for (int i=2; i<20; i+=2) {
+     >     cout << "B(" << i << ") == " << bernoulli(i) << endl;
+     > }
+B(2)==1/6
+B(4)==-1/30
+B(6)==1/42
+B(8)==-1/30
+B(10)==5/66
+B(12)==-691/2730
+B(14)==7/6
+B(16)==-3617/510
+B(18)==43867/798
 GiNaC> .function
 next expression can be a function definition
 GiNaC> ex EulerNumber(unsigned n)
      > {
      >     symbol x;
-     >     ex generator = pow(cosh(x),-1);
+     >     const ex generator = pow(cosh(x),-1);
      >     return generator.diff(x,n).subs(x==0);
      > }
 creating file /tmp/ginac26197caa
 GiNaC> EulerNumber(42);
-out3   -10364622733519612119397957304745185976310201
+Out3 = -10364622733519612119397957304745185976310201
 GiNaC> quit;
 .fi
 
@@ -85,13 +113,17 @@ you encounter as far as possible and contact Masaharu Goto
 
 .SH AUTHOR
 .TP
-The GiNaC Group:
+The GiNaC Group
 .br
 Christian Bauer <Christian.Bauer@uni-mainz.de>
 .br
 Alexander Frink <Alexander.Frink@uni-mainz.de>
 .br
 Richard Kreckel <Richard.Kreckel@uni-mainz.de>
+.TP
+Agilent Technologies Japan
+.br
+Masaharu Goto <MXJ02154@niftyserve.or.jp>
 .SH SEE ALSO
 GiNaC Tutorial \- An open framework for symbolic computation within the
 C++ programming language
similarity index 76%
rename from cint/ginaccint.cpp
rename to cint/ginaccint.bin.cpp
index 724bffb..52f3ef4 100644 (file)
@@ -4,7 +4,8 @@
 #include <string>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ginac/ginac.h>
+#include "ginac/ginac.h"
+#include "config.h"
 #include <list>
 
 extern "C" G__value G__exec_tempfile G__P((char *file));
@@ -15,7 +16,7 @@ extern "C" void G__store_undo_position(void);
 #include <strstream>
 
 template<class T>
-string ToString(T const & t)
+string ToString(const T & t)
 {
     char buf[256];
     ostrstream(buf,sizeof(buf)) << t << ends;
@@ -46,28 +47,28 @@ void sigterm_handler(int n)
 
 bool is_whitespace_char(char c)
 {
-    return ((c==' ')||(c=='\t')||(c=='\n')||(c=='\r')); 
+    return ((c==' ') || (c=='\t') || (c=='\n') || (c=='\r')); 
 }
 
 char first_non_whitespace_char(char const * s)
 {
-    int l=strlen(s);
-    int pos=0;
+    int l = strlen(s);
+    int pos = 0;
     while ((pos<l)&&is_whitespace_char(s[pos])) pos++;
     return s[pos];
 }    
 
 char last_non_whitespace_char(char const * s)
 {
-    int pos=strlen(s)-1;
-    while ((pos>=0)&&is_whitespace_char(s[pos])) pos--;
+    int pos = strlen(s)-1;
+    while ((pos>=0) && is_whitespace_char(s[pos])) pos--;
     return s[pos];
 }    
 
 string strip_whitespace(string const & s)
 {
     string s2;
-    int l=s.length();
+    int l = s.length();
     for (int pos=0; pos<l; ++pos) {
         if (!is_whitespace_char(s[pos])) s2 += s[pos];
     }
@@ -77,7 +78,7 @@ string strip_whitespace(string const & s)
 G__value exec_tempfile(string const & command)
 {
     G__value retval;
-    char *tmpfilename=tempnam(NULL,"ginac");
+    char *tmpfilename = tempnam(NULL,"ginac");
     ofstream fout;
     fout.open(tmpfilename);
     fout << "{" << endl << command << endl << "}" << endl;
@@ -92,7 +93,7 @@ G__value exec_tempfile(string const & command)
 
 char * process_permanentfile(string const & command)
 {
-    char *tmpfilename=tempnam(NULL,"ginac");
+    char *tmpfilename = tempnam(NULL,"ginac");
     cout << "creating file " << tmpfilename << endl;
     ofstream fout;
     fout.open(tmpfilename);
@@ -107,27 +108,30 @@ char * process_permanentfile(string const & command)
 void process_tempfile(string const & command)
 {
 #ifdef OBSCURE_CINT_HACK
-    static G__value ref_symbol=exec_tempfile("symbol ginac_cint_internal_symbol; ginac_cint_internal_symbol;");
-    static G__value ref_ex=exec_tempfile("ex ginac_cint_internal_ex; ginac_cint_internal_ex;");
-    static G__value ref_function=exec_tempfile("sin(ginac_cint_internal_symbol);");
-    static G__value ref_power=exec_tempfile("power(ginac_cint_internal_symbol,ginac_cint_internal_symbol);");
+    static G__value ref_symbol = exec_tempfile("symbol ginac_cint_internal_symbol; ginac_cint_internal_symbol;");
+    static G__value ref_ex = exec_tempfile("ex ginac_cint_internal_ex; ginac_cint_internal_ex;");
+    static G__value ref_function = exec_tempfile("sin(ginac_cint_internal_symbol);");
+    static G__value ref_power = exec_tempfile("power(ginac_cint_internal_symbol,ginac_cint_internal_symbol);");
 #endif // def OBSCURE_CINT_HACK
 
-    G__value retval=exec_tempfile(command);
+    G__value retval = exec_tempfile(command);
 
 #ifdef OBSCURE_CINT_HACK
 
-    #define TYPES_EQUAL(A,B) (((A).type==(B).type)&&((A).tagnum==(B).tagnum))
+    #define TYPES_EQUAL(A,B) (((A).type==(B).type) && ((A).tagnum==(B).tagnum))
     
-    static unsigned out_count=0;
+    static unsigned out_count = 0;
     if (TYPES_EQUAL(retval,ref_ex)) {
         if (ex::last_created_or_assigned_bp_can_be_converted_to_ex()) {
-            string varname="out"+ToString(++out_count);
+            string varname = "Out"+ToString(++out_count);
+            //string varfill;
+            //for (int i=4-int(log10(out_count)); i>0; --i)
+            //    varfill += ' ';
             exec_tempfile("ex "+varname+"(*ex::last_created_or_assigned_bp);\n"
                           +"LLLAST=LLAST;\n"
                           +"LLAST=LAST;\n"
                           +"LAST="+varname+";\n"
-                          +"cout << \""+varname+"   \" << "+varname+" << endl << endl;"); 
+                          +"cout << \""+varname+" = \" << "+varname+" << endl << endl;");
         } else {
             cout << "warning: last_created_or_assigned_bp modified 0 or not evaluated or not dynallocated" << endl;
         }
@@ -137,14 +141,13 @@ void process_tempfile(string const & command)
 
 void greeting(void)
 {
-    cout << "Welcome to GiNaC-cint V" << VERSION << endl;
+    cout << "Welcome to GiNaC-cint (" << PACKAGE << " V" << VERSION << ")" << endl;
     cout << "This software is provided \"as is\" without any warranty.  Copyright of Cint is" << endl
          << "owned by Agilent Technologies Japan and Masaharu Goto.  Registration is" << endl
          << "  __,  _______  requested, at this moment, for commercial use.  Send e-mail to" << endl
          << " (__) *       | <MXJ02154@niftyserve.or.jp>.  The registration is free." << endl
-         << "  ._) i N a C | The GiNaC framework is Copyright by Johannes Gutenberg Univ." << endl
+         << "  ._) i N a C | The GiNaC framework is Copyright by Johannes Gutenberg Univ.," << endl
          << "<-------------' Germany and licensed under the terms and conditions of the GPL." << endl << endl;
-    cout << "To quit, type 'quit;', 'exit;', 'bye;', '.q', '.quit', '.exit' or '.bye'" << endl;
 }
 
 int main(void) 
@@ -162,18 +165,18 @@ int main(void)
     exec_tempfile("#include <string>\n");
     exec_tempfile("ex LAST,LLAST,LLLAST;\n");
     
-    bool quit=false;
+    bool quit = false;
     bool next_command_is_function=false;    
     while (!quit) {
         strcpy(prompt,"GiNaC> ");
-        int open_braces=0;
+        int open_braces = 0;
         bool end_of_command=false;
         string command;
         while (!end_of_command) {
-            line=G__input(prompt);
+            line = G__input(prompt);
         
             int pos = 0;
-           bool double_quote=false;
+            bool double_quote=false;
             bool single_quote=false;
             while(line[pos]!='\0') {
                 switch(line[pos]) {
@@ -184,10 +187,10 @@ int main(void)
                     if (!double_quote) single_quote = !single_quote;
                     break;
                 case '{':
-                    if ((!single_quote)&&(!double_quote)) open_braces++;
+                    if ((!single_quote) && (!double_quote)) open_braces++;
                     break;
                 case '}':
-                    if ((!single_quote)&&(!double_quote)) open_braces--;
+                    if ((!single_quote) && (!double_quote)) open_braces--;
                     break;
                 }
                 pos++;
@@ -212,7 +215,7 @@ int main(void)
             (stripped_command==".quit")||
             (stripped_command==".exit")||
             (stripped_command==".bye")) {
-            quit=true;
+            quit = true;
         } else if (stripped_command==".function") {
             cout << "next expression can be a function definition" << endl;
             next_command_is_function=true;
@@ -224,9 +227,9 @@ int main(void)
         } else if (command[0]=='.') {
             cout << "special command (TBD): " << command << endl;
         } else {
-           // cout << "now processing: " << command << endl;
+            // cout << "now processing: " << command << endl;
             if (next_command_is_function) {
-                next_command_is_function=false;
+                next_command_is_function = false;
                 filenames.push_back(process_permanentfile(command));
             } else {
                 process_tempfile(command);
diff --git a/cint/ginaccint.in b/cint/ginaccint.in
new file mode 100644 (file)
index 0000000..2128a14
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+binprog=`basename $0`".bin"
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+config_cintsysdir=@CINTSYSDIR@
+
+if [ "x$CINTSYSDIR" = "x" ]; then
+  CINTSYSDIR=$config_cintsysdir
+  export CINTSYSDIR
+fi
+exec ${bindir}/${binprog}
index fe76b78..4876d44 100755 (executable)
--- a/configure
+++ b/configure
@@ -2942,10 +2942,10 @@ fi
   if [ "$CINT" -a "$MAKECINT" ]; then
     echo "$ac_t""creating cint/Makefile" 1>&6
     (cd cint && \
-    $MAKECINT -mk Makefile.makecint -o ginaccint -m \
+    $MAKECINT -mk Makefile.makecint -o ginaccint.bin -m \
       -D OBSCURE_CINT_HACK -D NO_NAMESPACE_GINAC \
       -I .. -I $CINTSYSDIR -m -H ../ginac/ginac.h dummies.h \
-      -C++ dummies.cpp -C++ ginaccint.cpp \
+      -C++ dummies.cpp -C++ ginaccint.bin.cpp \
       -l ./libginac.a -lcln -cint -M0x10; \
     cd ..)
     LIBGINACCINT="libginac.a"
@@ -2957,6 +2957,7 @@ fi
 
 
 
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -3070,6 +3071,7 @@ doc/Makefile
 doc/tutorial/Makefile
 doc/reference/Makefile
 cint/Makefile
+cint/ginaccint
  config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
@@ -3163,6 +3165,7 @@ s%@TUTORIAL_TARGETS@%$TUTORIAL_TARGETS%g
 s%@REFERENCE_TARGETS@%$REFERENCE_TARGETS%g
 s%@CINT@%$CINT%g
 s%@MAKECINT@%$MAKECINT%g
+s%@CINTSYSDIR@%$CINTSYSDIR%g
 s%@LIBGINACCINT@%$LIBGINACCINT%g
 s%@GINACCINTDIR@%$GINACCINTDIR%g
 
@@ -3217,6 +3220,7 @@ doc/Makefile
 doc/tutorial/Makefile
 doc/reference/Makefile
 cint/Makefile
+cint/ginaccint
 "}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
@@ -3390,7 +3394,7 @@ cat >> $CONFIG_STATUS <<EOF
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
-chmod +x ginac-config
+chmod +x ginac-config cint/ginaccint
 exit 0
 EOF
 chmod +x $CONFIG_STATUS
index 9249f9d..e962725 100644 (file)
@@ -163,10 +163,10 @@ if [[ "x$with_cint" != "xno" ]]; then
   if [[ "$CINT" -a "$MAKECINT" ]]; then
     AC_MSG_RESULT([creating cint/Makefile])
     (cd cint && \
-    $MAKECINT -mk Makefile.makecint -o ginaccint -m \
+    $MAKECINT -mk Makefile.makecint -o ginaccint.bin -m \
       -D OBSCURE_CINT_HACK -D NO_NAMESPACE_GINAC \
       -I .. -I $CINTSYSDIR -m -H ../ginac/ginac.h dummies.h \
-      -C++ dummies.cpp -C++ ginaccint.cpp \
+      -C++ dummies.cpp -C++ ginaccint.bin.cpp \
       -l ./libginac.a -lcln -cint -M0x10; \
     cd ..)
     LIBGINACCINT="libginac.a"
@@ -175,6 +175,7 @@ if [[ "x$with_cint" != "xno" ]]; then
     AC_MSG_ERROR([Cannot configure GiNaC-cint])
   fi
 fi
+AC_SUBST(CINTSYSDIR)
 AC_SUBST(LIBGINACCINT)
 AC_SUBST(GINACCINTDIR)
 
@@ -191,5 +192,6 @@ doc/Makefile
 doc/tutorial/Makefile
 doc/reference/Makefile
 cint/Makefile
-], [chmod +x ginac-config])
+cint/ginaccint
+], [chmod +x ginac-config cint/ginaccint])
 echo "Configuration done. Now type \"make\"."
index e201116..6fa6ecc 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -273,7 +274,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
index 47c0ee4..d9e8155 100644 (file)
@@ -67,6 +67,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -169,7 +170,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
index dcde437..16fc4f9 100644 (file)
@@ -66,6 +66,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -326,7 +327,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
index 04b8908..4cbf739 100644 (file)
@@ -215,11 +215,11 @@ generates Hermite polynomials in a specified free variable.
 #include <ginac/ginac.h>
 using namespace GiNaC;
 
-ex HermitePoly(symbol x, int deg)
+ex HermitePoly(const symbol & x, int n)
 @{
-    ex HKer=exp(-pow(x,2));
-    // uses the identity H_n(x) == (-1)^n exp(x^2) (d/dx)^n exp(-x^2) 
-    return normal(pow(-1,deg) * diff(HKer, x, deg) / HKer);
+    ex HKer=exp(-pow(x, 2));
+    // uses the identity H_n(x) == (-1)^n exp(x^2) (d/dx)^n exp(-x^2)
+    return normal(pow(-1, n) * diff(HKer, x, n) / HKer);
 @}
 
 int main()
@@ -422,19 +422,21 @@ installation.
 @c    node-name, next, previous, up
 @section Prerequisites
 
-In order to install GiNaC on your system, some prerequisites need
-to be met.  First of all, you need to have a C++-compiler adhering to
-the ANSI-standard @cite{ISO/IEC 14882:1998(E)}.  We used @acronym{GCC} for
+In order to install GiNaC on your system, some prerequisites need to be
+met.  First of all, you need to have a C++-compiler adhering to the
+ANSI-standard @cite{ISO/IEC 14882:1998(E)}.  We used @acronym{GCC} for
 development so if you have a different compiler you are on your own.
 For the configuration to succeed you need a Posix compliant shell
 installed in @file{/bin/sh}, GNU @command{bash} is fine.  Perl is needed
-by the built process as well, since some of the source files are automatically
-generated by Perl scripts.  Last but not least, Bruno Haible's library
-@acronym{CLN} is extensively used and needs to be installed on your system.
-Please get it from @uref{ftp://ftp.santafe.edu/pub/gnu/} or from
-@uref{ftp://ftp.ilog.fr/pub/Users/haible/gnu/, Bruno Haible's FTP site}
-(it is covered by GPL) and install it prior to trying to install GiNaC.
-The configure script checks if it can find it and if it cannot
+by the built process as well, since some of the source files are
+automatically generated by Perl scripts.  Last but not least, Bruno
+Haible's library @acronym{CLN} is extensively used and needs to be
+installed on your system.  Please get it either from
+@uref{ftp://ftp.santafe.edu/pub/gnu/}, from
+@uref{ftp://ftpthep.physik.uni-mainz.de/pub/gnu/, GiNaC's FTP site} or
+from @uref{ftp://ftp.ilog.fr/pub/Users/haible/gnu/, Bruno Haible's FTP
+site} (it is covered by GPL) and install it prior to trying to install
+GiNaC.  The configure script checks if it can find it and if it cannot
 it will refuse to continue.
 
 
@@ -1536,7 +1538,7 @@ using namespace GiNaC;
 ex EulerNumber(unsigned n)
 @{
     symbol x;
-    ex generator = pow(cosh(x),-1);
+    const ex generator = pow(cosh(x),-1);
     return generator.diff(x,n).subs(x==0);
 @}
 
index 2712309..e0cf87d 100644 (file)
@@ -1,8 +1,8 @@
 ## Process this file with automake to produce Makefile.in
 
 lib_LTLIBRARIES = libginac.la
-libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp diff.cpp \
-  ex.cpp expairseq.cpp exprseq.cpp fail.cpp function.cpp inifcns.cpp \
+libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp ex.cpp \
+  expairseq.cpp exprseq.cpp fail.cpp function.cpp inifcns.cpp \
   inifcns_trans.cpp inifcns_zeta.cpp inifcns_gamma.cpp matrix.cpp mul.cpp \
   normal.cpp numeric.cpp operators.cpp power.cpp registrar.cpp relational.cpp \
   symbol.cpp pseries.cpp utils.cpp ncmul.cpp clifford.cpp structure.cpp \
index 7fa0a4e..e9eff67 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -104,7 +105,7 @@ VERSION = @VERSION@
 YACC = @YACC@
 
 lib_LTLIBRARIES = libginac.la
-libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp diff.cpp   ex.cpp expairseq.cpp exprseq.cpp fail.cpp function.cpp inifcns.cpp   inifcns_trans.cpp inifcns_zeta.cpp inifcns_gamma.cpp matrix.cpp mul.cpp   normal.cpp numeric.cpp operators.cpp power.cpp registrar.cpp relational.cpp   symbol.cpp pseries.cpp utils.cpp ncmul.cpp clifford.cpp structure.cpp   color.cpp indexed.cpp idx.cpp isospin.cpp exprseq_suppl.cpp lst.cpp   lst_suppl.cpp simp_lor.cpp coloridx.cpp lorentzidx.cpp lortensor.cpp   debugmsg.h utils.h 
+libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp ex.cpp   expairseq.cpp exprseq.cpp fail.cpp function.cpp inifcns.cpp   inifcns_trans.cpp inifcns_zeta.cpp inifcns_gamma.cpp matrix.cpp mul.cpp   normal.cpp numeric.cpp operators.cpp power.cpp registrar.cpp relational.cpp   symbol.cpp pseries.cpp utils.cpp ncmul.cpp clifford.cpp structure.cpp   color.cpp indexed.cpp idx.cpp isospin.cpp exprseq_suppl.cpp lst.cpp   lst_suppl.cpp simp_lor.cpp coloridx.cpp lorentzidx.cpp lortensor.cpp   debugmsg.h utils.h 
 
 libginac_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)   -release $(LT_RELEASE)
 
@@ -123,13 +124,13 @@ CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 libginac_la_LIBADD = 
-libginac_la_OBJECTS =  add.lo archive.lo basic.lo constant.lo diff.lo \
-ex.lo expairseq.lo exprseq.lo fail.lo function.lo inifcns.lo \
-inifcns_trans.lo inifcns_zeta.lo inifcns_gamma.lo matrix.lo mul.lo \
-normal.lo numeric.lo operators.lo power.lo registrar.lo relational.lo \
-symbol.lo pseries.lo utils.lo ncmul.lo clifford.lo structure.lo \
-color.lo indexed.lo idx.lo isospin.lo exprseq_suppl.lo lst.lo \
-lst_suppl.lo simp_lor.lo coloridx.lo lorentzidx.lo lortensor.lo
+libginac_la_OBJECTS =  add.lo archive.lo basic.lo constant.lo ex.lo \
+expairseq.lo exprseq.lo fail.lo function.lo inifcns.lo inifcns_trans.lo \
+inifcns_zeta.lo inifcns_gamma.lo matrix.lo mul.lo normal.lo numeric.lo \
+operators.lo power.lo registrar.lo relational.lo symbol.lo pseries.lo \
+utils.lo ncmul.lo clifford.lo structure.lo color.lo indexed.lo idx.lo \
+isospin.lo exprseq_suppl.lo lst.lo lst_suppl.lo simp_lor.lo coloridx.lo \
+lorentzidx.lo lortensor.lo
 CXXFLAGS = @CXXFLAGS@
 CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -150,7 +151,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 TAR = tar
 GZIP_ENV = --best
 DEP_FILES =  .deps/add.P .deps/archive.P .deps/basic.P .deps/clifford.P \
-.deps/color.P .deps/coloridx.P .deps/constant.P .deps/diff.P .deps/ex.P \
+.deps/color.P .deps/coloridx.P .deps/constant.P .deps/ex.P \
 .deps/expairseq.P .deps/exprseq.P .deps/exprseq_suppl.P .deps/fail.P \
 .deps/function.P .deps/idx.P .deps/indexed.P .deps/inifcns.P \
 .deps/inifcns_gamma.P .deps/inifcns_trans.P .deps/inifcns_zeta.P \
@@ -294,7 +295,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
index 86703dd..5db2045 100644 (file)
@@ -414,6 +414,14 @@ ex add::simplify_ncmul(const exvector & v) const
 
 // protected
 
+/** Implementation of ex::diff() for a sum. It differentiates each term.
+ *  @see ex::diff */
+ex add::derivative(const symbol & s) const
+{
+    // D(a+b+c)=D(a)+D(b)+D(c)
+    return (new add(diffchildren(s)))->setflag(status_flags::dynallocated);
+}
+
 int add::compare_same_type(const basic & other) const
 {
     return inherited::compare_same_type(other);
index 176663f..4e5ec2b 100644 (file)
@@ -70,7 +70,6 @@ public:
     int ldegree(const symbol & s) const;
     ex coeff(const symbol & s, int n=1) const;
     ex eval(int level=0) const;
-    ex diff(const symbol & s) const;
     ex series(const symbol & s, const ex & point, int order) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
     numeric integer_content(void) const;
@@ -79,6 +78,7 @@ public:
     exvector get_indices(void) const;
     ex simplify_ncmul(const exvector & v) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
index e2a9320..43dbf33 100644 (file)
@@ -293,6 +293,27 @@ ex basic::subs(const lst & ls, const lst & lr) const
     return *this;
 }
 
+/** Default interface of nth derivative ex::diff(s, n).  It should be called
+ *  instead of ::derivative(s) for first derivatives and for nth derivatives it
+ *  just recurses down.
+ *
+ *  @param s symbol to differentiate in
+ *  @param nth order of differentiation
+ *  @see ex::diff */
+ex basic::diff(const symbol & s, unsigned nth) const
+{
+    // FIXME: Check if it is evaluated!
+    if (!nth)
+        return ex(*this);
+    ex ndiff = derivative(s);
+    while (!ndiff.is_zero() &&    // stop differentiating zeroes
+           nth>1) {
+        ndiff = ndiff.diff(s);
+        --nth;
+    }
+    return ndiff;
+}
+
 exvector basic::get_indices(void) const
 {
     return exvector(); // return an empty exvector
@@ -305,6 +326,15 @@ ex basic::simplify_ncmul(const exvector & v) const
 
 // protected
 
+/** Default implementation of ex::diff(). It simply throws an error message.
+ *
+ *  @exception logic_error (differentiation not supported by this type)
+ *  @see ex::diff */
+ex basic::derivative(const symbol & s) const
+{
+    throw(std::logic_error("differentiation not supported by this type"));
+}
+
 int basic::compare_same_type(const basic & other) const
 {
     return compare_pointers(this, &other);
@@ -349,6 +379,7 @@ ex basic::expand(unsigned options) const
     return this->setflag(status_flags::expanded);
 }
 
+
 //////////
 // non-virtual functions in this class
 //////////
index ebe10e6..4e9b517 100644 (file)
@@ -137,7 +137,6 @@ public: // only const functions please (may break reference counting)
     virtual ex collect(const symbol & s) const;
     virtual ex eval(int level=0) const;
     virtual ex evalf(int level=0) const;
-    virtual ex diff(const symbol & s) const;
     virtual ex series(const symbol & s, const ex & point, int order) const;
     virtual ex subs(const lst & ls, const lst & lr) const;
     virtual ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
@@ -147,6 +146,7 @@ public: // only const functions please (may break reference counting)
     virtual exvector get_indices(void) const;
     virtual ex simplify_ncmul(const exvector & v) const;
 protected: // non-const functions should be called from class ex only
+    virtual ex derivative(const symbol & s) const;
     virtual int compare_same_type(const basic & other) const;
     virtual bool is_equal_same_type(const basic & other) const;
     virtual unsigned return_type(void) const;
@@ -157,6 +157,7 @@ protected: // non-const functions should be called from class ex only
     // non-virtual functions in this class
 public:
     ex subs(const ex & e) const;
+    ex diff(const symbol & s, unsigned nth=1) const;
     int compare(const basic & other) const;
     bool is_equal(const basic & other) const;
     const basic & hold(void) const;
index cbf9030..b854309 100644 (file)
@@ -191,6 +191,14 @@ ex constant::evalf(int level) const
 
 // protected
 
+/** Implementation of ex::diff() for a constant. It always returns 0.
+ *
+ *  @see ex::diff */
+ex constant::derivative(const symbol & s) const
+{
+    return _ex0();
+}
+
 int constant::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_exactly_of_type(other, constant));
index c29ecf0..91ede28 100644 (file)
@@ -65,8 +65,8 @@ public:
     void printtree(ostream & os, unsigned indent) const;
     void printcsrc(ostream & os, unsigned type, unsigned upper_precedence=0) const;
     ex evalf(int level=0) const;
-    ex diff(const symbol & s) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     
index a66df7b..3a7f9bd 100755 (executable)
@@ -189,7 +189,7 @@ public:
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
-    ex diff(const symbol & s) const;
+    ex derivative(const symbol & s) const;
     ex subs(const lst & ls, const lst & lr) const;
 protected:
     int compare_same_type(const basic & other) const;
@@ -634,7 +634,7 @@ ex ${CONTAINER}::normal(lst &sym_lst, lst &repl_lst, int level) const
     return n.bp->basic::normal(sym_lst,repl_lst,level);
 }
 
-ex ${CONTAINER}::diff(const symbol & s) const
+ex ${CONTAINER}::derivative(const symbol & s) const
 {
     return this${CONTAINER}(diffchildren(s));
 }
diff --git a/ginac/diff.cpp b/ginac/diff.cpp
deleted file mode 100644 (file)
index 4b6e9c8..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/** @file diff.cpp
- *
- *  Implementation of symbolic differentiation in all of GiNaC's classes. */
-
-/*
- *  GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
- *
- *  This program 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 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program 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 this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <stdexcept>
-
-#include "basic.h"
-#include "ex.h"
-#include "add.h"
-#include "constant.h"
-#include "expairseq.h"
-#include "indexed.h"
-#include "inifcns.h"
-#include "mul.h"
-#include "ncmul.h"
-#include "numeric.h"
-#include "power.h"
-#include "relational.h"
-#include "pseries.h"
-#include "symbol.h"
-#include "utils.h"
-
-#ifndef NO_NAMESPACE_GINAC
-namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
-
-/** Default implementation of ex::diff(). It prints and error message and returns a fail object.
- *  @see ex::diff */
-ex basic::diff(const symbol & s) const
-{
-    throw(std::logic_error("differentiation not supported by this type"));
-}
-
-
-/** Implementation of ex::diff() for a numeric. It always returns 0.
- *
- *  @see ex::diff */
-ex numeric::diff(const symbol & s) const
-{
-    return _ex0();
-}
-
-
-/** Implementation of ex::diff() for single differentiation of a symbol.
- *  It returns 1 or 0.
- *
- *  @see ex::diff */
-ex symbol::diff(const symbol & s) const
-{
-    if (compare_same_type(s)) {
-        return _ex0();
-    } else {
-        return _ex1();
-    }
-}
-
-/** Implementation of ex::diff() for a constant. It always returns 0.
- *
- *  @see ex::diff */
-ex constant::diff(const symbol & s) const
-{
-    return _ex0();
-}
-
-/** Implementation of ex::diff() for multiple differentiation of a symbol.
- *  It returns the symbol, 1 or 0.
- *
- *  @param nth order of differentiation
- *  @see ex::diff */
-ex symbol::diff(const symbol & s, unsigned nth) const
-{
-    if (compare_same_type(s)) {
-        switch (nth) {
-        case 0:
-            return s;
-            break;
-        case 1:
-            return _ex1();
-            break;
-        default:
-            return _ex0();
-        }
-    } else {
-        return _ex1();
-    }
-}
-
-
-/** Implementation of ex::diff() for an indexed object. It always returns 0.
- *  @see ex::diff */
-ex indexed::diff(const symbol & s) const
-{
-        return _ex0();
-}
-
-
-/** Implementation of ex::diff() for an expairseq. It differentiates all elements of the sequence.
- *  @see ex::diff */
-ex expairseq::diff(const symbol & s) const
-{
-    return thisexpairseq(diffchildren(s),overall_coeff);
-}
-
-
-/** Implementation of ex::diff() for a sum. It differentiates each term.
- *  @see ex::diff */
-ex add::diff(const symbol & s) const
-{
-    // D(a+b+c)=D(a)+D(b)+D(c)
-    return (new add(diffchildren(s)))->setflag(status_flags::dynallocated);
-}
-
-
-/** Implementation of ex::diff() for a product. It applies the product rule.
- *  @see ex::diff */
-ex mul::diff(const symbol & s) const
-{
-    exvector new_seq;
-    new_seq.reserve(seq.size());
-
-    // D(a*b*c)=D(a)*b*c+a*D(b)*c+a*b*D(c)
-    for (unsigned i=0; i!=seq.size(); i++) {
-        epvector sub_seq=seq;
-        sub_seq[i] = split_ex_to_pair(sub_seq[i].coeff*
-                                      power(sub_seq[i].rest,sub_seq[i].coeff-1)*
-                                      sub_seq[i].rest.diff(s));
-        new_seq.push_back((new mul(sub_seq,overall_coeff))->setflag(status_flags::dynallocated));
-    }
-    return (new add(new_seq))->setflag(status_flags::dynallocated);
-}
-
-
-/** Implementation of ex::diff() for a non-commutative product. It always returns 0.
- *  @see ex::diff */
-ex ncmul::diff(const symbol & s) const
-{
-    return _ex0();
-}
-
-
-/** Implementation of ex::diff() for a power.
- *  @see ex::diff */
-ex power::diff(const symbol & s) const
-{
-    if (exponent.info(info_flags::real)) {
-        // D(b^r) = r * b^(r-1) * D(b) (faster than the formula below)
-        return mul(mul(exponent, power(basis, exponent - _ex1())), basis.diff(s));
-    } else {
-        // D(b^e) = b^e * (D(e)*ln(b) + e*D(b)/b)
-        return mul(power(basis, exponent),
-                   add(mul(exponent.diff(s), log(basis)),
-                       mul(mul(exponent, basis.diff(s)), power(basis, -1))));
-    }
-}
-
-
-/** Implementation of ex::diff() for functions. It applies the chain rule,
- *  except for the Order term function.
- *  @see ex::diff */
-ex function::diff(const symbol & s) const
-{
-    exvector new_seq;
-    
-    if (serial==function_index_Order) {
-        // Order Term function only differentiates the argument
-        return Order(seq[0].diff(s));
-    } else {
-        // Chain rule
-        ex arg_diff;
-        for (unsigned i=0; i!=seq.size(); i++) {
-            arg_diff = seq[i].diff(s);
-            // We apply the chain rule only when it makes sense.  This is not
-            // just for performance reasons but also to allow functions to
-            // throw when differentiated with respect to one of its arguments
-            // without running into trouble with our automatic full
-            // differentiation:
-            if (!arg_diff.is_zero())
-                new_seq.push_back(mul(pdiff(i), arg_diff));
-        }
-    }
-    return add(new_seq);
-}
-
-
-/** Implementation of ex::diff() for a power series. It treats the series as a polynomial.
- *  @see ex::diff */
-ex pseries::diff(const symbol & s) const
-{
-    if (s == var) {
-        epvector new_seq;
-        epvector::const_iterator it = seq.begin(), itend = seq.end();
-        
-        // FIXME: coeff might depend on var
-        while (it != itend) {
-            if (is_order_function(it->rest)) {
-                new_seq.push_back(expair(it->rest, it->coeff - 1));
-            } else {
-                ex c = it->rest * it->coeff;
-                if (!c.is_zero())
-                    new_seq.push_back(expair(c, it->coeff - 1));
-            }
-            it++;
-        }
-        return pseries(var, point, new_seq);
-    } else {
-        return *this;
-    }
-}
-
-
-/** Compute partial derivative of an expression.
- *
- *  @param s  symbol by which the expression is derived
- *  @param nth  order of derivative (default 1)
- *  @return partial derivative as a new expression */
-
-ex ex::diff(const symbol & s, unsigned nth) const
-{
-    GINAC_ASSERT(bp!=0);
-
-    if (nth==0) {
-        return *this;
-    }
-
-    ex ndiff = bp->diff(s);
-    while (nth>1) {
-        ndiff = ndiff.diff(s);
-        --nth;
-    }
-    return ndiff;
-}
-
-#ifndef NO_NAMESPACE_GINAC
-} // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 7899112..a390d71 100644 (file)
@@ -374,6 +374,21 @@ ex ex::evalf(int level) const
     return bp->evalf(level);
 }
 
+/** Compute partial derivative of an expression.
+ *
+ *  @param s  symbol by which the expression is derived
+ *  @param nth  order of derivative (default 1)
+ *  @return partial derivative as a new expression */
+ex ex::diff(const symbol & s, unsigned nth) const
+{
+    GINAC_ASSERT(bp!=0);
+
+    if (!nth)
+        return *this;
+    else
+        return bp->diff(s, nth);
+}
+
 ex ex::subs(const lst & ls, const lst & lr) const
 {
     GINAC_ASSERT(bp!=0);
index be065ce..fe910d0 100644 (file)
@@ -372,6 +372,14 @@ ex expairseq::subs(const lst & ls, const lst & lr) const
 
 // protected
 
+/** Implementation of ex::diff() for an expairseq. It differentiates all elements of the
+ *  sequence.
+ *  @see ex::diff */
+ex expairseq::derivative(const symbol & s) const
+{
+    return thisexpairseq(diffchildren(s),overall_coeff);
+}
+
 int expairseq::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_of_type(other, expairseq));
index 54062f6..9c32dbd 100644 (file)
@@ -102,9 +102,9 @@ public:
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
-    ex diff(const symbol & s) const;
     ex subs(const lst & ls, const lst & lr) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
index 8ad1abe..b7e1402 100755 (executable)
@@ -296,11 +296,11 @@ public:
     ex expand(unsigned options=0) const;
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
-    ex diff(const symbol & s) const;
     ex series(const symbol & s, const ex & point, int order) const;
     ex thisexprseq(const exvector & v) const;
     ex thisexprseq(exvector * vp) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
@@ -311,7 +311,7 @@ protected:
     
     // non-virtual functions in this class
 protected:
-    ex pdiff(unsigned diff_param) const; // partial differentiation
+    ex pderivative(unsigned diff_param) const; // partial differentiation
     static vector<registered_function_info> & registered_functions(void);
 public:
     // the following lines have been generated for max. ${maxargs} parameters
@@ -385,6 +385,7 @@ $implementation=<<END_OF_IMPLEMENTATION;
 #include "function.h"
 #include "ex.h"
 #include "archive.h"
+#include "inifcns.h"
 #include "utils.h"
 #include "debugmsg.h"
 
@@ -664,6 +665,34 @@ ${series_switch_statement}
 
 // protected
 
+
+/** Implementation of ex::diff() for functions. It applies the chain rule,
+ *  except for the Order term function.
+ *  \@see ex::diff */
+ex function::derivative(const symbol & s) const
+{
+    ex result;
+    
+    if (serial==function_index_Order) {
+        // Order Term function only differentiates the argument
+        return Order(seq[0].diff(s));
+    } else {
+        // Chain rule
+        ex arg_diff;
+        for (unsigned i=0; i!=seq.size(); i++) {
+            arg_diff = seq[i].diff(s);
+            // We apply the chain rule only when it makes sense.  This is not
+            // just for performance reasons but also to allow functions to
+            // throw when differentiated with respect to one of its arguments
+            // without running into trouble with our automatic full
+            // differentiation:
+            if (!arg_diff.is_zero())
+                result += pderivative(i)*arg_diff;
+        }
+    }
+    return result;
+}
+
 int function::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_of_type(other, function));
@@ -712,19 +741,19 @@ unsigned function::return_type_tinfo(void) const
 
 // protected
 
-ex function::pdiff(unsigned diff_param) const // partial differentiation
+ex function::pderivative(unsigned diff_param) const // partial differentiation
 {
     GINAC_ASSERT(serial<registered_functions().size());
     
     if (registered_functions()[serial].d==0) {
-        throw(std::logic_error(string("function::pdiff(") + registered_functions()[serial].name + "): no diff function defined"));
+        throw(std::logic_error(string("function::pderivative(") + registered_functions()[serial].name + "): no diff function defined"));
     }
     switch (registered_functions()[serial].nparams) {
         // the following lines have been generated for max. ${maxargs} parameters
 ${diff_switch_statement}
         // end of generated lines
     }        
-    throw(std::logic_error("function::pdiff(): no diff function defined"));
+    throw(std::logic_error("function::pderivative(): no diff function defined"));
 }
 
 vector<registered_function_info> & function::registered_functions(void)
index 1f67038..0f6726e 100644 (file)
@@ -221,6 +221,13 @@ exvector indexed::get_indices(void) const
 
 // protected
 
+/** Implementation of ex::diff() for an indexed object. It always returns 0.
+ *  @see ex::diff */
+ex indexed::derivative(const symbol & s) const
+{
+        return _ex0();
+}
+
 int indexed::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_of_type(other,indexed));
index 5988f0a..919fc18 100644 (file)
@@ -64,9 +64,9 @@ public:
     void print(ostream & os, unsigned upper_precedence=0) const;
     void printcsrc(ostream & os, unsigned type, unsigned upper_precedence) const;
     bool info(unsigned inf) const;
-    ex diff(const symbol & s) const;
     exvector get_indices(void) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
index 503c44c..9e96fda 100644 (file)
@@ -94,9 +94,9 @@ static ex gamma_eval(const ex & x)
 }    
 
 
-static ex gamma_diff(const ex & x, unsigned diff_param)
+static ex gamma_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx  log(gamma(x)) -> psi(x)
     // d/dx  gamma(x) -> psi(x)*gamma(x)
@@ -126,7 +126,7 @@ static ex gamma_series(const ex & x, const symbol & s, const ex & pt, int order)
 }
 
 
-REGISTER_FUNCTION(gamma, gamma_eval, gamma_evalf, gamma_diff, gamma_series);
+REGISTER_FUNCTION(gamma, gamma_eval, gamma_evalf, gamma_deriv, gamma_series);
 
 
 //////////
@@ -181,16 +181,16 @@ static ex beta_eval(const ex & x, const ex & y)
 }
 
 
-static ex beta_diff(const ex & x, const ex & y, unsigned diff_param)
+static ex beta_deriv(const ex & x, const ex & y, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param<2);
+    GINAC_ASSERT(deriv_param<2);
     ex retval;
     
     // d/dx beta(x,y) -> (psi(x)-psi(x+y)) * beta(x,y)
-    if (diff_param==0)
+    if (deriv_param==0)
         retval = (psi(x)-psi(x+y))*beta(x,y);
     // d/dy beta(x,y) -> (psi(y)-psi(x+y)) * beta(x,y)
-    if (diff_param==1)
+    if (deriv_param==1)
         retval = (psi(y)-psi(x+y))*beta(x,y);
     return retval;
 }
@@ -229,7 +229,7 @@ static ex beta_series(const ex & x, const ex & y, const symbol & s, const ex & p
 }
 
 
-REGISTER_FUNCTION(beta, beta_eval, beta_evalf, beta_diff, beta_series);
+REGISTER_FUNCTION(beta, beta_eval, beta_evalf, beta_deriv, beta_series);
 
 
 //////////
@@ -290,9 +290,9 @@ static ex psi1_eval(const ex & x)
     return psi(x).hold();
 }
 
-static ex psi1_diff(const ex & x, unsigned diff_param)
+static ex psi1_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx psi(x) -> psi(1,x)
     return psi(_ex1(), x);
@@ -319,7 +319,7 @@ static ex psi1_series(const ex & x, const symbol & s, const ex & pt, int order)
     return (psi(x+m+_ex1())-recur).series(s, pt, order);
 }
 
-const unsigned function_index_psi1 = function::register_new("psi", psi1_eval, psi1_evalf, psi1_diff, psi1_series);
+const unsigned function_index_psi1 = function::register_new("psi", psi1_eval, psi1_evalf, psi1_deriv, psi1_series);
 
 //////////
 // Psi-functions (aka polygamma-functions)  psi(0,x)==psi(x)
@@ -400,11 +400,11 @@ static ex psi2_eval(const ex & n, const ex & x)
     return psi(n, x).hold();
 }    
 
-static ex psi2_diff(const ex & n, const ex & x, unsigned diff_param)
+static ex psi2_deriv(const ex & n, const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param<2);
+    GINAC_ASSERT(deriv_param<2);
     
-    if (diff_param==0) {
+    if (deriv_param==0) {
         // d/dn psi(n,x)
         throw(std::logic_error("cannot diff psi(n,x) with respect to n"));
     }
@@ -435,7 +435,7 @@ static ex psi2_series(const ex & n, const ex & x, const symbol & s, const ex & p
     return (psi(n, x+m+_ex1())-recur).series(s, pt, order);
 }
 
-const unsigned function_index_psi2 = function::register_new("psi", psi2_eval, psi2_evalf, psi2_diff, psi2_series);
+const unsigned function_index_psi2 = function::register_new("psi", psi2_eval, psi2_evalf, psi2_deriv, psi2_series);
 
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
index da763b4..e0d0999 100644 (file)
@@ -80,15 +80,15 @@ static ex exp_eval(const ex & x)
     return exp(x).hold();
 }
 
-static ex exp_diff(const ex & x, unsigned diff_param)
+static ex exp_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
 
     // d/dx exp(x) -> exp(x)
     return exp(x);
 }
 
-REGISTER_FUNCTION(exp, exp_eval, exp_evalf, exp_diff, NULL);
+REGISTER_FUNCTION(exp, exp_eval, exp_evalf, exp_deriv, NULL);
 
 //////////
 // natural logarithm
@@ -133,15 +133,15 @@ static ex log_eval(const ex & x)
     return log(x).hold();
 }
 
-static ex log_diff(const ex & x, unsigned diff_param)
+static ex log_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
 
     // d/dx log(x) -> 1/x
     return power(x, _ex_1());
 }
 
-REGISTER_FUNCTION(log, log_eval, log_evalf, log_diff, NULL);
+REGISTER_FUNCTION(log, log_eval, log_evalf, log_deriv, NULL);
 
 //////////
 // sine (trigonometric function)
@@ -212,15 +212,15 @@ static ex sin_eval(const ex & x)
     return sin(x).hold();
 }
 
-static ex sin_diff(const ex & x, unsigned diff_param)
+static ex sin_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx sin(x) -> cos(x)
     return cos(x);
 }
 
-REGISTER_FUNCTION(sin, sin_eval, sin_evalf, sin_diff, NULL);
+REGISTER_FUNCTION(sin, sin_eval, sin_evalf, sin_deriv, NULL);
 
 //////////
 // cosine (trigonometric function)
@@ -291,15 +291,15 @@ static ex cos_eval(const ex & x)
     return cos(x).hold();
 }
 
-static ex cos_diff(const ex & x, unsigned diff_param)
+static ex cos_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
 
     // d/dx cos(x) -> -sin(x)
     return _ex_1()*sin(x);
 }
 
-REGISTER_FUNCTION(cos, cos_eval, cos_evalf, cos_diff, NULL);
+REGISTER_FUNCTION(cos, cos_eval, cos_evalf, cos_deriv, NULL);
 
 //////////
 // tangent (trigonometric function)
@@ -367,9 +367,9 @@ static ex tan_eval(const ex & x)
     return tan(x).hold();
 }
 
-static ex tan_diff(const ex & x, unsigned diff_param)
+static ex tan_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx tan(x) -> 1+tan(x)^2;
     return (_ex1()+power(tan(x),_ex2()));
@@ -378,7 +378,7 @@ static ex tan_diff(const ex & x, unsigned diff_param)
 static ex tan_series(const ex & x, const symbol & s, const ex & pt, int order)
 {
     // method:
-    // Taylor series where there is no pole falls back to tan_diff.
+    // Taylor series where there is no pole falls back to tan_deriv.
     // On a pole simply expand sin(x)/cos(x).
     const ex x_pt = x.subs(s==pt);
     if (!(2*x_pt/Pi).info(info_flags::odd))
@@ -387,7 +387,7 @@ static ex tan_series(const ex & x, const symbol & s, const ex & pt, int order)
     return (sin(x)/cos(x)).series(s, pt, order+2);
 }
 
-REGISTER_FUNCTION(tan, tan_eval, tan_evalf, tan_diff, tan_series);
+REGISTER_FUNCTION(tan, tan_eval, tan_evalf, tan_deriv, tan_series);
 
 //////////
 // inverse sine (arc sine)
@@ -428,15 +428,15 @@ static ex asin_eval(const ex & x)
     return asin(x).hold();
 }
 
-static ex asin_diff(const ex & x, unsigned diff_param)
+static ex asin_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx asin(x) -> 1/sqrt(1-x^2)
     return power(1-power(x,_ex2()),_ex_1_2());
 }
 
-REGISTER_FUNCTION(asin, asin_eval, asin_evalf, asin_diff, NULL);
+REGISTER_FUNCTION(asin, asin_eval, asin_evalf, asin_deriv, NULL);
 
 //////////
 // inverse cosine (arc cosine)
@@ -477,15 +477,15 @@ static ex acos_eval(const ex & x)
     return acos(x).hold();
 }
 
-static ex acos_diff(const ex & x, unsigned diff_param)
+static ex acos_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx acos(x) -> -1/sqrt(1-x^2)
     return _ex_1()*power(1-power(x,_ex2()),_ex_1_2());
 }
 
-REGISTER_FUNCTION(acos, acos_eval, acos_evalf, acos_diff, NULL);
+REGISTER_FUNCTION(acos, acos_eval, acos_evalf, acos_deriv, NULL);
 
 //////////
 // inverse tangent (arc tangent)
@@ -514,15 +514,15 @@ static ex atan_eval(const ex & x)
     return atan(x).hold();
 }    
 
-static ex atan_diff(const ex & x, unsigned diff_param)
+static ex atan_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
 
     // d/dx atan(x) -> 1/(1+x^2)
     return power(_ex1()+power(x,_ex2()), _ex_1());
 }
 
-REGISTER_FUNCTION(atan, atan_eval, atan_evalf, atan_diff, NULL);
+REGISTER_FUNCTION(atan, atan_eval, atan_evalf, atan_deriv, NULL);
 
 //////////
 // inverse tangent (atan2(y,x))
@@ -548,11 +548,11 @@ static ex atan2_eval(const ex & y, const ex & x)
     return atan2(y,x).hold();
 }    
 
-static ex atan2_diff(const ex & y, const ex & x, unsigned diff_param)
+static ex atan2_deriv(const ex & y, const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param<2);
+    GINAC_ASSERT(deriv_param<2);
     
-    if (diff_param==0) {
+    if (deriv_param==0) {
         // d/dy atan(y,x)
         return x*power(power(x,_ex2())+power(y,_ex2()),_ex_1());
     }
@@ -560,7 +560,7 @@ static ex atan2_diff(const ex & y, const ex & x, unsigned diff_param)
     return -y*power(power(x,_ex2())+power(y,_ex2()),_ex_1());
 }
 
-REGISTER_FUNCTION(atan2, atan2_eval, atan2_evalf, atan2_diff, NULL);
+REGISTER_FUNCTION(atan2, atan2_eval, atan2_evalf, atan2_deriv, NULL);
 
 //////////
 // hyperbolic sine (trigonometric function)
@@ -604,15 +604,15 @@ static ex sinh_eval(const ex & x)
     return sinh(x).hold();
 }
 
-static ex sinh_diff(const ex & x, unsigned diff_param)
+static ex sinh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx sinh(x) -> cosh(x)
     return cosh(x);
 }
 
-REGISTER_FUNCTION(sinh, sinh_eval, sinh_evalf, sinh_diff, NULL);
+REGISTER_FUNCTION(sinh, sinh_eval, sinh_evalf, sinh_deriv, NULL);
 
 //////////
 // hyperbolic cosine (trigonometric function)
@@ -656,15 +656,15 @@ static ex cosh_eval(const ex & x)
     return cosh(x).hold();
 }
 
-static ex cosh_diff(const ex & x, unsigned diff_param)
+static ex cosh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx cosh(x) -> sinh(x)
     return sinh(x);
 }
 
-REGISTER_FUNCTION(cosh, cosh_eval, cosh_evalf, cosh_diff, NULL);
+REGISTER_FUNCTION(cosh, cosh_eval, cosh_evalf, cosh_deriv, NULL);
 
 //////////
 // hyperbolic tangent (trigonometric function)
@@ -708,9 +708,9 @@ static ex tanh_eval(const ex & x)
     return tanh(x).hold();
 }
 
-static ex tanh_diff(const ex & x, unsigned diff_param)
+static ex tanh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx tanh(x) -> 1-tanh(x)^2
     return _ex1()-power(tanh(x),_ex2());
@@ -719,7 +719,7 @@ static ex tanh_diff(const ex & x, unsigned diff_param)
 static ex tanh_series(const ex & x, const symbol & s, const ex & pt, int order)
 {
     // method:
-    // Taylor series where there is no pole falls back to tanh_diff.
+    // Taylor series where there is no pole falls back to tanh_deriv.
     // On a pole simply expand sinh(x)/cosh(x).
     const ex x_pt = x.subs(s==pt);
     if (!(2*I*x_pt/Pi).info(info_flags::odd))
@@ -728,7 +728,7 @@ static ex tanh_series(const ex & x, const symbol & s, const ex & pt, int order)
     return (sinh(x)/cosh(x)).series(s, pt, order+2);
 }
 
-REGISTER_FUNCTION(tanh, tanh_eval, tanh_evalf, tanh_diff, tanh_series);
+REGISTER_FUNCTION(tanh, tanh_eval, tanh_evalf, tanh_deriv, tanh_series);
 
 //////////
 // inverse hyperbolic sine (trigonometric function)
@@ -757,15 +757,15 @@ static ex asinh_eval(const ex & x)
     return asinh(x).hold();
 }
 
-static ex asinh_diff(const ex & x, unsigned diff_param)
+static ex asinh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx asinh(x) -> 1/sqrt(1+x^2)
     return power(_ex1()+power(x,_ex2()),_ex_1_2());
 }
 
-REGISTER_FUNCTION(asinh, asinh_eval, asinh_evalf, asinh_diff, NULL);
+REGISTER_FUNCTION(asinh, asinh_eval, asinh_evalf, asinh_deriv, NULL);
 
 //////////
 // inverse hyperbolic cosine (trigonometric function)
@@ -800,15 +800,15 @@ static ex acosh_eval(const ex & x)
     return acosh(x).hold();
 }
 
-static ex acosh_diff(const ex & x, unsigned diff_param)
+static ex acosh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx acosh(x) -> 1/(sqrt(x-1)*sqrt(x+1))
     return power(x+_ex_1(),_ex_1_2())*power(x+_ex1(),_ex_1_2());
 }
 
-REGISTER_FUNCTION(acosh, acosh_eval, acosh_evalf, acosh_diff, NULL);
+REGISTER_FUNCTION(acosh, acosh_eval, acosh_evalf, acosh_deriv, NULL);
 
 //////////
 // inverse hyperbolic tangent (trigonometric function)
@@ -840,15 +840,15 @@ static ex atanh_eval(const ex & x)
     return atanh(x).hold();
 }
 
-static ex atanh_diff(const ex & x, unsigned diff_param)
+static ex atanh_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     // d/dx atanh(x) -> 1/(1-x^2)
     return power(_ex1()-power(x,_ex2()),_ex_1());
 }
 
-REGISTER_FUNCTION(atanh, atanh_eval, atanh_evalf, atanh_diff, NULL);
+REGISTER_FUNCTION(atanh, atanh_eval, atanh_evalf, atanh_deriv, NULL);
 
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
index 51f9700..6363737 100644 (file)
@@ -74,14 +74,14 @@ static ex zeta1_eval(const ex & x)
     return zeta(x).hold();
 }
 
-static ex zeta1_diff(const ex & x, unsigned diff_param)
+static ex zeta1_deriv(const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param==0);
+    GINAC_ASSERT(deriv_param==0);
     
     return zeta(_ex1(), x);
 }
 
-const unsigned function_index_zeta1 = function::register_new("zeta", zeta1_eval, zeta1_evalf, zeta1_diff, NULL);
+const unsigned function_index_zeta1 = function::register_new("zeta", zeta1_eval, zeta1_evalf, zeta1_deriv, NULL);
 
 //////////
 // Derivatives of Riemann's Zeta-function  zeta(0,x)==zeta(x)
@@ -98,11 +98,11 @@ static ex zeta2_eval(const ex & n, const ex & x)
     return zeta(n, x).hold();
 }
 
-static ex zeta2_diff(const ex & n, const ex & x, unsigned diff_param)
+static ex zeta2_deriv(const ex & n, const ex & x, unsigned deriv_param)
 {
-    GINAC_ASSERT(diff_param<2);
+    GINAC_ASSERT(deriv_param<2);
     
-    if (diff_param==0) {
+    if (deriv_param==0) {
         // d/dn zeta(n,x)
         throw(std::logic_error("cannot diff zeta(n,x) with respect to n"));
     }
@@ -110,7 +110,7 @@ static ex zeta2_diff(const ex & n, const ex & x, unsigned diff_param)
     return zeta(n+1,x);
 }
 
-const unsigned function_index_zeta2 = function::register_new("zeta", zeta2_eval, NULL, zeta2_diff, NULL);
+const unsigned function_index_zeta2 = function::register_new("zeta", zeta2_eval, NULL, zeta2_deriv, NULL);
 
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
index 1b051ab..6a32fb5 100644 (file)
@@ -462,6 +462,24 @@ ex mul::simplify_ncmul(const exvector & v) const
 
 // protected
 
+/** Implementation of ex::diff() for a product. It applies the product rule.
+ *  @see ex::diff */
+ex mul::derivative(const symbol & s) const
+{
+    exvector new_seq;
+    new_seq.reserve(seq.size());
+
+    // D(a*b*c)=D(a)*b*c+a*D(b)*c+a*b*D(c)
+    for (unsigned i=0; i!=seq.size(); i++) {
+        epvector sub_seq=seq;
+        sub_seq[i] = split_ex_to_pair(sub_seq[i].coeff*
+                                      power(sub_seq[i].rest,sub_seq[i].coeff-1)*
+                                      sub_seq[i].rest.diff(s));
+        new_seq.push_back((new mul(sub_seq,overall_coeff))->setflag(status_flags::dynallocated));
+    }
+    return (new add(new_seq))->setflag(status_flags::dynallocated);
+}
+
 int mul::compare_same_type(const basic & other) const
 {
     return inherited::compare_same_type(other);
index de047f4..1a01741 100644 (file)
@@ -71,7 +71,6 @@ public:
     int ldegree(const symbol & s) const;
     ex coeff(const symbol & s, int n=1) const;
     ex eval(int level=0) const;
-    ex diff(const symbol & s) const;
     ex series(const symbol & s, const ex & point, int order) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
     numeric integer_content(void) const;
@@ -80,6 +79,7 @@ public:
     exvector get_indices(void) const;
     ex simplify_ncmul(const exvector & v) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
index a970a8b..7cd8014 100644 (file)
@@ -538,6 +538,13 @@ ex ncmul::thisexprseq(exvector * vp) const
 
 // protected
 
+/** Implementation of ex::diff() for a non-commutative product. It always returns 0.
+ *  @see ex::diff */
+ex ncmul::derivative(const symbol & s) const
+{
+    return _ex0();
+}
+
 int ncmul::compare_same_type(const basic & other) const
 {
     return inherited::compare_same_type(other);
index b79b0ea..b5cc166 100644 (file)
@@ -75,12 +75,12 @@ public:
     ex expand(unsigned options=0) const;
     ex coeff(const symbol & s, int n=1) const;
     ex eval(int level=0) const;
-    ex diff(const symbol & s) const;
     ex subs(const lst & ls, const lst & lr) const;
     exvector get_indices(void) const;
     ex thisexprseq(const exvector & v) const;
     ex thisexprseq(exvector * vp) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     unsigned return_type(void) const;
     unsigned return_type_tinfo(void) const;
index 149f049..e504186 100644 (file)
@@ -545,6 +545,14 @@ ex numeric::evalf(int level) const
 
 // protected
 
+/** Implementation of ex::diff() for a numeric. It always returns 0.
+ *
+ *  @see ex::diff */
+ex numeric::derivative(const symbol & s) const
+{
+    return _ex0();
+}
+
 int numeric::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_exactly_of_type(other, numeric));
@@ -634,8 +642,14 @@ numeric numeric::power(const numeric & other) const
     static const numeric * _num1p=&_num1();
     if (&other==_num1p)
         return *this;
-    if (::zerop(*value) && other.is_real() && ::minusp(realpart(*other.value)))
-        throw (std::overflow_error("division by zero"));
+    if (::zerop(*value)) {
+        if (::zerop(*other.value))
+            throw (std::domain_error("numeric::eval(): pow(0,0) is undefined"));
+        else if (other.is_real() && !::plusp(realpart(*other.value)))
+            throw (std::overflow_error("numeric::eval(): division by zero"));
+        else
+            return _num0();
+    }
     return numeric(::expt(*value,*other.value));
 }
 
@@ -682,8 +696,14 @@ const numeric & numeric::power_dyn(const numeric & other) const
     static const numeric * _num1p=&_num1();
     if (&other==_num1p)
         return *this;
-    if (::zerop(*value) && other.is_real() && ::minusp(realpart(*other.value)))
-        throw (std::overflow_error("division by zero"));
+    if (::zerop(*value)) {
+        if (::zerop(*other.value))
+            throw (std::domain_error("numeric::eval(): pow(0,0) is undefined"));
+        else if (other.is_real() && !::plusp(realpart(*other.value)))
+            throw (std::overflow_error("numeric::eval(): division by zero"));
+        else
+            return _num0();
+    }
     return static_cast<const numeric &>((new numeric(::expt(*value,*other.value)))->
                                         setflag(status_flags::dynallocated));
 }
@@ -1659,15 +1679,6 @@ ostream& operator<<(ostream& os, const _numeric_digits & e)
 bool _numeric_digits::too_late = false;
 
 
-//////////
-// utility functions
-//////////
-
-const numeric &ex_to_numeric(const ex &e)
-{
-    return static_cast<const numeric &>(*e.bp);
-}
-
 /** Accuracy in decimal digits.  Only object of this type!  Can be set using
  *  assignment from C++ unsigned ints and evaluated like any built-in type. */
 _numeric_digits Digits;
index 6c1f9f2..03fcb43 100644 (file)
@@ -129,12 +129,12 @@ public:
     bool info(unsigned inf) const;
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
-    ex diff(const symbol & s) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
     numeric integer_content(void) const;
     ex smod(const numeric &xi) const;
     numeric max_coefficient(void) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned calchash(void) const {
@@ -323,8 +323,13 @@ ex PiEvalf(void);
 ex EulerGammaEvalf(void);
 ex CatalanEvalf(void);
 
+
 // utility functions
-const numeric &ex_to_numeric(const ex &e);
+inline const numeric &ex_to_numeric(const ex &e)
+{
+    return static_cast<const numeric &>(*e.bp);
+}
+
 
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
index 89ba78b..a85bc79 100644 (file)
@@ -29,6 +29,7 @@
 #include "add.h"
 #include "mul.h"
 #include "numeric.h"
+#include "inifcns.h"
 #include "relational.h"
 #include "symbol.h"
 #include "archive.h"
@@ -353,7 +354,10 @@ ex power::eval(int level) const
 
     // ^(x,0) -> 1 (0^0 also handled here)
     if (eexponent.is_zero())
-        return _ex1();
+        if (ebasis.is_zero())
+            throw (std::domain_error("power::eval(): pow(0,0) is undefined"));
+        else
+            return _ex1();
 
     // ^(x,1) -> x
     if (eexponent.is_equal(_ex1()))
@@ -514,6 +518,21 @@ ex power::simplify_ncmul(const exvector & v) const
 
 // protected
 
+/** Implementation of ex::diff() for a power.
+ *  @see ex::diff */
+ex power::derivative(const symbol & s) const
+{
+    if (exponent.info(info_flags::real)) {
+        // D(b^r) = r * b^(r-1) * D(b) (faster than the formula below)
+        return mul(mul(exponent, power(basis, exponent - _ex1())), basis.diff(s));
+    } else {
+        // D(b^e) = b^e * (D(e)*ln(b) + e*D(b)/b)
+        return mul(power(basis, exponent),
+                   add(mul(exponent.diff(s), log(basis)),
+                       mul(mul(exponent, basis.diff(s)), power(basis, -1))));
+    }
+}
+
 int power::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_exactly_of_type(other, power));
index 13dfd5f..7a76217 100644 (file)
@@ -73,12 +73,12 @@ public:
     ex coeff(const symbol & s, int n=1) const;
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
-    ex diff(const symbol & s) const;
     ex series(const symbol & s, const ex & point, int order) const;
     ex subs(const lst & ls, const lst & lr) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
     ex simplify_ncmul(const exvector & v) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     unsigned return_type(void) const;
     unsigned return_type_tinfo(void) const;
index 459b469..7fbf731 100644 (file)
@@ -298,6 +298,32 @@ ex pseries::subs(const lst & ls, const lst & lr) const
     return (new pseries(var, point.subs(ls, lr), new_seq))->setflag(status_flags::dynallocated);
 }
 
+/** Implementation of ex::diff() for a power series.  It treats the series as a
+ *  polynomial.
+ *  @see ex::diff */
+ex pseries::derivative(const symbol & s) const
+{
+    if (s == var) {
+        epvector new_seq;
+        epvector::const_iterator it = seq.begin(), itend = seq.end();
+        
+        // FIXME: coeff might depend on var
+        while (it != itend) {
+            if (is_order_function(it->rest)) {
+                new_seq.push_back(expair(it->rest, it->coeff - 1));
+            } else {
+                ex c = it->rest * it->coeff;
+                if (!c.is_zero())
+                    new_seq.push_back(expair(c, it->coeff - 1));
+            }
+            it++;
+        }
+        return pseries(var, point, new_seq);
+    } else {
+        return *this;
+    }
+}
+
 
 /*
  *  Construct ordinary polynomial out of series
index 1f69ae4..046c838 100644 (file)
@@ -66,8 +66,9 @@ public:
     ex eval(int level=0) const;
     ex evalf(int level=0) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
-    ex diff(const symbol & s) const;
     ex subs(const lst & ls, const lst & lr) const;
+protected:
+    ex derivative(const symbol & s) const;
 
     // non-virtual functions in this class
 public:
index 43927dc..1a8ef59 100644 (file)
@@ -259,6 +259,19 @@ ex symbol::subs(const lst & ls, const lst & lr) const
 
 // protected
 
+/** Implementation of ex::diff() for single differentiation of a symbol.
+ *  It returns 1 or 0.
+ *
+ *  @see ex::diff */
+ex symbol::derivative(const symbol & s) const
+{
+    if (compare_same_type(s)) {
+        return _ex0();
+    } else {
+        return _ex1();
+    }
+}
+
 int symbol::compare_same_type(const basic & other) const
 {
     GINAC_ASSERT(is_of_type(other,symbol));
index 13515c4..6ab13d1 100644 (file)
@@ -81,11 +81,11 @@ public:
     int ldegree(const symbol & s) const;
     ex coeff(const symbol & s, int n = 1) const;
     ex eval(int level = 0) const;
-    ex diff(const symbol & s) const;
     ex series(const symbol & s, const ex & point, int order) const;
     ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
     ex subs(const lst & ls, const lst & lr) const;
 protected:
+    ex derivative(const symbol & s) const;
     int compare_same_type(const basic & other) const;
     bool is_equal_same_type(const basic & other) const;
     unsigned return_type(void) const;
@@ -96,7 +96,6 @@ protected:
 public:
     void assign(const ex & value);
     void unassign(void);
-    ex diff(const symbol & s, unsigned nth) const;
     void setname(const string & n) {name=n;}
     string getname(void) const {return name;}
 private:
index 755881a..fa6f54a 100644 (file)
@@ -34,7 +34,7 @@ namespace GiNaC {
 #endif // ndef NO_NAMESPACE_GINAC
 
 template<class T>
-string ToString(T const & t)
+string ToString(const T & t)
 {
     char buf[256];
     ostrstream(buf,sizeof(buf)) << t << ends;
index b2a7cfa..4611377 100644 (file)
@@ -64,6 +64,7 @@ ARCHIVE_VERSION = @ARCHIVE_VERSION@
 AS = @AS@
 CC = @CC@
 CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
 CXX = @CXX@
 CXXCPP = @CXXCPP@
 DLLTOOL = @DLLTOOL@
@@ -316,7 +317,7 @@ distdir: $(DISTFILES)
        @for file in $(DISTFILES); do \
          d=$(srcdir); \
          if test -d $$d/$$file; then \
-           cp -pr $$/$$file $(distdir)/$$file; \
+           cp -pr $$d/$$file $(distdir)/$$file; \
          else \
            test -f $(distdir)/$$file \
            || ln $$d/$$file $(distdir)/$$file 2> /dev/null \