home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / newmat06 / part02 < prev    next >
Encoding:
Text File  |  1992-12-06  |  56.7 KB  |  1,647 lines

  1. Newsgroups: comp.sources.misc
  2. From: robertd@kauri.vuw.ac.nz (Robert Davies)
  3. Subject:  v34i008:  newmat06 - A matrix package in C++, Part02/07
  4. Message-ID: <1992Dec6.045217.3864@sparky.imd.sterling.com>
  5. X-Md4-Signature: 21b07b56422f7a7a111c04e57779191a
  6. Date: Sun, 6 Dec 1992 04:52:17 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: robertd@kauri.vuw.ac.nz (Robert Davies)
  10. Posting-number: Volume 34, Issue 8
  11. Archive-name: newmat06/part02
  12. Environment: C++
  13. Supersedes: newmat04: Volume 26, Issue 87-91
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 7)."
  22. # Contents:  boolean.h controlw.h except.h include.h newmatap.h
  23. #   newmatb.txt newmatio.h newmatrc.h newmatrm.h precisio.h
  24. # Wrapped by robert@kea on Thu Dec  3 22:36:38 1992
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'boolean.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'boolean.h'\"
  28. else
  29. echo shar: Extracting \"'boolean.h'\" \(478 characters\)
  30. sed "s/^X//" >'boolean.h' <<'END_OF_FILE'
  31. X//$$ boolean.h                       Boolean class
  32. X
  33. X#ifndef Boolean_LIB
  34. X#define Boolean_LIB 0
  35. X
  36. Xclass Boolean
  37. X{
  38. X   int value;
  39. Xpublic:
  40. X   Boolean(const int b) { value = b ? 1 : 0; }
  41. X   Boolean(const void* b) { value = b ? 1 : 0; }
  42. X   Boolean() {}
  43. X   operator int() const { return value; }
  44. X   int operator!() const { return !value; }
  45. X   FREE_CHECK(Boolean);
  46. X};
  47. X
  48. X#ifndef GXX
  49. X   const Boolean TRUE = 1;
  50. X   const Boolean FALSE = 0;
  51. X#else
  52. X#define FALSE 0
  53. X#define TRUE 1
  54. X#endif
  55. X
  56. X#endif
  57. END_OF_FILE
  58. if test 478 -ne `wc -c <'boolean.h'`; then
  59.     echo shar: \"'boolean.h'\" unpacked with wrong size!
  60. fi
  61. # end of 'boolean.h'
  62. fi
  63. if test -f 'controlw.h' -a "${1}" != "-c" ; then 
  64.   echo shar: Will not clobber existing file \"'controlw.h'\"
  65. else
  66. echo shar: Extracting \"'controlw.h'\" \(1475 characters\)
  67. sed "s/^X//" >'controlw.h' <<'END_OF_FILE'
  68. X//$$ controlw.h                Control word class
  69. X
  70. X#ifndef CONTROL_WORD_LIB
  71. X#define CONTROL_WORD_LIB 0
  72. X
  73. X// for organising an int as a series of bits which indicate whether an
  74. X// option is on or off.
  75. X
  76. Xclass ControlWord
  77. X{
  78. Xprotected:
  79. X   int cw;                                      // the control word
  80. Xpublic:
  81. X   ControlWord() : cw(0) {}                     // do nothing
  82. X   ControlWord(int i) : cw(i) {}                // load an integer
  83. X
  84. X      // select specific bits (for testing at least one set)
  85. X   ControlWord operator*(const ControlWord& i) const { return cw & i.cw; }
  86. X   void operator*=(const ControlWord& i)  { cw &= i.cw; }
  87. X
  88. X      // set bits
  89. X   ControlWord operator+(const ControlWord& i) const { return cw | i.cw; }
  90. X   void operator+=(const ControlWord& i)  { cw |= i.cw; }
  91. X
  92. X      // reset bits
  93. X   ControlWord operator-(const ControlWord& i) const
  94. X      { return cw - (cw & i.cw); }
  95. X   void operator-=(const ControlWord& i) { cw -= (cw & i.cw); }
  96. X
  97. X      // check if all of selected bits set or reset
  98. X   Boolean operator>=(const ControlWord& i) const { return (cw & i.cw) == i.cw; }
  99. X   Boolean operator<=(const ControlWord& i) const { return (cw & i.cw) == cw; }
  100. X
  101. X      // flip selected bits
  102. X   ControlWord operator^(const ControlWord& i) const { return cw ^ i.cw; }
  103. X   ControlWord operator~() const { return ~cw; }
  104. X
  105. X      // convert to integer
  106. X   int operator+() const { return cw; }
  107. X   int operator!() const { return cw==0; }
  108. X   FREE_CHECK(ControlWord)
  109. X};
  110. X
  111. X
  112. X#endif
  113. END_OF_FILE
  114. if test 1475 -ne `wc -c <'controlw.h'`; then
  115.     echo shar: \"'controlw.h'\" unpacked with wrong size!
  116. fi
  117. # end of 'controlw.h'
  118. fi
  119. if test -f 'except.h' -a "${1}" != "-c" ; then 
  120.   echo shar: Will not clobber existing file \"'except.h'\"
  121. else
  122. echo shar: Extracting \"'except.h'\" \(7378 characters\)
  123. sed "s/^X//" >'except.h' <<'END_OF_FILE'
  124. X//$$ except.h                          Exception handling classes
  125. X
  126. X// A set of classes to simulate exceptions in C++
  127. X//
  128. X//   Partially copied from Carlos Vidal's article in the C users' journal
  129. X//   September 1992, pp 19-28
  130. X//
  131. X//   Operations defined
  132. X//      Try {     }
  133. X//      Throw ( exception object )
  134. X//      Catch ( exception class ) {      }
  135. X//      CatchAll {      }
  136. X//      CatchAndThrow
  137. X//
  138. X//   All catch lists must end with a CatchAll or CatchAndThrow statement
  139. X//   but not both.
  140. X//
  141. X//   When exceptions are finally implemented replace Try, Throw, Catch,
  142. X//   CatchAll, CatchAndThrow by try, throw, catch, catch(...), and {}.
  143. X//
  144. X//   All exception classes must be derived from Exception, have no non-static
  145. X//   variables and must include functions
  146. X//
  147. X//      static long st_type()  { return 2; }
  148. X//      long type() const { return 2; }
  149. X//
  150. X//   where 2 is replaced by a prime number unique to the exception class.
  151. X//   See notes for use with levels of exceptions.
  152. X//
  153. X
  154. X#ifndef EXCEPTION_LIB
  155. X#define EXCEPTION_LIB
  156. X
  157. X#include <setjmp.h>
  158. X
  159. Xvoid Terminate();
  160. X
  161. X/*********** classes for setting up exceptions and reporting ***************/
  162. X
  163. Xclass Exception;
  164. X
  165. Xclass Tracer                                    // linked list showing how
  166. X{                                               // we got here
  167. X   char* entry;
  168. X   Tracer* previous;
  169. Xpublic:
  170. X   Tracer(char*);
  171. X   ~Tracer();
  172. X   void ReName(char*);
  173. X   friend Exception;
  174. X};
  175. X
  176. X
  177. Xclass Exception                                 // The base exception class
  178. X{
  179. Xpublic:
  180. X   static Tracer* last;                         // points to Tracer list
  181. X   static long st_type() { return 1; }
  182. X   virtual long type() const { return 1; }
  183. X   static void PrintTrace(Boolean=FALSE);       // for printing trace
  184. X   friend Tracer;
  185. X   Exception(int action);
  186. X};
  187. X
  188. X
  189. Xinline Tracer::Tracer(char* e)
  190. X   : entry(e), previous(Exception::last) { Exception::last = this; }
  191. X
  192. Xinline Tracer::~Tracer() { Exception::last = previous; }
  193. X
  194. Xinline void Tracer::ReName(char* e) { entry=e; }
  195. X
  196. X
  197. X
  198. X
  199. X
  200. X/************** the definitions of Try, Throw and Catch *******************/
  201. X
  202. X
  203. Xclass JumpItem;
  204. Xclass Janitor;
  205. X
  206. Xclass JumpBase         // pointer to a linked list of jmp_buf s
  207. X{
  208. Xpublic:
  209. X   static JumpItem *jl;
  210. X   static long type;                    // type id. of last exception
  211. X   static jmp_buf env;
  212. X};
  213. X
  214. Xclass JumpItem         // an item in a linked list of jmp_buf s
  215. X{
  216. Xpublic:
  217. X   JumpItem *ji;
  218. X   jmp_buf env;
  219. X   Tracer* trace;                     // to keep check on Tracer items
  220. X   Janitor* janitor;                  // list of items for cleanup
  221. X   JumpItem() : trace(0), janitor(0), ji(JumpBase::jl)
  222. X      { JumpBase::jl = this; }
  223. X   ~JumpItem() { JumpBase::jl = ji; }
  224. X};
  225. X
  226. Xvoid Throw(const Exception& exc);
  227. X
  228. Xvoid Throw();
  229. X
  230. X#define Try                                             \
  231. X      if (!setjmp( JumpBase::jl->env )) {               \
  232. X      JumpBase::jl->trace = Exception::last;            \
  233. X      JumpItem JI387256156;
  234. X
  235. X#define Catch(EXCEPTION)                                \
  236. X   } else if (JumpBase::type % EXCEPTION::st_type() == 0) {
  237. X
  238. X
  239. X#define CatchAll } else
  240. X
  241. X#define CatchAndThrow  } else Throw();
  242. X
  243. X
  244. X
  245. X/******************* cleanup heap following Throw ************************/
  246. X
  247. Xclass Janitor
  248. X{
  249. Xprotected:
  250. X   static Boolean do_not_link;                  // set when new is called
  251. X   Boolean OnStack;                             // false if created by new
  252. Xpublic:
  253. X   Janitor* NextJanitor;
  254. X   virtual void CleanUp() {}
  255. X   Janitor();
  256. X   ~Janitor();
  257. X};
  258. X
  259. X
  260. X
  261. X
  262. X#ifdef DO_FREE_CHECK
  263. X// Routines for tracing whether new and delete calls are balanced
  264. X
  265. Xclass FreeCheck;
  266. X
  267. Xclass FreeCheckLink
  268. X{
  269. Xprotected:
  270. X   FreeCheckLink* next;
  271. X   void* ClassStore;
  272. X   FreeCheckLink();
  273. X   virtual void Report()=0;                   // print details of link
  274. X   friend FreeCheck;
  275. X};
  276. X
  277. Xclass FCLClass : public FreeCheckLink         // for registering objects
  278. X{
  279. X   char* ClassName;
  280. X   FCLClass(void* t, char* name);
  281. X   void Report();
  282. X   friend FreeCheck;
  283. X};
  284. X
  285. Xclass FCLRealArray : public FreeCheckLink     // for registering real arrays
  286. X{
  287. X   char* Operation;
  288. X   int size;
  289. X   FCLRealArray(void* t, char* o, int s);
  290. X   void Report();
  291. X   friend FreeCheck;
  292. X};
  293. X
  294. Xclass FCLIntArray : public FreeCheckLink     // for registering int arrays
  295. X{
  296. X   char* Operation;
  297. X   int size;
  298. X   FCLIntArray(void* t, char* o, int s);
  299. X   void Report();
  300. X   friend FreeCheck;
  301. X};
  302. X
  303. X
  304. Xclass FreeCheck
  305. X{
  306. X   static FreeCheckLink* next;
  307. Xpublic:
  308. X   static void Register(void*, char*);
  309. X   static void DeRegister(void*, char*);
  310. X   static void RegisterR(void*, char*, int);
  311. X   static void DeRegisterR(void*, char*, int);
  312. X   static void RegisterI(void*, char*, int);
  313. X   static void DeRegisterI(void*, char*, int);
  314. X   static void Status();
  315. X   friend FreeCheckLink;
  316. X   friend FCLClass;
  317. X   friend FCLRealArray;
  318. X   friend FCLIntArray;
  319. X};
  320. X
  321. X#define FREE_CHECK(Class)                                                  \
  322. Xpublic:                                                                    \
  323. X   void* operator new(size_t size)                                         \
  324. X   {                                                                       \
  325. X      void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  326. X      return t;                                                            \
  327. X   }                                                                       \
  328. X   void operator delete(void* t)                                           \
  329. X   { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  330. X
  331. X#define NEW_DELETE(Class)                                                  \
  332. Xpublic:                                                                    \
  333. X   void* operator new(size_t size)                                         \
  334. X   {                                                                       \
  335. X      do_not_link=TRUE;                                                    \
  336. X      void* t = ::operator new(size); FreeCheck::Register(t,#Class);       \
  337. X      return t;                                                            \
  338. X   }                                                                       \
  339. X   void operator delete(void* t)                                           \
  340. X   { FreeCheck::DeRegister(t,#Class); ::operator delete(t); }
  341. X
  342. X#define MONITOR_REAL_NEW(Operation, Size, Pointer)                         \
  343. X   FreeCheck::RegisterR(Pointer, Operation, Size);
  344. X#define MONITOR_INT_NEW(Operation, Size, Pointer)                          \
  345. X   FreeCheck::RegisterI(Pointer, Operation, Size);
  346. X#define MONITOR_REAL_DELETE(Operation, Size, Pointer)                      \
  347. X   FreeCheck::DeRegisterR(Pointer, Operation, Size);
  348. X#define MONITOR_INT_DELETE(Operation, Size, Pointer)                       \
  349. X   FreeCheck::DeRegisterI(Pointer, Operation, Size);
  350. X#else
  351. X#define FREE_CHECK(Class) public:
  352. X#define MONITOR_REAL_NEW(Operation, Size, Pointer) {}
  353. X#define MONITOR_INT_NEW(Operation, Size, Pointer) {}
  354. X#define MONITOR_REAL_DELETE(Operation, Size, Pointer) {}
  355. X#define MONITOR_INT_DELETE(Operation, Size, Pointer) {}
  356. X
  357. X
  358. X#define NEW_DELETE(Class)                                                  \
  359. Xpublic:                                                                    \
  360. X   void* operator new(size_t size)                                         \
  361. X   { do_not_link=TRUE; void* t = ::operator new(size); return t; }         \
  362. X   void operator delete(void* t) { ::operator delete(t); }
  363. X
  364. X#endif
  365. X
  366. X
  367. X
  368. X
  369. X#endif
  370. X
  371. X
  372. X
  373. X
  374. END_OF_FILE
  375. if test 7378 -ne `wc -c <'except.h'`; then
  376.     echo shar: \"'except.h'\" unpacked with wrong size!
  377. fi
  378. # end of 'except.h'
  379. fi
  380. if test -f 'include.h' -a "${1}" != "-c" ; then 
  381.   echo shar: Will not clobber existing file \"'include.h'\"
  382. else
  383. echo shar: Extracting \"'include.h'\" \(3020 characters\)
  384. sed "s/^X//" >'include.h' <<'END_OF_FILE'
  385. X//$$ include.h           include files required by various versions of C++
  386. X
  387. X//#define Glock                         // for Glockenspiel on the PC
  388. X//#define ATandT                        // for AT&T C++ on a Sun
  389. X
  390. X#ifdef __GNUG__
  391. X#define GXX                             // for Gnu C++
  392. X#endif
  393. X
  394. X#define TEMPS_DESTROYED_QUICKLY         // for compiler that delete
  395. X                    // temporaries too quickly
  396. X
  397. X//#define DO_FREE_CHECK                   // check news and deletes balance
  398. X
  399. X#define USING_DOUBLE                    // elements of type double
  400. X//#define USING_FLOAT                   // elements of type float
  401. X
  402. X#define Version21                       // version 2.1 or later
  403. X
  404. X
  405. X#ifdef __ZTC__                          // Zortech
  406. X   #include <stdlib.h>
  407. X   #ifdef WANT_STREAM
  408. X      #include <stream.hpp>
  409. X      #define flush ""                  // doesn't have io manipulators
  410. X   #endif
  411. X   #ifdef WANT_MATH
  412. X      #include <math.h>
  413. X      #include <float.h>
  414. X   #endif
  415. X#endif
  416. X
  417. X#ifdef __BCPLUSPLUS__                   // Borland
  418. X   #include <stdlib.h>
  419. X   #ifdef WANT_STREAM
  420. X      #include <iostream.h>
  421. X      #include <iomanip.h>
  422. X   #endif
  423. X   #ifdef WANT_MATH
  424. X      #include <math.h>
  425. X      #define SystemV                   // optional in Borland
  426. X      #include <values.h>               // Borland has both float and values
  427. X   #endif
  428. X   #undef __TURBOC__                    // also defined in Borland
  429. X#endif
  430. X
  431. X#ifdef __TURBOC__                       // Turbo
  432. X   #include <stdlib.h>
  433. X   #ifdef WANT_STREAM
  434. X      #include <iostream.h>
  435. X      #include <iomanip.h>
  436. X   #endif
  437. X   #ifdef WANT_MATH
  438. X      #include <math.h>
  439. X      #define SystemV                   // optional in Turbo
  440. X      #include <values.h>
  441. X   #endif
  442. X#endif
  443. X
  444. X#ifdef ATandT                           // AT&T
  445. X#include <stdlib.h>
  446. X#ifdef WANT_STREAM
  447. X#include <iostream.h>
  448. X#include <iomanip.h>
  449. X#endif
  450. X#ifdef WANT_MATH
  451. X#include <math.h>
  452. X#define SystemV                         // must use System V on my Sun
  453. X#include <values.h>                     //    as float.h is not present
  454. X#endif
  455. X#endif
  456. X
  457. X#ifdef GXX                              // Gnu C++
  458. X   #include <stdlib.h>
  459. X   #ifdef WANT_STREAM
  460. X      #include <stream.h>               // no iomanip in G++
  461. X      #define flush ""
  462. X   #endif
  463. X   #ifdef WANT_MATH
  464. X      #include <math.h>
  465. X      #include <float.h>
  466. X   #endif
  467. X   #ifndef TEMPS_DESTROYED_QUICKLY
  468. X      #define TEMPS_DESTROYED_QUICKLY
  469. X   #endif
  470. X#endif
  471. X
  472. X#ifdef Glock                            // Glockenspiel
  473. X   extern "C" { #include <stdlib.h> }
  474. X   #ifdef WANT_STREAM
  475. X      #include <stream.hxx>
  476. X      #include <iomanip.hxx>
  477. X   #endif
  478. X   #ifdef WANT_MATH
  479. X      extern "C" { #include <math.h> }
  480. X      extern "C" { #include <float.h> }
  481. X   #endif
  482. X   #define NO_LONG_NAMES                // very long names don't work
  483. X#endif
  484. X
  485. X
  486. X
  487. X#ifdef USING_FLOAT                      // set precision type to float
  488. Xtypedef float Real;
  489. Xtypedef double long_Real;
  490. X#endif
  491. X
  492. X#ifdef USING_DOUBLE                     // set precision type to double
  493. Xtypedef double Real;
  494. Xtypedef long double long_Real;
  495. X#endif
  496. X
  497. X
  498. END_OF_FILE
  499. if test 3020 -ne `wc -c <'include.h'`; then
  500.     echo shar: \"'include.h'\" unpacked with wrong size!
  501. fi
  502. # end of 'include.h'
  503. fi
  504. if test -f 'newmatap.h' -a "${1}" != "-c" ; then 
  505.   echo shar: Will not clobber existing file \"'newmatap.h'\"
  506. else
  507. echo shar: Extracting \"'newmatap.h'\" \(2631 characters\)
  508. sed "s/^X//" >'newmatap.h' <<'END_OF_FILE'
  509. X//$$ newmatap.h           definition file for matrix package applications
  510. X
  511. X// Copyright (C) 1991,2: R B Davies
  512. X
  513. X#ifndef MATRIXAP_LIB
  514. X#define MATRIXAP_LIB 0
  515. X
  516. X#include "newmat.h"
  517. X
  518. X
  519. X/**************************** applications *****************************/
  520. X
  521. X
  522. Xvoid HHDecompose(Matrix&, LowerTriangularMatrix&);
  523. X
  524. Xvoid HHDecompose(const Matrix&, Matrix&, Matrix&);
  525. X
  526. XReturnMatrix Cholesky(const SymmetricMatrix&);
  527. X
  528. XReturnMatrix Cholesky(const SymmetricBandMatrix&);
  529. X
  530. X#ifndef GXX
  531. Xvoid SVD(const Matrix&, DiagonalMatrix&, Matrix&, Matrix&,
  532. X    Boolean=TRUE, Boolean=TRUE);
  533. X#else
  534. Xvoid SVD(const Matrix&, DiagonalMatrix&, Matrix&, Matrix&,
  535. X    Boolean=(Boolean)TRUE, Boolean=(Boolean)TRUE);
  536. X#endif
  537. X
  538. X
  539. Xvoid SVD(const Matrix&, DiagonalMatrix&);
  540. X
  541. X#ifndef GXX
  542. Xinline void SVD(const Matrix& A, DiagonalMatrix& D, Matrix& U,
  543. X   Boolean withU = TRUE) { SVD(A, D, U, U, withU, FALSE); }
  544. X#else
  545. Xinline void SVD(const Matrix& A, DiagonalMatrix& D, Matrix& U,
  546. X   Boolean withU = (Boolean)TRUE) { SVD(A, D, U, U, withU, FALSE); }
  547. X#endif
  548. X
  549. Xvoid Jacobi(const SymmetricMatrix&, DiagonalMatrix&);
  550. X
  551. Xvoid Jacobi(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&);
  552. X
  553. Xvoid Jacobi(const SymmetricMatrix&, DiagonalMatrix&, Matrix&);
  554. X
  555. X#ifndef GXX
  556. Xvoid Jacobi(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&,
  557. X   Matrix&, Boolean=TRUE);
  558. X#else
  559. Xvoid Jacobi(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&,
  560. X   Matrix&, Boolean=(Boolean)TRUE);
  561. X#endif
  562. X
  563. Xvoid EigenValues(const SymmetricMatrix&, DiagonalMatrix&);
  564. X
  565. Xvoid EigenValues(const SymmetricMatrix&, DiagonalMatrix&, SymmetricMatrix&);
  566. X
  567. Xvoid EigenValues(const SymmetricMatrix&, DiagonalMatrix&, Matrix&);
  568. X
  569. Xclass SymmetricEigenAnalysis
  570. X// not implemented yet
  571. X{
  572. Xpublic:
  573. X   SymmetricEigenAnalysis(const SymmetricMatrix&);
  574. Xprivate:
  575. X   DiagonalMatrix diag;
  576. X   DiagonalMatrix offdiag;
  577. X   SymmetricMatrix backtransform;
  578. X   FREE_CHECK(SymmetricEigenAnalysis)
  579. X};
  580. X
  581. Xvoid SortAscending(GeneralMatrix&);
  582. X
  583. Xvoid SortDescending(GeneralMatrix&);
  584. X
  585. X
  586. Xvoid FFT(const ColumnVector&, const ColumnVector&,
  587. X   ColumnVector&, ColumnVector&);
  588. X
  589. X
  590. X/********************** linear equation solving ****************************/
  591. X
  592. Xclass LinearEquationSolver : public BaseMatrix
  593. X{
  594. X   GeneralMatrix* gm;
  595. X   int search(const BaseMatrix*) const { return 0; }
  596. X   MatrixType Type() const { return gm->Type(); }
  597. X   friend BaseMatrix;
  598. Xpublic:
  599. X   LinearEquationSolver(const BaseMatrix& bm);
  600. X   ~LinearEquationSolver() { delete gm; }
  601. X   void CleanUp() { delete gm; } 
  602. X   GeneralMatrix* Evaluate(MatrixType) { return gm; }
  603. X   // probably should have an error message if MatrixType != UnSp
  604. X   NEW_DELETE(LinearEquationSolver)
  605. X};
  606. X
  607. X
  608. X
  609. X
  610. X
  611. X#endif
  612. END_OF_FILE
  613. if test 2631 -ne `wc -c <'newmatap.h'`; then
  614.     echo shar: \"'newmatap.h'\" unpacked with wrong size!
  615. fi
  616. # end of 'newmatap.h'
  617. fi
  618. if test -f 'newmatb.txt' -a "${1}" != "-c" ; then 
  619.   echo shar: Will not clobber existing file \"'newmatb.txt'\"
  620. else
  621. echo shar: Extracting \"'newmatb.txt'\" \(24232 characters\)
  622. sed "s/^X//" >'newmatb.txt' <<'END_OF_FILE'
  623. X//$$ newmatb.txt                                   Design
  624. X
  625. X
  626. XCopyright (C) 1991,2: R B Davies
  627. X
  628. XPlease treat this as an academic publication. You can use the ideas but
  629. Xplease acknowledge in any publication.
  630. X
  631. X
  632. X
  633. X                      Notes on the design of the package
  634. X                      ==================================
  635. X
  636. XContents
  637. X========
  638. X
  639. XWhat this is package for
  640. XWhat size of matrices?
  641. XAllow matrix expressions?
  642. XWhich matrix types?
  643. XWhat element types?
  644. XNaming convention
  645. XRow and Column index ranges
  646. XStructure of matrix objects
  647. XData storage - one block or several
  648. XData storage - by row or by column or other
  649. XStorage of symmetric matrices
  650. XElement access - method and checking
  651. XUse iterators?
  652. XMemory management - reference counting or status variable?
  653. XEvaluation of expressions - use two stage method?
  654. XHow to overcome an explosion in number of operations
  655. XDestruction of temporaries
  656. XA calculus of matrix types
  657. XError handling
  658. XSparse matrices
  659. XComplex matrices
  660. X
  661. X
  662. XI describe some of the ideas behind this package, some of the decisions
  663. Xthat I needed to make and give some details about the way it works. You
  664. Xdon't need to read this file in order to use the package.
  665. X
  666. XI don't think it is obvious what is the best way of going about
  667. Xstructuring a matrix package. And I don't think you can figure this
  668. Xout with "thought" experiments. Different people have to try out
  669. Xdifferent approaches. And someone else may have to figure out which is
  670. Xbest. Or, more likely, the ultimate packages will lift some ideas from
  671. Xeach of a variety of trial packages. So, I don't claim my package is an
  672. X"ultimate" package, but simply a trial of a number of ideas.
  673. X
  674. XBut I do hope it will meet the immediate requirements of some people who
  675. Xneed to carry out matrix calculations.
  676. X
  677. X
  678. XWhat this is package for
  679. X------------------------
  680. X
  681. XThe package is used for the manipulation of matrices, including the
  682. Xstandard operations such as multiplication as understood by numerical
  683. Xanalysts, engineers and mathematicians. A matrix is a two dimensional
  684. Xarray of numbers. However, very special operations such as matrix
  685. Xmultiplication are defined specifically for matrices. This means that a
  686. X"matrix" package tends to be different from a general "array" package.
  687. X
  688. XI see a matrix package as providing the following
  689. X
  690. X1.   Evaluation of matrix expressions in a form familiar to
  691. X     scientists and engineers. For example  A = B * (C + D.t());
  692. X2.   Access to the elements of a matrix;
  693. X3.   Access to submatrices;
  694. X4.   Common elementary matrix functions such as determinant and trace;
  695. X5.   A platform for developing advanced matrix functions such as eigen-
  696. X     value analysis;
  697. X6.   Good efficiency and storage management;
  698. X7.   Graceful exit from errors (I don't provide this yet).
  699. X
  700. XIt may also provide
  701. X
  702. X8.   A variety of types of elements (eg real and complex);
  703. X9.   A variety of types of matrices (eg rectangular and symmetric).
  704. X
  705. XIn contrast an array package should provide
  706. X
  707. X1'.  Arrays can be copied with a single instruction; may have some
  708. X     arithmetic operations, say + - and scalar + - * /, it may provide
  709. X     matrix multiplication as a function;
  710. X2'.  High speed access to elements directly and with iterators;
  711. X3'.  Access to subarrays and rows (and columns?);
  712. X6'.  Good efficiency and storage management;
  713. X7'.  Graceful exit from errors;
  714. X8'.  A variety of types of elements (eg real and complex);
  715. X9'.  One, two and three dimensional arrays, at least, with starting
  716. X     points of the indices set by user; may have arrays with ragged
  717. X     rows.
  718. X
  719. XIt may be possible to amalgamate these two sets of requirements to some
  720. Xextent. However my package is definitely oriented towards the first set.
  721. X
  722. XEven within the bounds set by the first set of requirements there is a
  723. Xsubstantial opportunity for variation between what different matrix
  724. Xpackages might provide.
  725. X
  726. XIt is not possible to build a matrix package that will meet everyone's
  727. Xrequirements. In many cases if you put in one facility, you impose
  728. Xoverheads on everyone using the package. This both is storage required
  729. Xfor the program and in efficiency. Likewise a package that is optimised
  730. Xtowards handling large matrices is likely to become less efficient for
  731. Xvery small matrices where the administration time for the matrix may
  732. Xbecome significant compared with the time to carry out the operations.
  733. X
  734. XIt is better to provide a variety of packages (hopefully compatible) so
  735. Xthat most users can find one that meets their requirements. This package
  736. Xis intended to be one of these packages; but not all of them.
  737. X
  738. XSince my background is in statistical methods, this package is oriented
  739. Xtowards the kinds things you need for statistical analyses.
  740. X
  741. X
  742. XWhat size of matrices?
  743. X----------------------
  744. X
  745. XA matrix package may target small matrices (say 3 x 3), or medium sized
  746. Xmatrices, or very large matrices. A package targeting very small
  747. Xmatrices will seek to minimise administration. A package for medium
  748. Xsized or very large matrices can spend more time on administration in
  749. Xorder to conserve space or optimise the evaluation of expressions. A
  750. Xpackage for very large matrices will need to pay special attention to
  751. Xstorage and numerical properties.
  752. X
  753. XThis package is designed for medium sized matrices. This means it is
  754. Xworth introducing some optimisations, but I don't have to worry about
  755. Xthe 64K limit that some compilers impose.
  756. X
  757. X
  758. XAllow matrix expressions?
  759. X-------------------------
  760. X
  761. XI want to be able to write matrix expressions the way I would on paper.
  762. XSo if I want to multiply two matrices and then add the transpose of a
  763. Xthird one I can write something like
  764. X
  765. X   X = A * B + C.t();
  766. X
  767. XI want this expression to be evaluated with close to the same efficiency
  768. Xas a hand-coded version. This is not so much of a problem with
  769. Xexpressions including a multiply since the multiply will dominate the
  770. Xtime. However, it is not so easy to achieve with expressions with just +
  771. Xand - .
  772. X
  773. XA second requirement is that temporary matrices generated during the
  774. Xevaluation of an expression are destroyed as quickly as possible.
  775. X
  776. XA desirable feature is that a certain amount of "intelligence" be
  777. Xdisplayed in the evaluation of an expression. For example, in the
  778. Xexpression
  779. X
  780. X   X = A.i() * B;
  781. X
  782. Xwhere i() denotes inverse, it would be desirable if the inverse wasn't
  783. Xexplicitly calculated.
  784. X
  785. X
  786. XWhich matrix types?
  787. X-------------------
  788. X
  789. XAs well as the usual rectangular matrices, matrices occuring repeatedly
  790. Xin numerical calculations are upper and lower triangular matrices,
  791. Xsymmetric matrices and diagonal matrices. This is particularly the case
  792. Xin calculations involving least squares and eigenvalue calculations. So
  793. Xas a first stage these were the types I decided to include.
  794. X
  795. XIt is also necessary to have types row vector and column vector. In a
  796. X"matrix" package, in contrast to an "array" package, it is necessary to
  797. Xhave both these types since they behave differently in matrix
  798. Xexpressions. The vector types can be derived for the rectangular matrix
  799. Xtype, so having them does not greatly increase the complexity of the
  800. Xpackage.
  801. X
  802. XThe problem with having several matrix types is the number of versions
  803. Xof the binary operators one needs. If one has 5 distinct matrix types
  804. Xthen a simple package will need 25 versions of each of the binary
  805. Xoperators. In fact, we can evade this problem, but at the cost of some
  806. Xcomplexity.
  807. X
  808. X
  809. XWhat element types?
  810. X-------------------
  811. X
  812. XIdeally we would allow element types double, float, complex and int, at
  813. Xleast. It would be reasonably easy, using templates or equivalent, to
  814. Xprovide a package which could handle a variety of element types.
  815. XHowever, as soon as one starts implementing the binary operators between
  816. Xmatrices with different element types, again one gets an explosion in
  817. Xthe number of operations one needs to consider. Hence I decided to
  818. Ximplement only one element type. But the user can decide whether this is
  819. Xfloat or double. The package assumes elements are of type Real. The user
  820. Xtypedefs Real to float or double.
  821. X
  822. XIn retrospect, it would not be too hard to include matrices with complex
  823. Xmatrix type.
  824. X
  825. XIt might also be worth including symmetric and triangular matrices with
  826. Xextra precision elements (double or long double) to be used for storage
  827. Xonly and with a minimum of operations defined. These would be used for
  828. Xaccumulating the results of sums of squares and product matrices or
  829. Xmultistage Householder triangularisations.
  830. X
  831. X
  832. XNaming convention
  833. X-----------------
  834. X
  835. XHow are classes and public member functions to be named? As a general
  836. Xrule I have spelt identifiers out in full with individual words being
  837. Xcapitalised. For example "UpperTriangularMatrix". If you don't like this
  838. Xyou can #define or typedef shorter names. This convention means you can
  839. Xselect an abbreviation scheme that makes sense to you.
  840. X
  841. XThe convention causes problems for Glockenspiel C++ on a PC feeding into
  842. XMicrosoft C. The names Glockenspiel generates exceed the the 32
  843. Xcharacters recognised by Microsoft C and ambiguities result. So it is
  844. Xnecessary to #define shorter names.
  845. X
  846. XExceptions to the general rule are the functions for transpose and
  847. Xinverse. To make matrix expressions more like the corresponding
  848. Xmathematical formulae, I have used the single letter abbreviations, t()
  849. Xand i() .
  850. X
  851. X
  852. XRow and Column index ranges
  853. X---------------------------
  854. X
  855. XIn mathematical work matrix subscripts usually start at one. In C, array
  856. Xsubscripts start at zero. In Fortran, they start at one. Possibilities
  857. Xfor this package were to make them start at 0 or 1 or be arbitrary.
  858. XAlternatively one could specify an "index set" for indexing the rows and
  859. Xcolumns of a matrix. One would be able to add or multiply matrices only
  860. Xif the appropriate row and column index sets were identical.
  861. X
  862. XIn fact, I adopted the simpler convention of making the rows and columns
  863. Xof a matrix be indexed by an integer starting at one, following the
  864. Xtraditional convention. In an earlier version of the package I had them
  865. Xstarting at zero, but even I was getting mixed up when trying to use
  866. Xthis earlier package. So I reverted to the more usual notation.
  867. X
  868. X
  869. XStructure of matrix objects
  870. X---------------------------
  871. X
  872. XEach matrix object contains the basic information such as the number of
  873. Xrows and columns and a status variable plus a pointer to the data
  874. Xarray which is on the heap.
  875. X
  876. X
  877. XData storage - one block or several
  878. X-----------------------------------
  879. X
  880. XIn this package the elements of the matrix are stored as a single array.
  881. XAlternatives would have been to store each row as a separate array or a
  882. Xset of adjacent rows as a separate array. The present solution
  883. Xsimplifies the program but limits the size of matrices in systems that
  884. Xhave a 64k byte (or other) limit on the size of arrays. The large arrays
  885. Xmay also cause problems for memory management in smaller machines.
  886. X
  887. X
  888. XData storage - by row or by column or other
  889. X-------------------------------------------
  890. X
  891. XIn Fortran two dimensional arrays are stored by column. In most other
  892. Xsystems they are stored by row. I have followed this later convention.
  893. XThis makes it easier to interface with other packages written in C but
  894. Xharder to interface with those written in Fortran.
  895. X
  896. XAn alternative would be to store the elements by mid-sized rectangular
  897. Xblocks. This might impose less strain on memory management when one
  898. Xneeds to access both rows and columns.
  899. X
  900. X
  901. XStorage of symmetric matrices
  902. X-----------------------------
  903. X
  904. XSymmetric matrices are stored as lower triangular matrices. The decision
  905. Xwas pretty arbitrary, but it does slightly simplify the Cholesky
  906. Xdecomposition program.
  907. X
  908. X
  909. XElement access - method and checking
  910. X------------------------------------
  911. X
  912. XWe want to be able to use the notation A(i,j) to specify the (i,j)-th
  913. Xelement of a matrix. This is the way mathematicians expect to address
  914. Xthe elements of matrices. I consider the notation A[i][j] totally alien.
  915. XHowever I may include it in a later version to help people converting
  916. Xfrom C. There are two ways of working out the address of A(i,j). One is
  917. Xusing a "dope" vector which contains the first address of each row.
  918. XAlternatively you can calculate the address using the formula
  919. Xappropriate for the structure of A. I use this second approach. It is
  920. Xprobably slower, but saves worrying about an extra bit of storage. The
  921. Xother question is whether to check for i and j being in range. I do
  922. Xcarry out this check following years of experience with both systems
  923. Xthat do and systems that don't do this check.
  924. X
  925. XI would hope that the routines I supply with this package will reduce
  926. Xyour need to access elements of matrices so speed of access is not a
  927. Xhigh priority.
  928. X
  929. X
  930. XUse iterators?
  931. X--------------
  932. X
  933. XIterators are an alternative way of providing fast access to the
  934. Xelements of an array or matrix when they are to be accessed
  935. Xsequentially. They need to be customised for each type of matrix. I have
  936. Xnot implemented iterators in this package, although some iterator like
  937. Xfunctions are used for some row and column functions.
  938. X
  939. X
  940. XMemory management - reference counting or status variable?
  941. X----------------------------------------------------------
  942. X
  943. XConsider the instruction
  944. X
  945. X   X = A + B + C;
  946. X
  947. XTo evaluate this a simple program will add A to B putting the total in a
  948. Xtemporary T1. Then it will add T1 to C creating another temporary T2
  949. Xwhich will be copied into X. T1 and T2 will sit around till the end of
  950. Xthe block. It would be faster if the program recognised that T1 was
  951. Xtemporary and stored the sum of T1 and C back into T1 instead of
  952. Xcreating T2 and then avoided the final copy by just assigning the
  953. Xcontents of T1 to X rather than copying. In this case there will be no
  954. Xtemporaries requiring deletion. (More precisely there will be a header
  955. Xto be deleted but no contents).
  956. X
  957. XFor an instruction like
  958. X
  959. X   X = (A * B) + (C * D);
  960. X
  961. Xwe can't easily avoid one temporary being left over, so we would like
  962. Xthis temporary deleted as quickly as possible.
  963. X
  964. XI provide the functionality for doing this by attaching a status
  965. Xvariable to each matrix. This indicates if the matrix is temporary so
  966. Xthat its memory is available for recycling or deleting. Any matrix
  967. Xoperation checks the status variables of the matrices it is working with
  968. Xand recycles or deletes any temporary memory.
  969. X
  970. XAn alternative or additional approach would be to use delayed copying.
  971. XIf a program requests a matrix to be copied, the copy is delayed until
  972. Xan instruction is executed which modifies the memory of either the
  973. Xoriginal matrix or the copy. This saves the unnecessary copying in the
  974. Xprevious examples. However, it does not provide the additional
  975. Xfunctionality of my approach.
  976. X
  977. XIt would be possible to have both delayed copy and tagging temporaries,
  978. Xbut this seemed an unnecessary complexity. In particular delayed copy
  979. Xmechanisms seem to require two calls to the heap manager, using extra
  980. Xtime and making building a memory compacting mechanism more difficult.
  981. X
  982. X
  983. XEvaluation of expressions - use two stage method?
  984. X-------------------------------------------------
  985. X
  986. XConsider the instruction
  987. X
  988. X   X = B - X;
  989. X
  990. XThe simple program will subtract X from B, store the result in a
  991. Xtemporary T1 and copy T1 into X. It would be faster if the program
  992. Xrecognised that the result could be stored directly into X. This would
  993. Xhappen automatically if the program could look at the instruction first
  994. Xand mark X as temporary.
  995. X
  996. XC programmers would expect to avoid the same problem with
  997. X
  998. X   X = X - B;
  999. X
  1000. Xby using an operator -= (which I haven't provided, yet)
  1001. X
  1002. X   X -= B;
  1003. X
  1004. XHowever this is an unnatural notation for non C users and it is much
  1005. Xnicer to write
  1006. X
  1007. X   X = X - B;
  1008. X
  1009. Xand know that the program will carry out the simplification.
  1010. X
  1011. XAnother example where this intelligent analysis of an instruction is
  1012. Xhelpful is in
  1013. X
  1014. X   X = A.i() * B;
  1015. X
  1016. Xwhere i() denotes inverse. Numerical analysts know it is inefficient to
  1017. Xevaluate this expression by carrying out the inverse operation and then
  1018. Xthe multiply. Yet it is a convenient way of writing the instruction. It
  1019. Xwould be helpful if the program recognised this expression and carried
  1020. Xout the more appropriate approach.
  1021. X
  1022. XTo carry out this "intelligent" analysis of an instruction  matrix
  1023. Xexpressions are evaluated in two stages. In the the first stage a tree
  1024. Xrepresentation of the expression is formed.
  1025. X
  1026. XFor example (A+B)*C is represented by a tree
  1027. X
  1028. X                    *
  1029. X                   / \
  1030. X                  +   C
  1031. X                 / \
  1032. X                A   B
  1033. X
  1034. XRather than adding A and B the + operator yields an object of a class
  1035. X"AddedMatrix" which is just a pair of pointers to A and B. Then the *
  1036. Xoperator yields a "MultipliedMatrix" which is a pair of pointers to the
  1037. X"AddedMatrix" and C. The tree is examined for any simplifications and
  1038. Xthen evaluated recursively.
  1039. X
  1040. XFurther possibilities not yet included are to recognise A.t()*A and
  1041. XA.t()+A as symmetric or to improve the efficiency of evaluation of
  1042. Xexpressions like A+B+C, A*B*C, A*B.t()  [t() denotes transpose].
  1043. X
  1044. XOne of the disadvantages of the two-stage approach is that the types of
  1045. Xmatrix expressions are determined at run-time. So the compiler will not
  1046. Xdetect errors of the type
  1047. X
  1048. X   Matrix M; DiagonalMatrix D; ....; D = M;
  1049. X
  1050. XWe don't allow conversions using = when information would be lost. Such
  1051. Xerrors will be detected when the statement is executed.
  1052. X
  1053. X
  1054. XHow to overcome an explosion in number of operations
  1055. X----------------------------------------------------
  1056. X
  1057. XThe package attempts to solve the problem of the large number of
  1058. Xversions of the binary operations required when one has a variety of
  1059. Xtypes. With n types of matrices the binary operations will each require
  1060. Xn-squared separate algorithms. Some reduction in the number may be
  1061. Xpossible by carrying out conversions. However the situation rapidly
  1062. Xbecomes impossible with more than 4 or 5 types.
  1063. X
  1064. XDoug Lea told me that it was possible to avoid this problem. I don't
  1065. Xknow what his solution is. Here's mine.
  1066. X
  1067. XEach matrix type includes routines for extracting individual rows or
  1068. Xcolumns. I assume a row or column consists of a sequence of zeros, a
  1069. Xsequence of stored values and then another sequence of zeros. Only a
  1070. Xsingle algorithm is then required for each binary operation. The rows
  1071. Xcan be located very quickly since most of the matrices are stored row by
  1072. Xrow. Columns must be copied and so the access is somewhat slower. As far
  1073. Xas possible my algorithms access the matrices by row.
  1074. X
  1075. XAn alternative approach of using iterators will be slower since the
  1076. Xiterators will involve a virtual function access at each step.
  1077. X
  1078. XThere is another approach. Each of the matrix types defined in this
  1079. Xpackage can be set up so both rows and columns have their elements at
  1080. Xequal intervals provided we are prepared to store the rows and columns
  1081. Xin up to three chunks. With such an approach one could write a single
  1082. X"generic" algorithm for each of multiply and add. This would be a
  1083. Xreasonable alternative to my approach.
  1084. X
  1085. XI provide several algorithms for operations like + . If one is adding
  1086. Xtwo matrices of the same type then there is no need to access the
  1087. Xindividual rows or columns and a faster general algorithm is
  1088. Xappropriate.
  1089. X
  1090. XGenerally the method works well. However symmetric matrices are not
  1091. Xalways handled very efficiently (yet) since complete rows are not stored
  1092. Xexplicitly.
  1093. X
  1094. XThe original version of the package did not use this access by row or
  1095. Xcolumn method and provided the multitude of algorithms for the
  1096. Xcombination of different matrix types. The code file length turned out
  1097. Xto be just a little longer than the present one when providing the same
  1098. Xfacilities with 5 distinct types of matrices. It would have been very
  1099. Xdifficult to increase the number of matrix types in the original
  1100. Xversion. Apparently 4 to 5 types is about the break even point for
  1101. Xswitching to the approach adopted in the present package.
  1102. X
  1103. X
  1104. XDestruction of temporaries
  1105. X--------------------------
  1106. X
  1107. XVersions before version 5 of newmat did not work correctly with Gnu C++.
  1108. XThis was because the tree structure used to represent a matrix
  1109. Xexpression was set up on the stack. This was fine for AT&T, Borland and
  1110. XZortech C++. However Gnu C++ destroys temporary structures as soon as
  1111. Xthe function that accesses them finishes. The other compilers wait until
  1112. Xthe end of the current block. (It would be good enough for them to wait
  1113. Xtill the end of the expression.) To overcome this problem, there is now
  1114. Xan option to store the temporaries forming the tree structure on the
  1115. Xheap (created with new) and to delete them explicitly. Activate the
  1116. Xdefinition of TEMPS_DESTROYED_QUICKLY to set this option. In fact, I
  1117. Xsuggest this be the default option as, with it, the package uses less
  1118. Xstorage and runs faster.
  1119. X
  1120. XThere still exist situations Gnu C++ will go wrong. These include
  1121. Xstatements like
  1122. X
  1123. XA = X * Matrix(P * Q); Real r = (A*B)(3,4);
  1124. X
  1125. XNeither of these kinds of statements will occur often in practice.
  1126. X
  1127. X
  1128. XA calculus of matrix types
  1129. X--------------------------
  1130. X
  1131. XThe program needs to be able to work out the class of the result of a
  1132. Xmatrix expression. This is to check that a conversion is legal or to
  1133. Xdetermine the class of a temporary. To assist with this, a class
  1134. XMatrixType is defined. Operators +, -, *, >= are defined to calculate
  1135. Xthe types of the results of expressions or to check that conversions are
  1136. Xlegal.
  1137. X
  1138. X
  1139. XError handling
  1140. X--------------
  1141. X
  1142. XThe package now does have a moderately graceful exit from errors.
  1143. XOriginally I thought I would wait until exceptions became available in
  1144. XC++. Trying to set up an error handling scheme that did not involve an
  1145. Xexception-like facility was just too complicated. Version 5 of this
  1146. Xpackage included the beginnings of such a facility. The approach in the
  1147. Xpresent package, attempting to implement C++ exceptions, is not
  1148. Xcompletely satisfactory, but seems a good interim solution.
  1149. X
  1150. XThe exception mechanism cannot clean-up objects explicitly created by
  1151. Xnew. This must be explicitly carried out by the package writer or the
  1152. Xpackage user. I have not yet done this with the present package so
  1153. Xoccasionally a little garbage may be left behind after an exception. I
  1154. Xdon't think this is a big problem, but it is one that needs fixing.
  1155. X
  1156. XI identify five categories of errors:
  1157. X
  1158. X   Programming error - eg illegal conversion of a matrix, subscript out
  1159. X   of bounds, matrix dimensions don't match;
  1160. X
  1161. X   Illegal data error - eg Cholesky of a non-positive definite matrix;
  1162. X
  1163. X   Out of space error - "new" returns a null pointer;
  1164. X
  1165. X   Convergence failure - an iterative operation fails to converge;
  1166. X
  1167. X   Internal error - failure of an internal check.
  1168. X
  1169. XSome of these have subcategories, which are nicely represented by
  1170. Xderived exception classes. But I don't think it is a good idea for
  1171. Xpackage users to refer to these as they may change in the next release
  1172. Xof the package.
  1173. X
  1174. X
  1175. XSparse matrices
  1176. X---------------
  1177. X
  1178. XThe package does not yet support sparse matrices.
  1179. X
  1180. XFor sparse matrices there is going to be some kind of structure vector.
  1181. XIt is going to have to be calculated for the results of expressions in
  1182. Xmuch the same way that types are calculated. In addition, a whole new
  1183. Xset of row and column operations would have to be written.
  1184. X
  1185. XSparse matrices are important for people solving large sets of
  1186. Xdifferential equations as well as being important for statistical and
  1187. Xoperational research applications. I think comprehensive matrix package
  1188. Xneeds to implement sparse matrices.
  1189. X
  1190. X
  1191. XComplex matrices
  1192. X----------------
  1193. X
  1194. XThe package does not yet support matrices with complex elements. There
  1195. Xare at least two approaches to including these. One is to have matrices
  1196. Xwith complex elements. This probably means making new versions of the
  1197. Xbasic row and column operations for Real*Complex, Complex*Complex,
  1198. XComplex*Real and similarly for + and -. This would be OK, except that I
  1199. Xam also going to have to also do this for sparse and when you put these
  1200. Xtogether, the whole thing will get out of hand.
  1201. X
  1202. XThe alternative is to represent a Complex matrix by a pair of Real
  1203. Xmatrices. One probably needs another level of decoding expressions but I
  1204. Xthink it might still be simpler than the first approach. There is going
  1205. Xto be a problem with accessing elements and the final package may be a
  1206. Xlittle less efficient that one using the previous representation.
  1207. XNeverthless, this is the approach I favour.
  1208. X
  1209. XComplex matrices are used extensively by electrical engineers and really
  1210. Xshould be fully supported in a comprehensive package.
  1211. END_OF_FILE
  1212. if test 24232 -ne `wc -c <'newmatb.txt'`; then
  1213.     echo shar: \"'newmatb.txt'\" unpacked with wrong size!
  1214. fi
  1215. # end of 'newmatb.txt'
  1216. fi
  1217. if test -f 'newmatio.h' -a "${1}" != "-c" ; then 
  1218.   echo shar: Will not clobber existing file \"'newmatio.h'\"
  1219. else
  1220. echo shar: Extracting \"'newmatio.h'\" \(366 characters\)
  1221. sed "s/^X//" >'newmatio.h' <<'END_OF_FILE'
  1222. X//$$ newmatio.h           definition file for matrix package input/output
  1223. X
  1224. X// Copyright (C) 1991,2: R B Davies
  1225. X
  1226. X#ifndef MATRIXIO_LIB
  1227. X#define MATRIXIO_LIB 0
  1228. X
  1229. X#include "newmat.h"
  1230. X
  1231. X/**************************** input/output *****************************/
  1232. X
  1233. Xostream& operator<<(ostream&, const BaseMatrix&);
  1234. X
  1235. Xostream& operator<<(ostream&, const GeneralMatrix&);
  1236. X
  1237. X
  1238. X#endif
  1239. END_OF_FILE
  1240. if test 366 -ne `wc -c <'newmatio.h'`; then
  1241.     echo shar: \"'newmatio.h'\" unpacked with wrong size!
  1242. fi
  1243. # end of 'newmatio.h'
  1244. fi
  1245. if test -f 'newmatrc.h' -a "${1}" != "-c" ; then 
  1246.   echo shar: Will not clobber existing file \"'newmatrc.h'\"
  1247. else
  1248. echo shar: Extracting \"'newmatrc.h'\" \(4899 characters\)
  1249. sed "s/^X//" >'newmatrc.h' <<'END_OF_FILE'
  1250. X//$$ newmatrc.h              definition file for row/column classes
  1251. X
  1252. X// Copyright (C) 1991,2: R B Davies
  1253. X
  1254. X#ifndef MATRIXRC_LIB
  1255. X#define MATRIXRC_LIB 0
  1256. X
  1257. X#include "controlw.h"
  1258. X
  1259. X
  1260. X
  1261. X/************** classes MatrixRowCol, MatrixRow, MatrixCol *****************/
  1262. X
  1263. X// Used for accessing the rows and columns of matrices
  1264. X// All matrix classes must provide routines for calculating matrix rows and
  1265. X// columns. Assume rows can be found very efficiently.
  1266. X
  1267. Xenum LSF { LoadOnEntry=1,StoreOnExit=2,IsACopy=4,DirectPart=8,StoreHere=16 };
  1268. X
  1269. X
  1270. Xclass LoadAndStoreFlag : public ControlWord
  1271. X{
  1272. Xpublic:
  1273. X   LoadAndStoreFlag() {}
  1274. X   LoadAndStoreFlag(int i) : ControlWord(i) {}
  1275. X   LoadAndStoreFlag(LSF lsf) : ControlWord(lsf) {}
  1276. X   LoadAndStoreFlag(const ControlWord& cwx) : ControlWord(cwx) {}
  1277. X   FREE_CHECK(LoadAndStoreFlag)
  1278. X};
  1279. X
  1280. Xclass MatrixRowCol
  1281. X// the row or column of a matrix
  1282. X{
  1283. Xpublic:                                        // these are public to avoid
  1284. X                           // numerous friend statements
  1285. X   int length;                                 // row or column length
  1286. X   int skip;                                   // initial number of zeros
  1287. X   int storage;                                // number of stored elements
  1288. X   int rowcol;                                 // row or column number
  1289. X   GeneralMatrix* gm;                          // pointer to parent matrix
  1290. X   Real* store;                                // pointer to local storage
  1291. X                           //    less skip
  1292. X   LoadAndStoreFlag cw;                        // Load? Store? Is a Copy?
  1293. X   void IncrMat() { rowcol++; store += storage; }
  1294. X                           // used by NextRow
  1295. X   void IncrDiag() { rowcol++; skip++; }
  1296. X   void IncrUT() { rowcol++; storage--; store += storage; skip++; }
  1297. X   void IncrLT() { rowcol++; store += storage; storage++; }
  1298. X
  1299. Xpublic:
  1300. X   void Add(const MatrixRowCol&);              // add a row/col
  1301. X   void AddScaled(const MatrixRowCol&, Real);  // add a multiple of a row/col
  1302. X   void Add(const MatrixRowCol&, const MatrixRowCol&);
  1303. X                           // add two rows/cols
  1304. X   void Add(const MatrixRowCol&, Real);        // add a row/col
  1305. X   void Sub(const MatrixRowCol&);              // subtract a row/col
  1306. X   void Sub(const MatrixRowCol&, const MatrixRowCol&);
  1307. X                           // sub a row/col from another
  1308. X   void RevSub(const MatrixRowCol&);           // subtract from a row/col
  1309. X   void Copy(const MatrixRowCol&);             // copy a row/col
  1310. X   void Copy(const Real*&);                    // copy from an array
  1311. X   void Copy(Real);                            // copy from constant
  1312. X   Real SumAbsoluteValue();                    // sum of absolute values
  1313. X   void Inject(const MatrixRowCol&);           // copy stored els of a row/col
  1314. X   void Negate(const MatrixRowCol&);           // change sign of a row/col
  1315. X   void Multiply(const MatrixRowCol&, Real);   // scale a row/col
  1316. X   friend Real DotProd(const MatrixRowCol&, const MatrixRowCol&);
  1317. X                           // sum of pairwise product
  1318. X   Real* operator()() { return store+skip; }   // pointer to first element
  1319. X   Real* Store() { return store; }
  1320. X   int Skip() { return skip; }                 // number of elements skipped
  1321. X   int Storage() { return storage; }           // number of elements stored
  1322. X   void Skip(int i) { skip=i; }
  1323. X   void Storage(int i) { storage=i; }
  1324. X   void SubRowCol(MatrixRowCol&, int, int) const;
  1325. X                           // get part of a row or column
  1326. X   MatrixRowCol() {}                           // to stop warning messages
  1327. X   virtual ~MatrixRowCol();
  1328. X   FREE_CHECK(MatrixRowCol)
  1329. X};
  1330. X
  1331. Xclass MatrixRow : public MatrixRowCol
  1332. X{
  1333. Xpublic:
  1334. X   // bodies for these are inline at the end of this .h file
  1335. X   MatrixRow(GeneralMatrix*, LoadAndStoreFlag, int=0);
  1336. X                                               // extract a row
  1337. X   ~MatrixRow();
  1338. X   void Next();                                // get next row
  1339. X   FREE_CHECK(MatrixRow)
  1340. X};
  1341. X
  1342. Xclass MatrixCol : public MatrixRowCol
  1343. X{
  1344. Xpublic:
  1345. X   // bodies for these are inline at the end of this .h file
  1346. X   MatrixCol(GeneralMatrix*, LoadAndStoreFlag, int=0);
  1347. X                                               // extract a col
  1348. X   MatrixCol(GeneralMatrix*, Real*, LoadAndStoreFlag, int=0);
  1349. X                                               // store/retrieve a col
  1350. X   ~MatrixCol();
  1351. X   void Next();                                // get next row
  1352. X   FREE_CHECK(MatrixCol)
  1353. X};
  1354. X
  1355. X
  1356. X/**************************** inline bodies ****************************/
  1357. X
  1358. Xinline MatrixRow::MatrixRow(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int row)
  1359. X{ gm=gmx; cw=cwx; rowcol=row; gm->GetRow(*this); } 
  1360. X
  1361. Xinline void MatrixRow::Next() { gm->NextRow(*this); }
  1362. X
  1363. Xinline MatrixCol::MatrixCol(GeneralMatrix* gmx, LoadAndStoreFlag cwx, int col)
  1364. X{ gm=gmx; cw=cwx; rowcol=col; gm->GetCol(*this); } 
  1365. X
  1366. Xinline MatrixCol::MatrixCol(GeneralMatrix* gmx, Real* r,
  1367. X   LoadAndStoreFlag cwx, int col)
  1368. X{ gm=gmx; store=r; cw=cwx+StoreHere; rowcol=col; gm->GetCol(*this); } 
  1369. X
  1370. Xinline void MatrixCol::Next() { gm->NextCol(*this); }
  1371. X
  1372. X#endif
  1373. END_OF_FILE
  1374. if test 4899 -ne `wc -c <'newmatrc.h'`; then
  1375.     echo shar: \"'newmatrc.h'\" unpacked with wrong size!
  1376. fi
  1377. # end of 'newmatrc.h'
  1378. fi
  1379. if test -f 'newmatrm.h' -a "${1}" != "-c" ; then 
  1380.   echo shar: Will not clobber existing file \"'newmatrm.h'\"
  1381. else
  1382. echo shar: Extracting \"'newmatrm.h'\" \(3747 characters\)
  1383. sed "s/^X//" >'newmatrm.h' <<'END_OF_FILE'
  1384. X//$$newmatrm.h                            rectangular matrix operations
  1385. X
  1386. X// Copyright (C) 1991,2: R B Davies
  1387. X
  1388. X#ifndef MATRIXRM_LIB
  1389. X#define MATRIXRM_LIB 0
  1390. X
  1391. X
  1392. X// operations on rectangular matrices
  1393. X
  1394. Xclass RectMatrixCol;
  1395. X
  1396. Xclass RectMatrixRowCol
  1397. X// a class for accessing rows and columns of rectangular matrices
  1398. X{
  1399. Xprotected:
  1400. X   Real* store;                   // pointer to storage
  1401. X   int n;                         // number of elements
  1402. X   int spacing;                   // space between elements
  1403. X   int shift;                     // space between cols or rows
  1404. X   RectMatrixRowCol(Real* st, int nx, int sp, int sh)
  1405. X      : store(st), n(nx), spacing(sp), shift(sh) {}
  1406. X   void Reset(Real* st, int nx, int sp, int sh)
  1407. X      { store=st; n=nx; spacing=sp; shift=sh; }
  1408. Xpublic:
  1409. X   Real operator*(const RectMatrixRowCol&) const;         // dot product
  1410. X   void AddScaled(const RectMatrixRowCol&, Real);         // add scaled
  1411. X   void Divide(const RectMatrixRowCol&, Real);            // scaling
  1412. X   void Divide(Real);                                     // scaling
  1413. X   void Negate();                                         // change sign
  1414. X   void Zero();                                           // zero row col
  1415. X   Real& operator[](int i) { return *(store+i*spacing); } // element
  1416. X   Real SumSquare() const;                                // sum of squares
  1417. X   Real& First() { return *store; }                       // get first element
  1418. X   void DownDiag() { store += (shift+spacing); n--; }
  1419. X   void UpDiag() { store -= (shift+spacing); n++; }
  1420. X   friend void ComplexScale(RectMatrixCol&, RectMatrixCol&, Real, Real);
  1421. X   friend void Rotate(RectMatrixCol&, RectMatrixCol&, Real, Real);
  1422. X   FREE_CHECK(RectMatrixRowCol)
  1423. X};
  1424. X
  1425. Xclass RectMatrixRow : public RectMatrixRowCol
  1426. X{
  1427. Xpublic:
  1428. X   RectMatrixRow(const Matrix&, int, int, int);
  1429. X   RectMatrixRow(const Matrix&, int);
  1430. X   void Reset(const Matrix&, int, int, int);
  1431. X   void Reset(const Matrix&, int);
  1432. X   Real& operator[](int i) { return *(store+i); }
  1433. X   void Down() { store += shift; }
  1434. X   void Right() { store++; n--; }
  1435. X   void Up() { store -= shift; }
  1436. X   void Left() { store--; n++; }
  1437. X   FREE_CHECK(RectMatrixRow)
  1438. X};
  1439. X
  1440. Xclass RectMatrixCol : public RectMatrixRowCol
  1441. X{
  1442. Xpublic:
  1443. X   RectMatrixCol(const Matrix&, int, int, int);
  1444. X   RectMatrixCol(const Matrix&, int);
  1445. X   void Reset(const Matrix&, int, int, int);
  1446. X   void Reset(const Matrix&, int);
  1447. X   void Down() { store += spacing; n--; }
  1448. X   void Right() { store++; }
  1449. X   void Up() { store -= spacing; n++; }
  1450. X   void Left() { store--; }
  1451. X   friend void ComplexScale(RectMatrixCol&, RectMatrixCol&, Real, Real);
  1452. X   friend void Rotate(RectMatrixCol&, RectMatrixCol&, Real, Real);
  1453. X   FREE_CHECK(RectMatrixCol)
  1454. X};
  1455. X
  1456. Xclass RectMatrixDiag : public RectMatrixRowCol
  1457. X{
  1458. Xpublic:
  1459. X   RectMatrixDiag(const DiagonalMatrix& D)
  1460. X      : RectMatrixRowCol(D.Store(), D.Nrows(), 1, 1) {}
  1461. X   Real& operator[](int i) { return *(store+i); }
  1462. X   void DownDiag() { store++; n--; }
  1463. X   void UpDiag() { store--; n++; }
  1464. X   FREE_CHECK(RectMatrixDiag)
  1465. X};
  1466. X
  1467. X
  1468. Xinline RectMatrixRow::RectMatrixRow
  1469. X   (const Matrix& M, int row, int skip, int length)
  1470. X   : RectMatrixRowCol( M.Store()+row*M.Ncols()+skip, length, 1, M.Ncols() ) {}
  1471. X
  1472. Xinline RectMatrixRow::RectMatrixRow (const Matrix& M, int row)
  1473. X   : RectMatrixRowCol( M.Store()+row*M.Ncols(), M.Ncols(), 1, M.Ncols() ) {}
  1474. X
  1475. Xinline RectMatrixCol::RectMatrixCol
  1476. X   (const Matrix& M, int skip, int col, int length)
  1477. X   : RectMatrixRowCol( M.Store()+col+skip*M.Ncols(), length, M.Ncols(), 1 ) {}
  1478. X
  1479. Xinline RectMatrixCol::RectMatrixCol (const Matrix& M, int col)
  1480. X   : RectMatrixRowCol( M.Store()+col, M.Nrows(), M.Ncols(), 1 ) {}
  1481. X
  1482. Xinline Real square(Real x) { return x*x; }
  1483. Xinline Real sign(Real x, Real y)
  1484. X   { return (y>=0) ? x : -x; }                    // assume x >=0
  1485. X
  1486. X
  1487. X#endif
  1488. END_OF_FILE
  1489. if test 3747 -ne `wc -c <'newmatrm.h'`; then
  1490.     echo shar: \"'newmatrm.h'\" unpacked with wrong size!
  1491. fi
  1492. # end of 'newmatrm.h'
  1493. fi
  1494. if test -f 'precisio.h' -a "${1}" != "-c" ; then 
  1495.   echo shar: Will not clobber existing file \"'precisio.h'\"
  1496. else
  1497. echo shar: Extracting \"'precisio.h'\" \(3227 characters\)
  1498. sed "s/^X//" >'precisio.h' <<'END_OF_FILE'
  1499. X//$$ precisio.h                          floating point constants
  1500. X
  1501. X#ifndef PRECISION_LIB
  1502. X#define PRECISION_LIB 0
  1503. X
  1504. X#ifndef SystemV                    // if there is float.h
  1505. X
  1506. X
  1507. X#ifdef USING_FLOAT
  1508. X
  1509. X
  1510. Xclass FloatingPointPrecision
  1511. X{
  1512. Xpublic:
  1513. X   static int Dig()
  1514. X      { return FLT_DIG; }        // number of decimal digits or precision
  1515. X   static Real Epsilon()
  1516. X      { return FLT_EPSILON; }    // smallest number such that 1+Eps!=Eps
  1517. X   static int Mantissa()
  1518. X      { return FLT_MANT_DIG; }   // bits in mantisa
  1519. X   static Real Maximum()
  1520. X      { return FLT_MAX; }        // maximum value
  1521. X   static int MaximumDecimalExponent()
  1522. X      { return FLT_MAX_10_EXP; } // maximum decimal exponent
  1523. X   static int MaximumExponent()
  1524. X      { return FLT_MAX_EXP; }    // maximum binary exponent
  1525. X   static Real Minimum()
  1526. X      { return FLT_MIN; }        // minimum positive value
  1527. X   static int MinimumDecimalExponent()
  1528. X      { return FLT_MIN_10_EXP; } // minimum decimal exponent
  1529. X   static int MinimumExponent()
  1530. X      { return FLT_MIN_EXP; }    // minimum binary exponent
  1531. X   static int Radix()
  1532. X      { return FLT_RADIX; }      // exponent radix
  1533. X   static int Rounds()
  1534. X      { return FLT_ROUNDS; }     // addition rounding (1 = does round)
  1535. X   FREE_CHECK(FloatingPointPrecision)
  1536. X};
  1537. X
  1538. X#endif
  1539. X
  1540. X
  1541. X#ifdef USING_DOUBLE
  1542. X
  1543. Xclass FloatingPointPrecision
  1544. X{
  1545. Xpublic:
  1546. X   static int Dig()
  1547. X      { return DBL_DIG; }        // number of decimal digits or precision
  1548. X   static Real Epsilon()
  1549. X      { return DBL_EPSILON; }    // smallest number such that 1+Eps!=Eps
  1550. X   static int Mantissa()
  1551. X      { return DBL_MANT_DIG; }   // bits in mantisa
  1552. X   static Real Maximum()
  1553. X      { return DBL_MAX; }        // maximum value
  1554. X   static int MaximumDecimalExponent()
  1555. X      { return DBL_MAX_10_EXP; } // maximum decimal exponent
  1556. X   static int MaximumExponent()
  1557. X      { return DBL_MAX_EXP; }    // maximum binary exponent
  1558. X   static Real Minimum()
  1559. X   {
  1560. X#ifdef __BCPLUSPLUS__
  1561. X       return 2.225074e-308;     // minimum positive value
  1562. X#else
  1563. X       return DBL_MIN;
  1564. X#endif
  1565. X   }
  1566. X   static int MinimumDecimalExponent()
  1567. X      { return DBL_MIN_10_EXP; } // minimum decimal exponent
  1568. X   static int MinimumExponent()
  1569. X      { return DBL_MIN_EXP; }    // minimum binary exponent
  1570. X   static int Radix()
  1571. X      { return FLT_RADIX; }      // exponent radix
  1572. X   static int Rounds()
  1573. X      { return FLT_ROUNDS; }     // addition rounding (1 = does round)
  1574. X   FREE_CHECK(FloatingPointPrecision)
  1575. X};
  1576. X
  1577. X#endif
  1578. X
  1579. X#endif
  1580. X
  1581. X#ifdef SystemV                    // if there is no float.h
  1582. X
  1583. X#ifdef USING_FLOAT
  1584. X
  1585. Xclass FloatingPointPrecision
  1586. X{
  1587. Xpublic:
  1588. X   static Real Epsilon()
  1589. X      { return pow(2.0,1-FSIGNIF); }  // smallest number such that 1+Eps!=Eps
  1590. X   static Real Maximum()
  1591. X      { return MAXFLOAT; }        // maximum value
  1592. X   static Real Minimum()
  1593. X      { return MINFLOAT; }        // minimum positive value
  1594. X   FREE_CHECK(FloatingPointPrecision)
  1595. X};
  1596. X
  1597. X#endif
  1598. X
  1599. X
  1600. X#ifdef USING_DOUBLE
  1601. X
  1602. Xclass FloatingPointPrecision
  1603. X{
  1604. Xpublic:
  1605. X   static Real Epsilon()
  1606. X      { return pow(2.0,1-DSIGNIF); }  // smallest number such that 1+Eps!=Eps
  1607. X   static Real Maximum()
  1608. X      { return MAXDOUBLE; }          // maximum value
  1609. X   static Real Minimum()
  1610. X      { return MINDOUBLE; }
  1611. X   FREE_CHECK(FloatingPointPrecision)
  1612. X};
  1613. X
  1614. X#endif
  1615. X
  1616. X#endif
  1617. X
  1618. X
  1619. X
  1620. X
  1621. X#endif
  1622. END_OF_FILE
  1623. if test 3227 -ne `wc -c <'precisio.h'`; then
  1624.     echo shar: \"'precisio.h'\" unpacked with wrong size!
  1625. fi
  1626. # end of 'precisio.h'
  1627. fi
  1628. echo shar: End of archive 2 \(of 7\).
  1629. cp /dev/null ark2isdone
  1630. MISSING=""
  1631. for I in 1 2 3 4 5 6 7 ; do
  1632.     if test ! -f ark${I}isdone ; then
  1633.     MISSING="${MISSING} ${I}"
  1634.     fi
  1635. done
  1636. if test "${MISSING}" = "" ; then
  1637.     echo You have unpacked all 7 archives.
  1638.     rm -f ark[1-9]isdone
  1639. else
  1640.     echo You still need to unpack the following archives:
  1641.     echo "        " ${MISSING}
  1642. fi
  1643. ##  End of shell archive.
  1644. exit 0
  1645.  
  1646. exit 0 # Just in case...
  1647.