]> www.ginac.de Git - ginac.git/commitdiff
*** empty log message ***
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Tue, 30 Sep 2003 20:23:35 +0000 (20:23 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Tue, 30 Sep 2003 20:23:35 +0000 (20:23 +0000)
doc/tutorial/ginac.texi
ginac/Makefile.am
ginac/container.pl
ginac/container_suppl.h [new file with mode: 0644]
ginac/matrix.h

index 2247fe4be60b202da18287d48ef1c1e179047cc2..059d998d6d4fed69aff91e9d8e603ff5b869d6ea 100644 (file)
@@ -1337,14 +1337,27 @@ packages, but are sometimes used to supply a variable number of arguments of
 the same type to GiNaC methods such as @code{subs()} and @code{to_rational()},
 so you should have a basic understanding of them.
 
-Lists of up to 16 expressions can be directly constructed from single
+Lists can be constructed by assigning a comma-separated sequence of
 expressions:
 
 @example
 @{
     symbol x("x"), y("y");
-    lst l(x, 2, y, x+y);
-    // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y'
+    lst l;
+    l = x, 2, y, x+y;
+    // now, l is a list holding the expressions 'x', '2', 'y', and 'x+y',
+    // in that order
+    ...
+@end example
+
+There are also constructors that allow direct creation of lists of up to
+16 expressions, which is often more convenient but slightly less efficient:
+
+@example
+    ...
+    // This produces the same list 'l' as above:
+    // lst l(x, 2, y, x+y);
+    // lst l = lst(x, 2, y, x+y);
     ...
 @end example
 
@@ -1399,10 +1412,10 @@ the C++ standard library:
 @example
     ...
     // print the elements of the list (requires #include <iterator>)
-    copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));
+    std::copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));
 
     // sum up the elements of the list (requires #include <numeric>)
-    ex sum = accumulate(l.begin(), l.end(), ex(0));
+    ex sum = std::accumulate(l.begin(), l.end(), ex(0));
     cout << sum << endl;  // prints '2+2*x+2*y'
     ...
 @end example
@@ -1449,8 +1462,9 @@ You can bring the elements of a list into a canonical order with @code{sort()}:
 
 @example
     ...
-    lst l1(x, 2, y, x+y);
-    lst l2(2, x+y, x, y);
+    lst l1, l2;
+    l1 = x, 2, y, x+y;
+    l2 = 2, x+y, x, y;
     l1.sort();
     l2.sort();
     // l1 and l2 are now equal
@@ -1462,7 +1476,8 @@ elements with @code{unique()}:
 
 @example
     ...
-    lst l3(x, 2, 2, 2, y, x+y, y+x);
+    lst l3;
+    l3 = x, 2, 2, 2, y, x+y, y+x;
     l3.unique();        // l3 is now @{x, 2, y, x+y@}
 @}
 @end example
@@ -1558,16 +1573,39 @@ matrix with @math{m} rows and @math{n} columns are accessed with two
 second one in the range 0@dots{}@math{n-1}.
 
 There are a couple of ways to construct matrices, with or without preset
-elements:
+elements. The constructor
+
+@example
+matrix::matrix(unsigned r, unsigned c);
+@end example
+
+creates a matrix with @samp{r} rows and @samp{c} columns with all elements
+set to zero.
+
+The fastest way to create a matrix with preinitialized elements is to assign
+a list of comma-separated expressions to an empty matrix (see below for an
+example). But you can also specify the elements as a (flat) list with
+
+@example
+matrix::matrix(unsigned r, unsigned c, const lst & l);
+@end example
+
+The function
 
 @cindex @code{lst_to_matrix()}
+@example
+ex lst_to_matrix(const lst & l);
+@end example
+
+constructs a matrix from a list of lists, each list representing a matrix row.
+
+There is also a set of functions for creating some special types of
+matrices:
+
 @cindex @code{diag_matrix()}
 @cindex @code{unit_matrix()}
 @cindex @code{symbolic_matrix()}
 @example
-matrix::matrix(unsigned r, unsigned c);
-matrix::matrix(unsigned r, unsigned c, const lst & l);
-ex lst_to_matrix(const lst & l);
 ex diag_matrix(const lst & l);
 ex unit_matrix(unsigned x);
 ex unit_matrix(unsigned r, unsigned c);
@@ -1575,16 +1613,11 @@ ex symbolic_matrix(unsigned r, unsigned c, const string & base_name);
 ex symbolic_matrix(unsigned r, unsigned c, const string & base_name, const string & tex_base_name);
 @end example
 
-The first two functions are @code{matrix} constructors which create a matrix
-with @samp{r} rows and @samp{c} columns. The matrix elements can be
-initialized from a (flat) list of expressions @samp{l}. Otherwise they are
-all set to zero. The @code{lst_to_matrix()} function constructs a matrix
-from a list of lists, each list representing a matrix row. @code{diag_matrix()}
-constructs a diagonal matrix given the list of diagonal elements.
-@code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r} by @samp{c})
-unit matrix. And finally, @code{symbolic_matrix} constructs a matrix filled
-with newly generated symbols made of the specified base name and the
-position of each element in the matrix.
+@code{diag_matrix()} constructs a diagonal matrix given the list of diagonal
+elements. @code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r}
+by @samp{c}) unit matrix. And finally, @code{symbolic_matrix} constructs a
+matrix filled with newly generated symbols made of the specified base name
+and the position of each element in the matrix.
 
 Matrix elements can be accessed and set using the parenthesis (function call)
 operator:
