AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \
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++).
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \
## 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
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
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
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 =
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:
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 $<
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:
@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 \
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
-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 \
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 \
# 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
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.
.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
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
.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
#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));
#include <strstream>
template<class T>
-string ToString(T const & t)
+string ToString(const T & t)
{
char buf[256];
ostrstream(buf,sizeof(buf)) << t << ends;
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];
}
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;
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);
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;
}
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)
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]) {
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++;
(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;
} 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);
--- /dev/null
+#! /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}
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"
+
trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
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
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
doc/tutorial/Makefile
doc/reference/Makefile
cint/Makefile
+cint/ginaccint
"}
EOF
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
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"
AC_MSG_ERROR([Cannot configure GiNaC-cint])
fi
fi
+AC_SUBST(CINTSYSDIR)
AC_SUBST(LIBGINACCINT)
AC_SUBST(GINACCINTDIR)
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\"."
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \
#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()
@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.
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);
@}
## 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 \
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
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)
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)
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 \
@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 \
// 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);
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;
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;
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
// 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);
return this->setflag(status_flags::expanded);
}
+
//////////
// non-virtual functions in this class
//////////
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;
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;
// 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;
// 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));
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;
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;
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));
}
+++ /dev/null
-/** @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
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);
// 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));
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;
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;
// 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
#include "function.h"
#include "ex.h"
#include "archive.h"
+#include "inifcns.h"
#include "utils.h"
#include "debugmsg.h"
// 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));
// 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)
// 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));
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;
}
-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)
}
-REGISTER_FUNCTION(gamma, gamma_eval, gamma_evalf, gamma_diff, gamma_series);
+REGISTER_FUNCTION(gamma, gamma_eval, gamma_evalf, gamma_deriv, gamma_series);
//////////
}
-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;
}
}
-REGISTER_FUNCTION(beta, beta_eval, beta_evalf, beta_diff, beta_series);
+REGISTER_FUNCTION(beta, beta_eval, beta_evalf, beta_deriv, beta_series);
//////////
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);
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)
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"));
}
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
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
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)
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)
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)
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()));
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))
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)
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)
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)
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))
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());
}
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)
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)
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)
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());
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))
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)
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)
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)
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
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)
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"));
}
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
// 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);
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;
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;
// 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);
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;
// 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));
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));
}
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));
}
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;
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 {
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
#include "add.h"
#include "mul.h"
#include "numeric.h"
+#include "inifcns.h"
#include "relational.h"
#include "symbol.h"
#include "archive.h"
// ^(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()))
// 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));
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;
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
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:
// 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));
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;
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:
#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;
AS = @AS@
CC = @CC@
CINT = @CINT@
+CINTSYSDIR = @CINTSYSDIR@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
@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 \