Mercurial > forge
changeset 49:c5a7665ca140 octave-forge
Adding Ben Sapp's symbolic toolbox (but not GinaC, cln, or gmp on which it depends)
author | pkienzle |
---|---|
date | Wed, 14 Nov 2001 15:09:50 +0000 |
parents | 0ef6cb6a66e0 |
children | 08858f6d9127 |
files | main/symbolic/INSTALL main/symbolic/Makeconf.add main/symbolic/Makefile main/symbolic/configure.add main/symbolic/doc/symbolic.html main/symbolic/ov-ex.cc main/symbolic/ov-ex.h main/symbolic/ov-sym.cc main/symbolic/ov-sym.h main/symbolic/ov-vpa.cc main/symbolic/ov-vpa.h main/symbolic/splot.m main/symbolic/symbols.cc main/symbolic/symbols.h |
diffstat | 14 files changed, 1975 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/INSTALL Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,29 @@ + +Prerequisites +------------- +You will need GiNaC installed before you can install this package. Go to +the GiNaC web site http://www.ginac.de and follow the download +instructions. It will tell you how to get cln and also how to build +GiNaC once you have built cln. + +You will also need a version of Octave that was compiled without the +-fno-rtti or -fno-exceptions. Versions below octave-2.1.33 have these +options by default. These options are typically loacated in the +Makeconf file in the top level directory. After configure and before +compile you can remove these options if you want to use an older +version of octave. + +Compiling +---------- +Make sure that the correct version of mkoctfile is in your path. Then +just type gmake(or whatever you call you version of GNU Make) in the +top level directory. + +Installing +---------- +Just type "gmake INSTALL_PATH=/your/path install" and it will install +all the .oct files and .m files in /your/path. Add /your/path to your +octave path. Once you have it installed you will need to type symbols +at the octave command prompt each session to initialize the toolbox. +Then you can use all of the commands in the toolbox. Command completion +will not work on the commands until after yopu have used them once.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/Makeconf.add Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,1 @@ +@DEFHAVE_GINAC@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/Makefile Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,34 @@ + +sinclude ../../Makeconf + +ifndef MKOCTFILE +# assumptions to make if not using ./configure script +MKOCTFILE=mkoctfile +HAVE_GINAC=1 +endif + +SRC=symbols.cc ov-ex.cc ov-sym.cc ov-vpa.cc +OBJ=$(SRC:.cc=.o) + +%.o: %.cc ; $(MKOCTFILE) -v $(GINAC_CPP_FLAGS) -c $< + +ifdef HAVE_GINAC + +GINAC_CPP_FLAGS=$(shell ginac-config --cppflags) +GINAC_LD_FLAGS=$(shell ginac-config --libs) + +all: symbols.oct + +symbols.oct: $(OBJ) + $(MKOCTFILE) -v -o $@ $(OBJ) $(GINAC_LD_FLAGS) + +else + +all: + +endif + +clean: + $(RM) *.o *.oct core octave-core *~ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/configure.add Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,12 @@ + +AC_SUBST(DEFHAVE_GINAC) + +AC_DEFINE(have_ginac) +AC_CHECK_PROG(have_ginac, ginac-config, yes, no) + +if test $have_ginac = no ; then + DEFHAVE_GINAC= + AC_MSG_WARN([GiNaC not found; symbolic toolbox not built]) +else + DEFHAVE_GINAC="HAVE_GINAC=1" +fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/doc/symbolic.html Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,248 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> + <meta name="GENERATOR" content="Mozilla/4.75C-SGI [en] (X11; U; IRIX 6.5 IP22) [Netscape]"> +</head> +<body text="#000000" bgcolor="#FFFFFF" link="#0000FF" vlink="#FF0000" alink="#000088"> +<font size=+2>Octave Symbolic Manipulation Toolbox</font> +<p>The Octave Symbolic Manipulation Toolbox is based upon <a href="http://www.ginac.de">GiNaC</a> +. The goal is to simply provide the capabilities of GiNaC in +the easy to use environment provided by Octave. +<p><font size=+1>Limitations/Features</font> +<br>Currently there is no support for symbolic matrices. I think it would +require a few changes to the parser to do it nicely: for example: +sym_matrix = [x+1, x+5; x^2+4,x^2+2*x+1]; I could make a function +like sym_matrix(the_rows,the_columns,x+1, ... ) that returned a symbolic +matrix but this would be a bit of a kludge. +<p>In order to do exact arithmetic you need to deal with strings and the +vpa command. For example: vpa("1")/vpa("7") is represented +internally as exactly 1/7. However, vpa("1")/7 or 1/vpa("7") +is an approximation to 1/7 that is accurate to roughly the accuracy of +the current value of digits. +<p>GiNaC throws exceptions when there are problems with computations. +I handle some of them at this time, but I do not handle all of them. +This can cause octave to terminate prematurely. For example, +try vpa("1")/vpa("0"). This will eventually be fixed. +<p><font size=+1>Download and install</font> +<p>You will need to install cln-1.0.1, GiNaC-0.8.0 and octave-2.1.33 or +later to use this package. You may be able to get by with an earlier +version of octave if you compiled without the "-fno-rtti -fno-exceptions" +options. This package uses both exceptions and run-time type +identification. There is an INSTALL file in the package +which will tell you how to install the package. +<p><font size=+1>Functions</font> +<br>Below I provide a list of function that I have implemented or have +plans to implement as of the latest release . If the function name +is <font color="#009900">green</font><font color="#330000"> </font><font color="#000000">then +the function is implemented and to the best of my knowledge there are no +problems with it. If the function is </font><font color="#CC0000">red +</font><font color="#000000">then it has not been implemented yet. +If the function is </font><font color="#000099">blue</font><font color="#000000"> +then it has been implemented but is known not to work correctly. +Blues will appear only very rarely.</font> +<ul> +<li> +<font color="#009900">vpa</font> - create a variable precision arithmetic +variable from a string, double, or an appropriate expression.</li> + +<li> +<font color="#009900">sym</font> - create a symbolic variable</li> + +<li> +<font color="#009900">is_vpa</font> - returns true if an object is +a vpa object</li> + +<li> +<font color="#009900">is_sym</font> - return true if the argument +is a symbolic variable</li> + +<li> +<font color="#009900">is_ex</font> - returns true if an object a +symbolic expression (i.e. x+y)</li> + +<li> +<font color="#009900">to_double</font> - convert a vpa, ex or string +to a double value.</li> + +<li> +<font color="#009900">digits</font> - set or view the number of digits +that newly created vpa object should have</li> + +<li> +<font color="#CC0000">Abs</font> - Absolute value</li> + +<li> +<font color="#CC0000">csgn</font> -</li> + +<li> +<font color="#CC0000">Sqrt</font> - Sqrt(x) => x^(vpa(1)/2) +or x^(1/vpa(2))</li> + +<li> +<font color="#009900">Cos</font> - the cosine of a sym, vpa , or +ex variable</li> + +<li> +<font color="#009900">Sin</font> - the sine of a sym, vpa , or ex variable</li> + +<li> +<font color="#009900">Tan</font> - the tangent of a sym, vpa , or ex variable</li> + +<li> +<font color="#009900">aCos</font> - the inverse cosine of a sym, +vpa , or ex variable</li> + +<li> +<font color="#009900">aSin</font> - the inverse sin of a sym, vpa +, or ex variable</li> + +<li> +<font color="#009900">aTan</font> - the inverse tangent of a sym, +vpa , or ex variable</li> + +<li> +<font color="#CC0000">aTan2</font> -</li> + +<li> +<font color="#009900">Cosh</font> - the hyperbolic cosine of a sym, +vpa , or ex variable</li> + +<li> +<font color="#009900">Sinh</font> - the hyperbolic sine of a sym, +vpa , or ex variable</li> + +<li> +<font color="#009900">Tanh</font> - the hyperbolic tangent of a sym, +vpa , or ex variable</li> + +<li> +<font color="#009900">aCosh</font> - the inverse hyperbolic cosine of a +sym, vpa , or ex variable</li> + +<li> +<font color="#009900">aSinh</font> - the inverse hyperbolic sine of a sym, +vpa , or ex variable</li> + +<li> +<font color="#009900">aTanh</font> - the inverse hyperbolic tangent +of a sym, vpa , or ex variable</li> + +<li> +<font color="#009900">Exp</font> - the cosine of a sym, vpa , or +ex variable</li> + +<li> +<font color="#009900">Log</font> - the cosine of a sym, vpa , or +ex variable</li> + +<li> +<font color="#CC0000">Zeta</font> -</li> + +<li> +<font color="#CC0000">Tgamma</font> -</li> + +<li> +<font color="#CC0000">Lgamma</font> -</li> + +<li> +<font color="#CC0000">Beta</font> -</li> + +<li> +<font color="#CC0000">Factorial</font> -</li> + +<li> +<font color="#CC0000">Binomial</font> -</li> + +<li> +<font color="#CC0000">Order</font> -</li> + +<li> +<font color="#009900">subs</font> - perform a substitution in an expression</li> + +<li> +<font color="#009900">differentiate</font> - differentiate an expression</li> + +<li> +<font color="#009900">expand</font> - multiply all of the terms +in an expression out: (x+y)*(x+z) => x^2+x*y+x*z+y*z</li> + +<li> +<font color="#009900">collect</font> - collect similar terms in an +already expanded expression</li> + +<li> +<font color="#009900">coeff</font> - return the nth coefficient in +a polynomial</li> + +<li> +<font color="#009900">lcoeff</font> - leading coefficient of a polynomial +(4x^2+2x+5 => 4)</li> + +<li> +<font color="#009900">tcoeff</font> - trailing coefficient of a polynomial +(4x^2+2x+5 => 5)</li> + +<li> +<font color="#009900">degree</font> - The degree of a polynomial +(i.e. x^2+2x+1 => 2)</li> + +<li> +<font color="#009900">ldegree</font> - The low degree of a polynomial +(i.e. x^2+2x+1 => 0)</li> + +<li> +<font color="#009900">quotient</font> -</li> + +<li> +<font color="#009900">remainder</font> -</li> + +<li> +<font color="#009900">premainder</font> -</li> + +<li> +<font color="#CC0000">unit</font> -</li> + +<li> +<font color="#CC0000">content</font> -</li> + +<li> +<font color="#CC0000">primpart</font> -</li> + +<li> +<font color="#CC0000">Gcd</font> - greatest common denominator of +a polynomial expression</li> + +<li> +<font color="#CC0000">Lcm</font> - least common multiple of a polynomial +expression</li> + +<li> +<font color="#CC0000">numer</font> -</li> + +<li> +<font color="#CC0000">denom</font> -</li> + +<li> +normal - ?</li> + +<li> +<font color="#CC0000">to_rational</font> -</li> + +<li> +<font color="#CC0000">Series</font> -</li> + +<li> +<font color="#009900">Pi</font> - pi evaluated to the current value +of digits accuracy.</li> + +<li> +<font color="#009900">splot</font> -plot a symbolic functin over +a range of values</li> + +<li> +<font color="#CC0000">Saving of expressions, Retrieving of expressions</font></li> +</ul> + +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-ex.cc Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,202 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#include <octave/config.h> + +#include <cstdlib> + +#include <string> + +class ostream; +class octave_sym; + +#include <octave/lo-mappers.h> +#include <octave/lo-utils.h> +#include <octave/mx-base.h> +#include <octave/str-vec.h> + +#include <octave/defun-dld.h> +#include <octave/error.h> +#include <octave/gripes.h> +#include <octave/oct-obj.h> +#include <octave/ops.h> +#include <octave/ov-base.h> +#include <octave/ov-typeinfo.h> +#include <octave/ov.h> +#include <octave/ov-scalar.h> +#include <octave/pager.h> +#include <octave/pr-output.h> +#include <octave/symtab.h> +#include <octave/variables.h> +#include <iostream> +#include <fstream> +#include "ov-ex.h" +#include "ov-sym.h" +#include "ov-vpa.h" + +#ifdef DEFUNOP_OP +#undef DEFUNOP_OP +#endif + +#define DEFUNOP_OP(name, t, op) \ + UNOPDECL (name, a) \ + { \ + CAST_UNOP_ARG (const octave_ ## t&); \ + return octave_value (new octave_ex (op v.t ## _value ())); \ + } + +DEFUNOP_OP (uminus, ex, -) + +DEFNCUNOP_METHOD (incr, ex, increment) +DEFNCUNOP_METHOD (decr, ex, decrement) + +#ifdef DEFBINOP_OP +#undef DEFBINOP_OP +#endif + +#define DEFBINOP_OP(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (v1.t1 ## _value () op v2.t2 ## _value ())); \ + } + +#ifdef DEFBINOP_POW +#undef DEFBINOP_POW +#endif + +#define DEFBINOP_POW(name, t1, t2) \ + BINOPDECL(name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (pow(v1.t1 ## _value (), v2.t2 ## _value ()))); \ + } + +// Addition operations +DEFBINOP_OP(ex_scalar_add,ex,scalar,+) +DEFBINOP_OP(scalar_ex_add,scalar,ex,+) +DEFBINOP_OP(ex_vpa_add,ex,vpa,+) +DEFBINOP_OP (add, ex, ex, +) +DEFBINOP_OP(ex_sym_add,ex,sym,+) + +// Subtraction operations +DEFBINOP_OP(ex_scalar_sub,ex,scalar,-) +DEFBINOP_OP(scalar_ex_sub,scalar,ex,-) +DEFBINOP_OP(ex_vpa_sub,ex,vpa,-) +DEFBINOP_OP (sub, ex, ex, -) +DEFBINOP_OP(ex_sym_sub,ex,sym,-) + +// Multiplication operations +DEFBINOP_OP(ex_scalar_mul,ex,scalar,*) +DEFBINOP_OP(scalar_ex_mul,scalar,ex,*) +DEFBINOP_OP(ex_vpa_mul,ex,vpa,*) +DEFBINOP_OP (mul, ex, ex, *) +DEFBINOP_OP(ex_sym_mul,ex,sym,*) + +// Division operations +DEFBINOP_OP(ex_scalar_div,ex,scalar,/) +DEFBINOP_OP(scalar_ex_div,scalar,ex,/) +DEFBINOP_OP(ex_vpa_div,ex,vpa,/) +DEFBINOP_OP (div, ex, ex, /) +DEFBINOP_OP(ex_sym_div,ex,sym,/) + +// Power operations +DEFBINOP_POW(pow,ex,ex) +DEFBINOP_POW(ex_scalar_pow,ex,scalar) +DEFBINOP_POW(scalar_ex_pow,scalar,ex) +DEFBINOP_POW(ex_vpa_pow,ex,vpa) +DEFBINOP_POW(ex_sym_pow,ex,sym) + +void +octave_ex::print(ostream& os,bool pr_as_read_syntax) const +{ + os << x; +} + +octave_ex& octave_ex::operator=(const octave_ex& a) +{ + // GiNaC::ex *tmp; + // tmp = (a.x.bp->duplicate()); + // return octave_ex(*tmp); + return (*(new octave_ex(a.x))); +} + +void +install_ex_type() +{ + octave_ex::register_type(); + + cerr << "installing ex type at type-id = " + << octave_ex::static_type_id() << "\n"; +} + +void +install_ex_ops() +{ + INSTALL_UNOP(op_uminus, octave_ex, uminus); // -x + + INSTALL_NCUNOP(op_incr, octave_ex, incr); // x++ + INSTALL_NCUNOP(op_decr, octave_ex, decr); // x-- + + // Addition operations + INSTALL_BINOP(op_add, octave_scalar, octave_ex, scalar_ex_add); + INSTALL_BINOP(op_add, octave_ex, octave_scalar, ex_scalar_add); + INSTALL_BINOP(op_add, octave_ex, octave_vpa, ex_vpa_add); + INSTALL_BINOP(op_add, octave_ex, octave_ex, add); + INSTALL_BINOP(op_add, octave_ex, octave_sym, ex_sym_add); + + // Subtraction operations + INSTALL_BINOP(op_sub, octave_scalar, octave_ex, scalar_ex_sub); + INSTALL_BINOP(op_sub, octave_ex, octave_scalar, ex_scalar_sub); + INSTALL_BINOP(op_sub, octave_ex, octave_vpa, ex_vpa_sub); + INSTALL_BINOP(op_sub, octave_ex, octave_ex, sub); + INSTALL_BINOP(op_sub, octave_ex, octave_sym, ex_sym_sub); + + // Multiplication operations + INSTALL_BINOP(op_mul, octave_scalar, octave_ex, scalar_ex_mul); + INSTALL_BINOP(op_mul, octave_ex, octave_scalar, ex_scalar_mul); + INSTALL_BINOP(op_mul, octave_ex, octave_vpa, ex_vpa_mul); + INSTALL_BINOP(op_mul, octave_ex, octave_ex, mul); + INSTALL_BINOP(op_mul, octave_ex, octave_sym, ex_sym_mul); + + // Division operations + INSTALL_BINOP(op_div, octave_scalar, octave_ex, scalar_ex_div); + INSTALL_BINOP(op_div, octave_ex, octave_scalar, ex_scalar_div); + INSTALL_BINOP(op_div, octave_ex, octave_vpa, ex_vpa_div); + INSTALL_BINOP(op_div, octave_ex, octave_ex, div); + INSTALL_BINOP(op_div, octave_ex, octave_sym, ex_sym_div); + + // Power operations + INSTALL_BINOP(op_pow, octave_scalar, octave_ex, scalar_ex_pow); + INSTALL_BINOP(op_pow, octave_ex, octave_scalar, ex_scalar_pow); + INSTALL_BINOP(op_pow, octave_ex, octave_vpa, ex_vpa_pow); + INSTALL_BINOP(op_pow, octave_ex, octave_sym, ex_sym_pow); + INSTALL_BINOP(op_pow, octave_ex, octave_ex, pow); +} + +DEFINE_OCTAVE_ALLOCATOR (octave_ex); + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_ex, "ex"); + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-ex.h Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,100 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#if !defined (octave_ex_h) +#define octave_ex_h 1 + +#include <ginac/ginac.h> + +void install_ex_type(); +void install_ex_ops(); + +class +octave_ex : public octave_base_value +{ +public: + octave_ex(void):octave_base_value() {} + + octave_ex(octave_ex &ox) + { + // x = *(ox.x.bp->duplicate()); + x = ox.x; + } + + octave_ex(GiNaC::symbol sym) + { + // x = *(sym.duplicate()); + x = sym; + } + + octave_ex(GiNaC::ex expression) + { + // x = *(expression.bp->duplicate()); + x = expression; + } + + ~octave_ex() {} + + octave_ex& operator=(const octave_ex&); + + GiNaC::ex ex_value(bool = false) const + { + // GiNaC::ex tmp = *(x.bp->duplicate()); + // return tmp; + return x; + } + + octave_value *clone (void) + { + return new octave_ex (*this); + } + + int rows (void) const { return 1; } + int columns (void) const { return 1; } + + bool is_constant (void) const { return true; } + bool is_defined (void) const { return true; } + + bool valid_as_scalar_index(void) const {return false;} + + bool is_true(void) const { return true; } + + octave_value uminus (void) const { return new octave_ex(-x); } + + void increment (void) { x = x+1;} + + void decrement (void) { x = x-1;} + + void print(ostream& os,bool pr_as_read_syntax) const; + +private: + GiNaC::ex x; + + DECLARE_OCTAVE_ALLOCATOR + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA + +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-sym.cc Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,185 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#include <octave/config.h> + +#include <cstdlib> + +#include <string> + +class ostream; + +#include <octave/lo-mappers.h> +#include <octave/lo-utils.h> +#include <octave/mx-base.h> +#include <octave/str-vec.h> + +#include <octave/error.h> +#include <octave/gripes.h> +#include <octave/oct-obj.h> +#include <octave/ops.h> +#include <octave/ov-base.h> +#include <octave/ov-typeinfo.h> +#include <octave/ov.h> +#include <octave/ov-scalar.h> +#include <octave/pager.h> +#include <octave/pr-output.h> +#include <octave/symtab.h> +#include <octave/variables.h> +#include "ov-ex.h" +#include "ov-sym.h" +#include "ov-vpa.h" + +#ifdef DEFUNOP_OP +#undef DEFUNOP_OP +#endif + +#define DEFUNOP_OP(name, t, op) \ + UNOPDECL (name, a) \ + { \ + CAST_UNOP_ARG (const octave_ ## t&); \ + return octave_value (new octave_ex (op v.t ## _value ())); \ + } + +DEFUNOP_OP (uminus, sym, -) + +#ifdef DEFBINOP_OP +#undef DEFBINOP_OP +#endif + + +#define DEFBINOP_OP(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (v1.t1 ## _value () op v2.t2 ## _value ())); \ + } + +#ifdef DEFBINOP_POW +#undef DEFBINOP_POW +#endif + +#define DEFBINOP_POW(name, t1, t2) \ + BINOPDECL(name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (pow(v1.t1 ## _value (), v2.t2 ## _value ()))); \ + } + +// Addition operations +DEFBINOP_OP(sym_scalar_add,sym,scalar,+) +DEFBINOP_OP(scalar_sym_add,scalar,sym,+) +DEFBINOP_OP(sym_vpa_add,sym,vpa,+) +DEFBINOP_OP (sym_sym_add, sym, sym, +) +DEFBINOP_OP(sym_ex_add,sym,ex,+) + +// Subtraction operations +DEFBINOP_OP(sym_scalar_sub,sym,scalar,-) +DEFBINOP_OP(scalar_sym_sub,scalar,sym,-) +DEFBINOP_OP(sym_vpa_sub,sym,vpa,-) +DEFBINOP_OP (sym_sym_sub, sym, sym, -) +DEFBINOP_OP(sym_ex_sub,sym,ex,-) + +// Multiplication operations +DEFBINOP_OP(sym_scalar_mul,sym,scalar,*) +DEFBINOP_OP(scalar_sym_mul,scalar,sym,*) +DEFBINOP_OP(sym_vpa_mul,sym,vpa,*) +DEFBINOP_OP (sym_sym_mul, sym, sym, *) +DEFBINOP_OP(sym_ex_mul,sym,ex,*) + +// Division operations +DEFBINOP_OP(sym_scalar_div,sym,scalar,/) +DEFBINOP_OP(scalar_sym_div,scalar,sym,/) +DEFBINOP_OP(sym_vpa_div,sym,vpa,/) +DEFBINOP_OP (sym_sym_div, sym, sym, /) +DEFBINOP_OP(sym_ex_div,sym,ex,/) + +// Power operations +DEFBINOP_POW(sym_sym_pow,sym,sym) +DEFBINOP_POW(sym_scalar_pow,sym,scalar) +DEFBINOP_POW(scalar_sym_pow,scalar,sym) +DEFBINOP_POW(sym_vpa_pow,sym,vpa) +DEFBINOP_POW(sym_ex_pow,sym,ex) + +GiNaC::symbol octave_sym::sym_value() const +{ + // This is ugly + return ex_to_symbol(GiNaC::ex(*(x.duplicate ()))); +} + +void +install_sym_type() +{ + octave_sym::register_type(); + + cerr << "installing sym type at type-id = " + << octave_sym::static_type_id() << "\n"; +} + +void +install_sym_ops() +{ + INSTALL_UNOP(op_uminus, octave_sym, uminus); // -x + + // Addition operations + INSTALL_BINOP(op_add, octave_scalar, octave_sym, scalar_sym_add); + INSTALL_BINOP(op_add, octave_sym, octave_scalar, sym_scalar_add); + INSTALL_BINOP(op_add, octave_sym, octave_vpa, sym_vpa_add); + INSTALL_BINOP(op_add, octave_sym, octave_sym, sym_sym_add); + INSTALL_BINOP(op_add, octave_sym, octave_ex, sym_ex_add); + + // Subtraction operations + INSTALL_BINOP(op_sub, octave_scalar, octave_sym, scalar_sym_sub); + INSTALL_BINOP(op_sub, octave_sym, octave_scalar, sym_scalar_sub); + INSTALL_BINOP(op_sub, octave_sym, octave_vpa, sym_vpa_sub); + INSTALL_BINOP(op_sub, octave_sym, octave_sym, sym_sym_sub); + INSTALL_BINOP(op_sub, octave_sym, octave_ex, sym_ex_sub); + + // Multiplication operations + INSTALL_BINOP(op_mul, octave_scalar, octave_sym, scalar_sym_mul); + INSTALL_BINOP(op_mul, octave_sym, octave_scalar, sym_scalar_mul); + INSTALL_BINOP(op_mul, octave_sym, octave_vpa, sym_vpa_mul); + INSTALL_BINOP(op_mul, octave_sym, octave_sym, sym_sym_mul); + INSTALL_BINOP(op_mul, octave_sym, octave_ex, sym_ex_mul); + + // Division operations + INSTALL_BINOP(op_div, octave_scalar, octave_sym, scalar_sym_div); + INSTALL_BINOP(op_div, octave_sym, octave_scalar, sym_scalar_div); + INSTALL_BINOP(op_div, octave_sym, octave_vpa, sym_vpa_div); + INSTALL_BINOP(op_div, octave_sym, octave_sym, sym_sym_div); + INSTALL_BINOP(op_div, octave_sym, octave_ex, sym_ex_div); + + // Power operations + INSTALL_BINOP(op_pow, octave_scalar, octave_sym, scalar_sym_pow); + INSTALL_BINOP(op_pow, octave_sym, octave_scalar, sym_scalar_pow); + INSTALL_BINOP(op_pow, octave_sym, octave_vpa, sym_vpa_pow); + INSTALL_BINOP(op_pow, octave_sym, octave_sym, sym_sym_pow); + INSTALL_BINOP(op_pow, octave_sym, octave_ex, sym_ex_pow); +} + +DEFINE_OCTAVE_ALLOCATOR (octave_sym); + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sym, "sym"); + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-sym.h Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,92 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#if !defined (octave_sym_h) +#define octave_sym_h 1 + +#include <ginac/ginac.h> +#include "ov.h" +#include "ov-base.h" +#include "ov-ex.h" + +class Octave_map; +class octave_value_list; +class tree_walker; + +void install_sym_type(); +void install_sym_ops(); + +class +octave_sym : public octave_base_value +{ +public: + octave_sym(void){} + + octave_sym(char *str) + { + x = GiNaC::symbol(str); + } + + octave_sym(const octave_sym &xtmp):x(xtmp.x){} + + octave_sym(GiNaC::symbol xtmp):x(xtmp){} + + ~octave_sym (void) {} + + octave_value *clone (void) {return new octave_sym(*this);} + + GiNaC::symbol sym_value(void) const; + + octave_value uminus (void){ return (new octave_ex(-x));} + + void print(ostream& os,bool pr_as_read_syntax) const + { + os << x; + } + + int rows (void) const { return 1; } + int columns (void) const { return 1; } + + bool is_constant (void) const { return true; } + bool is_defined (void) const { return true; } + bool is_real_scalar (void) const { return false; } + + bool is_real_type(void) const {return false;} + bool is_scalar_type(void) const {return true;} + bool is_numeric_type(void) const {return false;} + + bool valid_as_scalar_index(void) const {return false;} + + bool is_true(void) const { return true; } + +private: + GiNaC::symbol x; + + DECLARE_OCTAVE_ALLOCATOR + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA + +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-vpa.cc Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,234 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + + +#include <octave/config.h> + +#include <cstdlib> + +#include <string> + +class ostream; + +#include <octave/lo-mappers.h> +#include <octave/lo-utils.h> +#include <octave/mx-base.h> +#include <octave/str-vec.h> + +#include <octave/defun-dld.h> +#include <octave/error.h> +#include <octave/gripes.h> +#include <octave/oct-obj.h> +#include <octave/ops.h> +#include <octave/ov-base.h> +#include <octave/ov-typeinfo.h> +#include <octave/ov.h> +#include <octave/ov-scalar.h> +#include <octave/pager.h> +#include <octave/pr-output.h> +#include <octave/symtab.h> +#include <octave/variables.h> +#include "ov-vpa.h" +#include "ov-ex.h" +#include "ov-sym.h" + +void +octave_vpa::print (ostream& os, bool pr_as_read_syntax) const +{ + os << scalar; +} + + +#ifdef DEFUNOP_OP +#undef DEFUNOP_OP +#endif + +#define DEFUNOP_OP(name, t, op) \ + UNOPDECL (name, a) \ + { \ + CAST_UNOP_ARG (const octave_ ## t&); \ + return octave_value (new octave_vpa (op v.t ## _value ())); \ + } + +// DEFUNOP_OP (not, vpa, !) +DEFUNOP_OP (uminus, vpa, -) +DEFUNOP_OP (transpose, vpa, /* no-op */) +DEFUNOP_OP (hermitian, vpa, /* no-op */) + +DEFNCUNOP_METHOD (incr, vpa, increment) +DEFNCUNOP_METHOD (decr, vpa, decrement) + +#ifdef DEFBINOP_OP +#undef DEFBINOP_OP +#endif + +#define DEFBINOP_OP(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_vpa (v1.t1 ## _value () op v2.t2 ## _value ())); \ + } + +#define DEFBINOP_OP_NUM(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_vpa (v1.t1 ## _value () op v2.t2 ## _value ())); \ + } + +#define DEFBINOP_OP_EX(name, t1, t2, op) \ + BINOPDECL (name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (v1.t1 ## _value () op v2.t2 ## _value ())); \ + } + + +#ifdef DEFBINOP_POW +#undef DEFBINOP_POW +#endif + +#define DEFBINOP_POW(name, t1, t2) \ + BINOPDECL(name, a1, a2) \ + { \ + CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \ + return octave_value \ + (new octave_ex (pow(v1.t1 ## _value (), v2.t2 ## _value ()))); \ + } + +// relational ops. +DEFBINOP_OP (lt, vpa, vpa, <) +DEFBINOP_OP (le, vpa, vpa, <=) +DEFBINOP_OP (eq, vpa, vpa, ==) +DEFBINOP_OP (ge, vpa, vpa, >=) +DEFBINOP_OP (gt, vpa, vpa, >) +DEFBINOP_OP (ne, vpa, vpa, !=) + //DEFBINOP_OP (el_mul, vpa, vpa, !=) + + //#error The type of return arguements in sym_vpa class are not always correct + +// Addition operations +DEFBINOP_OP_NUM(vpa_scalar_add,vpa,scalar,+) +DEFBINOP_OP_NUM(scalar_vpa_add,scalar,vpa,+) +DEFBINOP_OP_NUM (add, vpa, vpa, +) +DEFBINOP_OP_EX(vpa_sym_add,vpa,sym,+) +DEFBINOP_OP_EX(vpa_ex_add,vpa,ex,+) + +// Subtraction operations +DEFBINOP_OP_NUM(vpa_scalar_sub,vpa,scalar,-) +DEFBINOP_OP_NUM(scalar_vpa_sub,scalar,vpa,-) +DEFBINOP_OP_NUM(sub, vpa, vpa, -) +DEFBINOP_OP_EX(vpa_sym_sub,vpa,sym,-) +DEFBINOP_OP_EX(vpa_ex_sub,vpa,ex,-) + +// Multiplication operations +DEFBINOP_OP_NUM(vpa_scalar_mul,vpa,scalar,*) +DEFBINOP_OP_NUM(scalar_vpa_mul,scalar,vpa,*) +DEFBINOP_OP_NUM(mul, vpa, vpa, *) +DEFBINOP_OP_EX(vpa_sym_mul,vpa,sym,*) +DEFBINOP_OP_EX(vpa_ex_mul,vpa,ex,*) + +// Division operations +DEFBINOP_OP_NUM(vpa_scalar_div,vpa,scalar,/) +DEFBINOP_OP_NUM(scalar_vpa_div,scalar,vpa,/) +DEFBINOP_OP_NUM(div, vpa, vpa, /) +DEFBINOP_OP_EX(vpa_sym_div,vpa,sym,/) +DEFBINOP_OP_EX(vpa_ex_div,vpa,ex,/) + +// Power operations +DEFBINOP_POW(pow,vpa,vpa) +DEFBINOP_POW(vpa_scalar_pow,vpa,scalar) +DEFBINOP_POW(scalar_vpa_pow,scalar,vpa) +DEFBINOP_POW(vpa_sym_pow,vpa,sym) +DEFBINOP_POW(vpa_ex_pow,vpa,ex) + +void +install_vpa_type() +{ + octave_vpa::register_type (); + + cerr << "installing vpa type at type-id = " + << octave_vpa::static_type_id () << "\n"; +} + +void install_vpa_ops() +{ + // INSTALL_UNOP (op_not, octave_vpa, not); + INSTALL_UNOP (op_uminus, octave_vpa, uminus); + INSTALL_UNOP (op_transpose, octave_vpa, transpose); + INSTALL_UNOP (op_hermitian, octave_vpa, hermitian); + + INSTALL_NCUNOP (op_incr, octave_vpa, incr); + INSTALL_NCUNOP (op_decr, octave_vpa, decr); + + // Addition operations + INSTALL_BINOP(op_add, octave_scalar, octave_vpa, scalar_vpa_add); + INSTALL_BINOP(op_add, octave_vpa, octave_scalar, vpa_scalar_add); + INSTALL_BINOP(op_add, octave_vpa, octave_vpa, add); + INSTALL_BINOP(op_add, octave_vpa, octave_sym, vpa_sym_add); + INSTALL_BINOP(op_add, octave_vpa, octave_ex, vpa_ex_add); + + // Subtraction operations + INSTALL_BINOP(op_sub, octave_scalar, octave_vpa, scalar_vpa_sub); + INSTALL_BINOP(op_sub, octave_vpa, octave_scalar, vpa_scalar_sub); + INSTALL_BINOP(op_sub, octave_vpa, octave_vpa, sub); + INSTALL_BINOP(op_sub, octave_vpa, octave_sym, vpa_sym_sub); + INSTALL_BINOP(op_sub, octave_vpa, octave_ex, vpa_ex_sub); + + // Multiplication operations + INSTALL_BINOP(op_mul, octave_scalar, octave_vpa, scalar_vpa_mul); + INSTALL_BINOP(op_mul, octave_vpa, octave_scalar, vpa_scalar_mul); + INSTALL_BINOP(op_mul, octave_vpa, octave_vpa, mul); + INSTALL_BINOP(op_mul, octave_vpa, octave_sym, vpa_sym_mul); + INSTALL_BINOP(op_mul, octave_vpa, octave_ex, vpa_ex_mul); + + // Division operations + INSTALL_BINOP(op_div, octave_scalar, octave_vpa, scalar_vpa_div); + INSTALL_BINOP(op_div, octave_vpa, octave_scalar, vpa_scalar_div); + INSTALL_BINOP(op_div, octave_vpa, octave_vpa, div); + INSTALL_BINOP(op_div, octave_vpa, octave_sym, vpa_sym_div); + INSTALL_BINOP(op_div, octave_vpa, octave_ex, vpa_ex_div); + + // Power operations + INSTALL_BINOP(op_pow, octave_scalar, octave_vpa, scalar_vpa_pow); + INSTALL_BINOP(op_pow, octave_vpa, octave_scalar, vpa_scalar_pow); + INSTALL_BINOP(op_pow, octave_vpa, octave_vpa, pow); + INSTALL_BINOP(op_pow, octave_vpa, octave_sym, vpa_sym_pow); + INSTALL_BINOP(op_pow, octave_vpa, octave_ex, vpa_ex_pow); + + INSTALL_BINOP (op_lt, octave_vpa, octave_vpa, lt); + INSTALL_BINOP (op_le, octave_vpa, octave_vpa, le); + INSTALL_BINOP (op_eq, octave_vpa, octave_vpa, eq); + INSTALL_BINOP (op_ge, octave_vpa, octave_vpa, ge); + INSTALL_BINOP (op_gt, octave_vpa, octave_vpa, gt); + INSTALL_BINOP (op_ne, octave_vpa, octave_vpa, ne); + +} + +DEFINE_OCTAVE_ALLOCATOR (octave_vpa); + +DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_vpa, "vpa"); + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/ov-vpa.h Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,125 @@ +/* +Copyright (C) 2000 Benjamin Sapp + +This 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, or (at your option) any +later version. + +This 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 can have receive a copy of the GNU General Public License. Write +to the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#if !defined (octave_vpa_h) +#define octave_vpa_h 1 + +// GiNaC +#include <ginac/ginac.h> + +class Octave_map; +class octave_value_list; + +class tree_walker; + +void install_vpa_type(); +void install_vpa_ops(); + +// vpa values. + +class +octave_vpa : public octave_base_value +{ +public: + + octave_vpa (void):octave_base_value() + { + scalar = GiNaC::numeric(0); + } + + octave_vpa (int i):octave_base_value() + { + scalar = GiNaC::numeric(0); + } + + octave_vpa (const octave_vpa& s):octave_base_value() + { + scalar = s.scalar; + } + + octave_vpa (const GiNaC::numeric& s):octave_base_value() + { + scalar = s; + } + + octave_vpa( const GiNaC::ex& x):octave_base_value() + { + scalar = GiNaC::ex_to_numeric(x); + } + + ~octave_vpa (void) { } + + octave_value *clone (void) { return new octave_vpa (*this); } + +#if 0 + void *operator new (size_t size); + void operator delete (void *p, size_t size); +#endif + + int rows (void) const { return 1; } + int columns (void) const { return 1; } + + bool is_constant (void) const { return true; } + + bool is_defined (void) const { return true; } + bool is_real_scalar (void) const { return true; } + + octave_value all (void) const { return (double) (scalar != 0); } + octave_value any (void) const { return (double) (scalar != 0); } + + bool is_real_type (void) const { return true; } + bool is_scalar_type (void) const { return true; } + bool is_vpa_type (void) const { return true; } + + bool valid_as_scalar_index (void) const + { return scalar == 1; } + + bool valid_as_zero_index (void) const + { return scalar == 0; } + + bool is_true (void) const { return (scalar != 0); } + + double double_value (bool = false) const { return scalar.to_double(); } + + GiNaC::numeric vpa_value (bool = false) const { return scalar; } + + octave_value hermitian (void) const { return new octave_vpa (scalar); } + + void increment (void) { ++scalar; } + + void decrement (void) { --scalar; } + + void print (ostream& os, bool pr_as_read_syntax = false) const; + +private: + + GiNaC::numeric scalar; + + DECLARE_OCTAVE_ALLOCATOR + + DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/splot.m Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,17 @@ +## -*- texinfo -*- +## @deftypefn {Function File} splot(@var{f},@var{x},@var{range}) +## Plot a symbolic function f(x) over range. +## @end deftypefn + +function splot(expression,symbol,range) + ## we should be a little smarter about this + t = linspace(min(range),max(range),400); + x = zeros(size(t)); + j = 1; + for i = t + x(j) = to_double(subs(expression,symbol,vpa(t(j)))); + j++; + endfor + + plot(t,x); +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/symbols.cc Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,563 @@ + +// 2001-09-18 Paul Kienzle <pkienzle@users.sf.net> +// * use GiNaC::is_a<GiNaC::blah>(x) rather than is_ex_of_type(x, blah) +// * use GiNaC::ex_to<GiNaC::blah>(x) rather than ex_to_blah(x) + +#include <octave/config.h> +#include <cstdlib> + +#include <string> + +class ostream; +class octave_sym; + +#include <octave/lo-mappers.h> +#include <octave/lo-utils.h> +#include <octave/mx-base.h> +#include <octave/str-vec.h> + +#include <octave/defun-dld.h> +#include <octave/error.h> +#include <octave/gripes.h> +#include <octave/oct-obj.h> +#include <octave/ops.h> +#include <octave/ov-base.h> +#include <octave/ov-typeinfo.h> +#include <octave/ov.h> +#include <octave/ov-scalar.h> +#include <octave/pager.h> +#include <octave/pr-output.h> +#include <octave/symtab.h> +#include <octave/variables.h> +#include <iostream> +#include <fstream> + +#include <ginac/ginac.h> + +#include "ov-vpa.h" +#include "ov-ex.h" +#include "ov-sym.h" +#include "symbols.h" + +bool get_expression(const octave_value arg, GiNaC::ex& expression) +{ + const octave_value& rep = (arg).get_rep(); + + if (arg.type_id () == octave_vpa::static_type_id ()) + { + GiNaC::numeric x = ((octave_vpa& ) rep).vpa_value(); + expression = x+0; + } + else if (arg.type_id () == octave_sym::static_type_id ()) + { + GiNaC::symbol x = ((octave_sym& ) rep).sym_value(); + expression = x+0; + } + else if (arg.type_id () == octave_ex::static_type_id ()) + { + GiNaC::ex x = ((octave_ex& ) rep).ex_value(); + expression = x; + } + else if (arg.is_real_scalar ()) + { + GiNaC::numeric x(arg.double_value ()); + expression = x+0; + } + else + { + return false; + } + + return true; +} + +bool get_symbol(const octave_value arg, GiNaC::symbol& sym) +{ + const octave_value& rep = arg.get_rep (); + + if (arg.type_id () == octave_sym::static_type_id ()) + sym = ((octave_sym& ) rep).sym_value(); + else if (arg.type_id () == octave_ex::static_type_id ()) + { + GiNaC::ex x = ((octave_ex& ) rep).ex_value(); + if(GiNaC::is_a<GiNaC::symbol>(x)) + sym = GiNaC::ex_to<GiNaC::symbol>(x); + else + return false; + } + else + return false; + + return true; +} + +bool get_numeric(const octave_value arg, GiNaC::numeric& number) +{ + const octave_value& rep = arg.get_rep (); + + if (arg.type_id () == octave_ex::static_type_id ()) + { + GiNaC::ex x = ((octave_ex& ) rep).ex_value(); + if(GiNaC::is_a<GiNaC::numeric>(x)) + number = GiNaC::ex_to<GiNaC::numeric>(x); + else + return false; + } + else if (arg.type_id () == octave_vpa::static_type_id ()) + number = ((const octave_vpa &) rep).vpa_value (); + else if (arg.is_real_scalar ()) + number = GiNaC::numeric (arg.double_value ()); + else if (arg.is_string ()) + number = GiNaC::numeric (arg.string_value ().c_str ()); + else + return false; + + return true; +} + +DEFUN_DLD(symbols,args,,"Initialize symbolic manipulation") +{ + octave_value retval; + install_ex_type(); + install_sym_type(); + install_vpa_type(); + install_ex_ops(); + install_sym_ops(); + install_vpa_ops(); + return retval; +} + +DEFUN_DLD (vpa, args, , +"-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {n =} vpa(@var{s})\n\ +\n\ +Creates a variable precision arithmetic variable from @var{s}.\n\ +@var{s} can be a scalar, vpa value, string or a ex value that \n\ +is a number.\n\ +@end deftypefn\n\ +") +{ + octave_value retval; + GiNaC::numeric d; + int nargin = args.length(); + + if (nargin == 1) + { + if (!get_numeric (args(0), d)) + { + gripe_wrong_type_arg ("vpa", args(0)); + return retval; + } + } + else + { + print_usage("vpa"); + return retval; + } + + retval = octave_value(new octave_vpa(d)); + + return retval; +} + +DEFUN_DLD(to_double,args, , +"-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {d =} to_double(@var{n})\n\ +\n\ +Convert a vpa, string, ex or string type to a double.\n\ +\n\ +@end deftypefn\n\ +") +{ + octave_value retval; + int nargin = args.length(); + GiNaC::numeric num; + + if (nargin != 1) + { + print_usage("to_double"); + return retval; + } + + if (!get_numeric (args(0), num)) + { + print_usage("to_double"); + return retval; + } + + retval = octave_value(num.to_double ()); + + return retval; +} + +DEFUN_DLD(digits, args, , +"-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{dgts} =} digits([@var{num}])\n\ +Change the precision for the vpa type +@end deftypefn\n\ +") +{ + octave_value retval; + int nargin = args.length(); + + if ((nargin != 1) && (nargin != 0)) + { + error("you must supply 0 or 1 arguments\n"); + return(retval); + } + + if(nargin == 1) + { + if(args(0).is_real_scalar()) + { + GiNaC::Digits = int(args(0).double_value()); + } + else + { + print_usage("digits"); + } + } + + double dig = double(GiNaC::Digits); + retval = octave_value(dig); + return(retval); +} + +DEFUN_DLD(Pi,args, , +"-*- texinfo -*-\n\ +Pi evaluated to the current value of Digits\n\ +\n\ +@seealso{digits}") +{ + return octave_value(new octave_vpa(GiNaC::ex_to_numeric(GiNaC::Pi.evalf()))); +} + +DEFUN_DLD(is_vpa, args, , +"Return true if an object is of type vpa, false otherwise.\n") +{ + bool retval; + retval = (args(0).type_id() == octave_vpa::static_type_id()); + return octave_value(retval); +} + +DEFUN_DLD (sym,args, , +"-*- texinfo -*-\n\ +Create an object of type symbol\n") +{ + int nargin = args.length (); + + if (nargin != 1) + { + error("one argument expected\n"); + return octave_value (); + } + + GiNaC::symbol xtmp(args(0).string_value()); + octave_sym x(xtmp); + return octave_value(new octave_sym(x)); +} + +DEFUN_DLD(is_sym,args, ,"Return true if an object is of type sym false otherwise.\n") +{ + bool retval; + retval = (args(0).type_id() == octave_sym::static_type_id()); + return octave_value(retval); +} + +DEFUN_DLD(differentiate,args,, +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {da_dx =} differentiate(@var{a},@var{x} [, @var{n}])\n\ +\n\ +Return the @var{n}th derivative of @var{a} with respect to @var{x}. If @var{n} is not\n\ +supplied then a default value of 1 is used.\n\ +@end deftypefn") +{ + GiNaC::ex expression; + GiNaC::symbol variable; + GiNaC::numeric num; + int order; + octave_value retval; + int nargin = args.length(); + + if ((nargin < 2) || (nargin > 3)) + { + print_usage ("differentiate"); + return retval; + } + + if (!get_expression (args(0), expression)) + { + print_usage ("differentiate"); + return retval; + } + + if (!get_symbol (args(1), variable)) + { + print_usage ("differentiate"); + return retval; + } + + if (nargin == 3) + { + if (!get_numeric (args(2), num)) + { + print_usage ("differentiate"); + return retval; + } + order = int(num.to_double ()); + if (order < 0) + { + error("must supply an integer greater than zero\n"); + return retval; + } + } + else + order = 1; + + return octave_value(new octave_ex(expression.diff(variable,order))); +} + +DEFINE_EX_GINAC_FUNCTION(Cos,cos,"cosine"); +DEFINE_EX_GINAC_FUNCTION(Sin,sin,"sine"); +DEFINE_EX_GINAC_FUNCTION(Tan,tan,"tangent"); +DEFINE_EX_GINAC_FUNCTION(aCos,acos,"inverse cosine"); +DEFINE_EX_GINAC_FUNCTION(aSin,asin,"inverse sine"); +DEFINE_EX_GINAC_FUNCTION(aTan,atan,"inverse tangent"); +DEFINE_EX_GINAC_FUNCTION(Cosh,cosh,"hyperbolic cosine"); +DEFINE_EX_GINAC_FUNCTION(Sinh,sinh,"hyperbolic sine"); +DEFINE_EX_GINAC_FUNCTION(Tanh,tanh,"hyperbolic tangent"); +DEFINE_EX_GINAC_FUNCTION(aCosh,acosh,"inverse hyperbolic cosine"); +DEFINE_EX_GINAC_FUNCTION(aSinh,asinh,"inverse hyperbolic sine"); +DEFINE_EX_GINAC_FUNCTION(aTanh,atanh,"inverse hyperbolic tangent"); +DEFINE_EX_GINAC_FUNCTION(Exp,exp,"exponential"); +DEFINE_EX_GINAC_FUNCTION(Log,log,"logarithm"); +DEFINE_EX_GINAC_FUNCTION(Abs,abs,"absolute value"); + +DEFINE_EX_SYM_GINAC_FUNCTION(degree, degree,"degree"); +DEFINE_EX_SYM_GINAC_FUNCTION(ldegree, ldegree,"low degree"); +DEFINE_EX_SYM_GINAC_FUNCTION(tcoeff, tcoeff, "trailing coeffiecient"); +DEFINE_EX_SYM_GINAC_FUNCTION(lcoeff, lcoeff, "leading coefficient"); + +DEFINE_EX_EX_SYM_GINAC_FUNCTION(quotient,quo,"quotient"); +DEFINE_EX_EX_SYM_GINAC_FUNCTION(remainder,rem,"remainder"); +DEFINE_EX_EX_SYM_GINAC_FUNCTION(premainder,prem,"pseudo-remainder"); + +DEFUN_DLD(is_ex,args,, +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {bool =} is_ex(@var{a})\n\ +\n\ +Return true if an object is of type ex.\n\ +@seealso{is_sym, is_vpa}") +{ + bool retval; + retval = (args(0).type_id() == octave_ex::static_type_id()); + return octave_value(retval); +} + +DEFUN_DLD(subs,args,, +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {b =} subs(@var{a},@var{x},@var{n})\n\ +\n\ +Substitute a number for a variables in an expression\n\ +@table @var\n\ +@item a\n\ + The expresion in which the substition will occur.\n\ +@item x\n\ + The variable that will be substituted.\n\ +@item n\n\ + The expression,vpa value or scalar that will replace x.\n\ +@end table\n\ +\n\ +@end deftypefn\n\ +") +{ + GiNaC::ex expression; + GiNaC::symbol the_sym; + GiNaC::ex ex_sub; + GiNaC::ex tmp; + int nargin = args.length (); + octave_value retval; + + if (nargin != 3) + { + error("need three arguments\n"); + return retval; + } + + try + { + if (!get_expression (args(0), expression)) + { + gripe_wrong_type_arg ("subs",args(0)); + return retval; + } + + if (!get_symbol (args(1), the_sym)) + { + gripe_wrong_type_arg("subs",args(1)); + return retval; + } + + if (!get_expression (args(2), ex_sub)) + { + gripe_wrong_type_arg ("subs",args(2)); + return retval; + } + + tmp = expression.subs(the_sym == ex_sub); + retval = octave_value (new octave_ex(tmp)); + } + catch (exception e) + { + e.what (); + return octave_value (); + } + + return retval; +} + +DEFUN_DLD(expand,args,, +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {b =} expand(@var{a})\n\ +\n\ +Expand an expression\n\ +@table @var\n\ +@item a\n\ + The expresion in which the expansion will occur.\n\ +@end table\n\ +\n\ +@end deftypefn\n\ +") +{ + GiNaC::ex expression; + GiNaC::symbol the_sym; + GiNaC::ex result; + octave_value retval; + + if(args.length() != 1) + { + print_usage("expand"); + return retval; + } + if(args(0).type_id() == octave_ex::static_type_id()) + { + const octave_value& rep1 = args(0).get_rep(); + expression = ((const octave_ex& ) rep1).ex_value(); + } + else + { + gripe_wrong_type_arg("expand",args(0)); + } + + result = expression.expand(); + return octave_value(new octave_ex(result)); +} + +DEFUN_DLD(coeff,args,, +"-*- texinfo -*- +@deftypefn {Loadable Function} {b =} coeff(@var{a},@var{x},@var{n})\n\ +\n\ +Obtain the @var{n}th coefficient of the variable @var{x} in @var{a}. +\n\ +@end deftypefn\n\ +") +{ + octave_value retval; + GiNaC::ex expression; + GiNaC::symbol sym; + int n; + + if(args.length () != 3) + { + print_usage("coeff"); + return retval; + } + + if(args(0).type_id() == octave_ex::static_type_id()) + { + const octave_value& rep0 = args(0).get_rep(); + expression = ((const octave_ex& ) rep0).ex_value(); + } + else + { + gripe_wrong_type_arg("coeff",args(0)); + return retval; + } + + if(args(1).type_id() == octave_sym::static_type_id()) + { + const octave_value& rep1 = args(1).get_rep(); + sym = ((const octave_sym& ) rep1).sym_value(); + } + else + { + gripe_wrong_type_arg("coeff",args(1)); + return retval; + } + + if(args(2).is_real_scalar()) + { + n = (int )args(2).double_value(); + } + else + { + gripe_wrong_type_arg("coeff",args(2)); + return retval; + } + + retval = octave_value (new octave_ex (expression.coeff(sym,n))); + + return retval; +} + +DEFUN_DLD(collect,args,, +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {b =} collect(@var{a},@var{x})\n\ +\n\ +collect the terms in @var{a} as a univariate polynomial in @var{x}\n\ +@table @var\n\ +@item a\n\ + The expresion in which the collection will occur.\n\ +@item x\n\ + The variable that will be collected.\n\ +@end table\n\ +\n\ +@end deftypefn\n\ +") +{ + octave_value retval; + GiNaC::ex expression; + GiNaC::symbol the_sym; + + if(args.length() != 2) + { + print_usage("collect"); + return retval; + } + + if(args(0).type_id() == octave_ex::static_type_id()) + { + const octave_value& rep1 = args(0).get_rep(); + expression = ((const octave_ex& ) rep1).ex_value(); + } + else + { + gripe_wrong_type_arg("collect",args(0)); + } + + if(args(1).type_id() == octave_sym::static_type_id()) + { + const octave_value& rep2 = args(1).get_rep(); + the_sym = ((octave_sym& ) rep2).sym_value(); + } + else + { + gripe_wrong_type_arg("collect",args(1)); + } + + retval = new octave_ex(expression.collect(the_sym)); + + return retval; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/symbolic/symbols.h Wed Nov 14 15:09:50 2001 +0000 @@ -0,0 +1,133 @@ + +bool get_expression(const octave_value arg, GiNaC::ex& expression); +bool get_symbol(const octave_value arg, GiNaC::symbol& sym); +bool get_numeric(const octave_value arg, GiNaC::numeric& number); + +#define DEFINE_EX_GINAC_FUNCTION(oct_name,ginac_name,description) \ +DEFUN_DLD(oct_name, args, , \ +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {r =}" # oct_name "(@var{x})\n\ +Return the " description " of a symbolic expression.\n\ +@end deftypefn\n\ +") \ +{ \ + int nargin = args.length (); \ + octave_value retval; \ + octave_ex *r = NULL; \ + GiNaC::ex expression; \ + \ + if (nargin != 1) \ + { \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + try \ + { \ + if(!get_expression(args(0), expression)) \ + { \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + r = new octave_ex(GiNaC::ginac_name (expression)); \ + \ + } \ + catch (exception e) \ + { \ + e.what (); \ + return octave_value (); \ + } \ + \ + return octave_value(r); \ +} + +#define DEFINE_EX_SYM_GINAC_FUNCTION(oct_name,ginac_name,description) \ +DEFUN_DLD(oct_name, args, , \ +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {r =}" # oct_name "(@var{a}, @var{x})\n\ +Return the " description " of a symbolic expression.\n\ +@end deftypefn\n\ +") \ +{ \ + int nargin = args.length (); \ + octave_value retval; \ + octave_ex *r = NULL; \ + GiNaC::ex expression; \ + GiNaC::symbol sym; \ + \ + if (nargin != 2) \ + { \ + error("need exactly two arguments"); \ + return retval; \ + } \ + \ + if(!get_expression(args(0), expression)) \ + { \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + if (!get_symbol(args(1), sym)) \ + { \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + r = new octave_ex(expression.ginac_name(sym)); \ + \ + return octave_value(r); \ +} + +#define DEFINE_EX_EX_SYM_GINAC_FUNCTION(oct_name,ginac_name,description) \ +DEFUN_DLD(oct_name, args, , \ +"-*- texinfo -*-\n\ +@deftypefn Loadable Function {r =}" # oct_name "(@var{a}, @var{x})\n\ +Return the " description " of a symbolic expression.\n\ +@end deftypefn\n\ +") \ +{ \ + int nargin = args.length (); \ + octave_value retval; \ + octave_ex *r = NULL; \ + GiNaC::ex expression0; \ + GiNaC::ex expression1; \ + GiNaC::symbol sym; \ + \ + if (nargin != 3) \ + { \ + error("need exactly three arguments"); \ + return retval; \ + } \ + \ + if(!get_expression(args(0), expression0)) \ + { \ + gripe_wrong_type_arg(# oct_name, args(0)); \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + if(!get_expression(args(1), expression1)) \ + { \ + gripe_wrong_type_arg(# oct_name, args(1)); \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + if (!get_symbol(args(2), sym)) \ + { \ + gripe_wrong_type_arg(# oct_name, args(2)); \ + print_usage(# oct_name); \ + return retval; \ + } \ + \ + r = new octave_ex(ginac_name (expression0, expression1, sym)); \ + \ + return octave_value(r); \ +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/