@@ -1598,18 +1631,24 @@ It is also possible to access the matrix elements in a linear fashion with
 the @code{op()} method. But C++-style subscripting with square brackets
 @samp{[]} is not available.
 
-Here are a couple of examples of constructing matrices:
+Here are a couple of examples for constructing matrices:
 
 @example
 @{
     symbol a("a"), b("b");
 
     matrix M(2, 2);
-    M(0, 0) = a;
-    M(1, 1) = b;
+    M = a, 0,
+        0, b;
     cout << M << endl;
      // -> [[a,0],[0,b]]
 
+    matrix M2(2, 2);
+    M2(0, 0) = a;
+    M2(1, 1) = b;
+    cout << M2 << endl;
+     // -> [[a,0],[0,b]]
+
     cout << matrix(2, 2, lst(a, 0, 0, b)) << endl;
      // -> [[a,0],[0,b]]
 
@@ -1646,9 +1685,13 @@ and @math{C}:
 
 @example
 @{
-    matrix A(2, 2, lst(1, 2, 3, 4));
-    matrix B(2, 2, lst(-1, 0, 2, 1));
-    matrix C(2, 2, lst(8, 4, 2, 1));
+    matrix A(2, 2), B(2, 2), C(2, 2);
+    A =  1, 2,
+         3, 4;
+    B = -1, 0,
+         2, 1;
+    C =  8, 4,
+         2, 1;
 
     matrix result = A.mul(B).sub(C.mul_scalar(2));
     cout << result << endl;
@@ -2447,7 +2490,10 @@ and scalar products):
     symbol x("x"), y("y");
 
     // A is a 2x2 matrix, X is a 2x1 vector
-    matrix A(2, 2, lst(1, 2, 3, 4)), X(2, 1, lst(x, y));
+    matrix A(2, 2), X(2, 1);
+    A = 1, 2,
+        3, 4;
+    X = x, y;
 
     cout << indexed(A, i, i) << endl;
      // -> 5
@@ -4552,16 +4598,16 @@ GiNaC contains the following predefined mathematical functions:
 @item @code{Order(x)}
 @tab order term function in truncated power series
 @cindex @code{Order()}
-@item @code{Li(n,x)}
+@item @code{Li(n, x)}
 @tab polylogarithm
 @cindex @code{Li()}
-@item @code{S(n,p,x)}
+@item @code{S(n, p, x)}
 @tab Nielsen's generalized polylogarithm
 @cindex @code{S()}
-@item @code{H(m_lst,x)}
+@item @code{H(m_lst, x)}
 @tab harmonic polylogarithm
 @cindex @code{H()}
-@item @code{Li(m_lst,x_lst)}
+@item @code{Li(m_lst, x_lst)}
 @tab multiple polylogarithm
 @cindex @code{Li()}
 @item @code{mZeta(m_lst)}
@@ -4611,12 +4657,11 @@ let us solve the two equations @code{a*x+b*y==3} and @code{x-y==b}:
 @example
 @{
     symbol a("a"), b("b"), x("x"), y("y");
-    lst eqns;
-    eqns.append(a*x+b*y==3).append(x-y==b);
-    lst vars;
-    vars.append(x).append(y);
+    lst eqns, vars;
+    eqns = a*x+b*y==3, x-y==b;
+    vars = x, y;
     cout << lsolve(eqns, vars) << endl;
-    // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
+     // -> @{x==(3+b^2)/(b+a),y==(3-b*a)/(b+a)@}
 @end example
 
 When the linear equations @code{eqns} are underdetermined, the solution
@@ -4959,7 +5004,8 @@ And the stored expressions can be retrieved by their name:
 
 @example
     // ...
-    lst syms(x, y);
+    lst syms;
+    syms = x, y;
 
     ex ex1 = a2.unarchive_ex(syms, "foo");
     ex ex2 = a2.unarchive_ex(syms, "the second one");
index 99d69555c310fd51e651cc1e2a61f0882c5895cf..28f92c133ca4463a3fef508d614779817c071bc9 100644 (file)
@@ -13,12 +13,12 @@ libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp ex.cpp \
 libginac_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
   -release $(LT_RELEASE)
 ginacincludedir = $(includedir)/ginac
-ginacinclude_HEADERS = ginac.h add.h archive.h basic.h constant.h ex.h \
-  expair.h expairseq.h exprseq.h fail.h flags.h function.h hash_map.h \
-  inifcns.h lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h \
-  power.h registrar.h relational.h pseries.h structure.h symbol.h tinfos.h \
-  assertion.h version.h idx.h indexed.h tensor.h color.h clifford.h wildcard.h \
-  print.h symmetry.h fderivative.h
+ginacinclude_HEADERS = ginac.h add.h archive.h basic.h constant.h \
+  container_suppl.h ex.h expair.h expairseq.h exprseq.h fail.h flags.h \
+  function.h hash_map.h inifcns.h lst.h matrix.h mul.h ncmul.h normal.h \
+  numeric.h operators.h power.h registrar.h relational.h pseries.h structure.h \
+  symbol.h tinfos.h assertion.h version.h idx.h indexed.h tensor.h color.h \
+  clifford.h wildcard.h print.h symmetry.h fderivative.h
 LFLAGS = -Pginac_yy -olex.yy.c
 YFLAGS = -p ginac_yy -d
 EXTRA_DIST = container.pl function.pl structure.pl input_parser.h version.h.in
index 9d77d540b5bbe194fc934d992d7d60466960c51e..2a1bcb4216172d4461cb00956698df0e83671bf8 100755 (executable)
@@ -234,6 +234,7 @@ $interface=<<END_OF_INTERFACE;
 
 #include "basic.h"
 #include "ex.h"
+#include "container_suppl.h"
 
 namespace GiNaC {
 
@@ -254,6 +255,15 @@ public:
        ${CONTAINER}(exvector::const_iterator b, exvector::const_iterator e);
 ${constructors_interface}
 
+       // First step of initialization of container with a comma-separated
+       // sequence of expressions. Subsequent steps are handled by
+       // container_init<>::operator,().
+       container_init<ex, ${STLT}> operator=(const ex & x)
+       {
+               this->seq.push_back(x);
+               return container_init<ex, ${STLT}>(seq);
+       }
+
 public:
        void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence(void) const {return 10;}
diff --git a/ginac/container_suppl.h b/ginac/container_suppl.h
new file mode 100644 (file)
index 0000000..79eddbe
--- /dev/null
@@ -0,0 +1,87 @@
+/** @file container_suppl.h
+ *
+ *  Helper classes shared by all containers. */
+
+/*
+ *  GiNaC Copyright (C) 1999-2003 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
+ */
+
+#ifndef __GINAC_CONTAINER_SUPPL_H__
+#define __GINAC_CONTAINER_SUPPL_H__
+
+namespace GiNaC {
+
+/** Helper template to allow initialization of containers via an overloaded
+ *  comma operator (idea stolen from Blitz++). */
+template <typename T, typename STLT>
+class container_init {
+public:
+       container_init(STLT & s) : stlt(s) {}
+
+       container_init<T, STLT> operator,(const T & x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       // The following specializations produce much tighter code than the
+       // general case above
+
+       container_init<T, STLT> operator,(int x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       container_init<T, STLT> operator,(unsigned int x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       container_init<T, STLT> operator,(long x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       container_init<T, STLT> operator,(unsigned long x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       container_init<T, STLT> operator,(double x)
+       {
+               stlt.push_back(x);
+               return container_init<T, STLT>(stlt);
+       }
+
+       container_init<T, STLT> operator,(const symbol & x)
+       {
+               stlt.push_back(T(x));
+               return container_init<T, STLT>(stlt);
+       }
+
+private:
+       container_init();
+       STLT & stlt;
+};
+
+} // namespace GiNaC
+
+#endif // ndef __GINAC_CONTAINER_SUPPL_H__
index 8176f88209c1ad30bf2fdf9e7d938864d6065589..4c7481c44a97f4060a5c66e610364946a94153af 100644 (file)
 
 namespace GiNaC {
 
+
+/** Helper template to allow initialization of matrices via an overloaded
+ *  comma operator (idea stolen from Blitz++). */
+template <typename T, typename It>
+class matrix_init {
+public:
+       matrix_init(It i) : iter(i) {}
+
+       matrix_init<T, It> operator,(const T & x)
+       {
+               *iter = x;
+               return matrix_init<T, It>(++iter);
+       }
+
+       // The following specializations produce much tighter code than the
+       // general case above
+
+       matrix_init<T, It> operator,(int x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+       matrix_init<T, It> operator,(unsigned int x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+       matrix_init<T, It> operator,(long x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+       matrix_init<T, It> operator,(unsigned long x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+       matrix_init<T, It> operator,(double x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+       matrix_init<T, It> operator,(const symbol & x)
+       {
+               *iter = T(x);
+               return matrix_init<T, It>(++iter);
+       }
+
+private:
+       matrix_init();
+       It iter;
+};
+
+
 /** Symbolic matrices. */
 class matrix : public basic
 {
@@ -40,6 +99,14 @@ public:
        matrix(unsigned r, unsigned c);
        matrix(unsigned r, unsigned c, const exvector & m2);
        matrix(unsigned r, unsigned c, const lst & l);
+
+       // First step of initialization of matrix with a comma-separated seqeuence
+       // of expressions. Subsequent steps are handled by matrix_init<>::operator,().
+       matrix_init<ex, exvector::iterator> operator=(const ex & x)
+       {
+               m[0] = x;
+               return matrix_init<ex, exvector::iterator>(++m.begin());
+       }
        
        // functions overriding virtual functions from base classes
 public: