PLplot  5.15.0
tclMatrix.h
Go to the documentation of this file.
1 // -*-C++-*-
2 // Copyright 1994, 1995
3 // Maurice LeBrun mjl@dino.ph.utexas.edu
4 // Institute for Fusion Studies University of Texas at Austin
5 //
6 // Copyright (C) 2004 Maurice LeBrun
7 // Copyright (C) 2016 Alan W. Irwin
8 //
9 // This file is part of PLplot.
10 //
11 // PLplot is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // PLplot is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with PLplot; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 //--------------------------------------------------------------------------
26 //
27 // Contains declarations for Tcl "Matrix" command.
28 // C functions that need access to the matrix data will need
29 // to include this file.
30 //
31 
32 #ifndef __TCLMATRIX_H__
33 #define __TCLMATRIX_H__
34 
35 #include "plplot.h"
36 #include <tcl.h>
37 
38 typedef PLFLT Mat_float;
39 
40 #if defined ( MSDOS )
41 typedef long Mat_int;
42 #else
43 typedef int Mat_int;
44 #endif
45 
46 enum { TYPE_FLOAT, TYPE_INT };
47 
48 // Arrays are column dominant (normal C ordering)
49 // Array elements are stored contiguously
50 // Require dimension <= 3 for simplicity
51 
52 #define MAX_ARRAY_DIM 3
53 
54 // Useful macros for index calculations
55 
56 #define I3D( i, j, k ) k + matPtr->n[2] * ( I2D( i, j ) )
57 #define I2D( i, j ) j + matPtr->n[1] * ( I1D( i ) )
58 #define I1D( i ) i
59 
60 // Matrix operator data
61 
62 typedef struct
63 {
64  int type; // Data type
65  // It is tempting to declare the next 3 as size_t, but the second
66  // limit on slices must be -1 for one particular case (negative
67  // step with second limit of -1 corresponding to actual index of
68  // 0) so it is better to keep all these as int to reduce casting.
69  int len; // Total length of array
70  int dim; // Number of dimensions
71  int n[MAX_ARRAY_DIM]; // Holds array length in each dimension
72  int tracing; // Set if not persistent
73 
74  char *name; // Matrix operator name, malloc'ed
75 
76  Mat_float *fdata; // Floating point data, malloc'ed
77  Mat_int *idata; // Integer data, malloc'ed
78 
79  Tcl_Interp *interp; // Interpreter where command is installed
80 
81  // These do the put/get operations for each supported type
82 
83  void ( *put )( ClientData clientData, Tcl_Interp* interp, int index, const char *string );
84  void ( *get )( ClientData clientData, Tcl_Interp* interp, int index, char *string );
85  // number of indices that will be either put or get. If indices is NULL, this
86  // should be set to the product of the (MAX_ARRAY_DIM=3) values in the above n array.
87  int nindices;
88  // Array of those indices (malloc'ed if used, NULL if all raw indices
89  // are used in the normal C [row-major] order without reference to the indices
90  // array).
91  int *indices;
92 } tclMatrix;
93 
94 // Function prototypes
95 
96 #ifdef __cplusplus
97 //--------------------------------------------------------------------------
98 // // Since C++ does not generally have a per-platform ABI the way C
99 // // does, we stick to a totally inline class declaration and
100 // // definition. That way you don't have to keep a separate version of
101 // // libplplot*.a for each compiler you'd like to use.
102 //
103 // // Start by setting up some important macros.
104 //
105 
106 #include <iostream>
107 
108 #ifdef throw
109 #define TCL_NO_UNDEF
110 #endif
111 
112 #ifndef throw
113 #ifdef __hpux
114 #if defined ( __GNUC__ ) || defined ( __lucid ) || defined ( __CENTERLINE__ ) \
115  || defined ( CENTERLINE_CLPP )
116 #define NO_XCPT
117 #endif
118 #else
119 #define NO_XCPT
120 #endif
121 
122 #ifdef NO_XCPT
123 #define try
124 #define throw( a ) \
125  { cerr << "THROW: " << # a << " from " << __FILE__ \
126  << " line " << __LINE__ << endl << flush; abort(); }
127 #define catch( a ) if ( 0 )
128 #define Throw
129 #else
130 #define Throw throw
131 #endif
132 #endif
133 
134 #define tMat_Assert( a, b ) if ( !( a ) ) \
135  { using namespace std; \
136  cerr << "Assertion " << # a << " failed in " << __FILE__ \
137  << " at line " << __LINE__ << endl << flush; \
138  throw( b ); }
139 
140 //--------------------------------------------------------------------------
141 // // class TclMatFloat
142 //
143 // // This class provides a convenient way to access the data of a
144 // // tclMatrix from within compiled code. Someone should make clones of
145 // // this class for the other tclMatrix supported data types.
146 //--------------------------------------------------------------------------
147 
148 class TclMatFloat {
149  tclMatrix *matPtr;
150 public:
151  TclMatFloat( tclMatrix * ptm )
152  : matPtr( ptm )
153  {
154  tMat_Assert( matPtr->type == TYPE_FLOAT, "Type mismatch" );
155  }
156 
157  int Dimensions() const
158  {
159  return matPtr->dim;
160  }
161 
162  int dim_size( int d ) const
163  {
164  tMat_Assert( d < matPtr->dim, "Range error." );
165  return matPtr->n[d];
166  }
167 
168  void redim( int nx )
169  {
170  free( matPtr->fdata );
171  matPtr->dim = 1;
172  matPtr->n[0] = nx;
173  matPtr->len = nx;
174  matPtr->fdata = (Mat_float *) malloc( matPtr->len *
175  sizeof ( Mat_float ) );
176  }
177 
178  void redim( int nx, int ny )
179  {
180  free( matPtr->fdata );
181  matPtr->dim = 2;
182  matPtr->n[0] = nx;
183  matPtr->n[1] = ny;
184  matPtr->len = nx * ny;
185  matPtr->fdata = (Mat_float *) malloc( matPtr->len *
186  sizeof ( Mat_float ) );
187  }
188 
189  void redim( int nx, int ny, int nz )
190  {
191  free( matPtr->fdata );
192  matPtr->dim = 3;
193  matPtr->n[0] = nx;
194  matPtr->n[1] = ny;
195  matPtr->n[2] = nz;
196  matPtr->len = nx * ny * nz;
197  matPtr->fdata = (Mat_float *) malloc( matPtr->len *
198  sizeof ( Mat_float ) );
199  }
200 
201  Mat_float& operator() ( int i )
202  {
203  tMat_Assert( matPtr->dim == 1, "Wrong number of indicies." );
204  tMat_Assert( i >= 0 && i < matPtr->n[0],
205  "Out of bounds reference" );
206 
207  return matPtr->fdata[i];
208  }
209 
210  Mat_float& operator() ( int i, int j )
211  {
212  tMat_Assert( matPtr->dim == 2, "Wrong number of indicies." );
213  tMat_Assert( i >= 0 && i < matPtr->n[0] &&
214  j >= 0 && j < matPtr->n[1],
215  "Out of bounds reference" );
216 
217  return matPtr->fdata[I2D( i, j )];
218  }
219 
220  Mat_float& operator() ( int i, int j, int k )
221  {
222  tMat_Assert( matPtr->dim == 3, "Wrong number of indicies." );
223  tMat_Assert( i >= 0 && i < matPtr->n[0] &&
224  j >= 0 && j < matPtr->n[1] &&
225  k >= 0 && k < matPtr->n[2],
226  "Out of bounds reference" );
227 
228  return matPtr->fdata[I3D( i, j, k )];
229  }
230 };
231 
232 //--------------------------------------------------------------------------
233 // // class TclMatInt
234 //
235 // // This class provides a convenient way to access the data of a
236 // // tclMatrix from within compiled code. This is just like TclMatFloat above,
237 // // but for ints.
238 //--------------------------------------------------------------------------
239 
240 class TclMatInt {
241  tclMatrix *matPtr;
242 public:
243  TclMatInt( tclMatrix * ptm )
244  : matPtr( ptm )
245  {
246  tMat_Assert( matPtr->type == TYPE_INT, "Type mismatch" );
247  }
248 
249  int Dimensions() const
250  {
251  return matPtr->dim;
252  }
253 
254  int dim_size( int d ) const
255  {
256  tMat_Assert( d < matPtr->dim, "Range error." );
257  return matPtr->n[d];
258  }
259 
260  void redim( int nx )
261  {
262  free( matPtr->idata );
263  matPtr->dim = 1;
264  matPtr->n[0] = nx;
265  matPtr->len = nx;
266  matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) );
267  }
268 
269  void redim( int nx, int ny )
270  {
271  free( matPtr->idata );
272  matPtr->dim = 2;
273  matPtr->n[0] = nx;
274  matPtr->n[1] = ny;
275  matPtr->len = nx * ny;
276  matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) );
277  }
278 
279  void redim( int nx, int ny, int nz )
280  {
281  free( matPtr->idata );
282  matPtr->dim = 3;
283  matPtr->n[0] = nx;
284  matPtr->n[1] = ny;
285  matPtr->n[2] = nz;
286  matPtr->len = nx * ny * nz;
287  matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) );
288  }
289 
290  Mat_int& operator() ( int i )
291  {
292  tMat_Assert( matPtr->dim == 1, "Wrong number of indicies." );
293  tMat_Assert( i >= 0 && i < matPtr->n[0],
294  "Out of bounds reference" );
295 
296  return matPtr->idata[i];
297  }
298 
299  Mat_int& operator() ( int i, int j )
300  {
301  tMat_Assert( matPtr->dim == 2, "Wrong number of indicies." );
302  tMat_Assert( i >= 0 && i < matPtr->n[0] &&
303  j >= 0 && j < matPtr->n[1],
304  "Out of bounds reference" );
305 
306  return matPtr->idata[I2D( i, j )];
307  }
308 
309  Mat_int& operator() ( int i, int j, int k )
310  {
311  tMat_Assert( matPtr->dim == 3, "Wrong number of indicies." );
312  tMat_Assert( i >= 0 && i < matPtr->n[0] &&
313  j >= 0 && j < matPtr->n[1] &&
314  k >= 0 && k < matPtr->n[2],
315  "Out of bounds reference" );
316 
317  return matPtr->idata[I3D( i, j, k )];
318  }
319 };
320 
321 #ifndef TCL_NO_UNDEF
322 
323 #ifdef NO_XCPT
324 #undef NO_XCPT
325 #undef try
326 #undef throw
327 #undef Throw
328 #undef catch
329 #endif
330 
331 #endif
332 
333 #undef tMat_Assert
334 
335 extern "C" {
336 //--------------------------------------------------------------------------
337 #endif
338 
339 // Tcl package initialisation function
340 
341 int PLDLLIMPEXP_TCLMAT Matrix_Init( Tcl_Interp* );
342 
343 // This procedure is invoked to process the "matrix" Tcl command.
344 
345 int
346 Tcl_MatrixCmd( ClientData clientData, Tcl_Interp *interp,
347  int argc, const char **argv );
348 
349 // Returns a pointer to the specified matrix operator's data.
350 
352 Tcl_GetMatrixPtr( Tcl_Interp *interp, const char *matName );
353 
354 // Some stuff for handling extension subcommands.
355 
356 typedef int ( *tclMatrixXtnsnProc )( tclMatrix *pm, Tcl_Interp *interp,
357  int argc, const char *argv[] );
358 
359 typedef struct tclMatrixXtnsnDescr
360 {
361  char *cmd;
365 
367 
368 #ifdef __cplusplus
369 }
370 #endif
371 
372 #endif // __TCLMATRIX_H__
int Mat_int
Definition: tclMatrix.h:43
struct tclMatrixXtnsnDescr * next
Definition: tclMatrix.h:363
static char ** argv
Definition: qt.cpp:49
int n[MAX_ARRAY_DIM]
Definition: tclMatrix.h:71
#define I2D(i, j)
Definition: tclMatrix.h:57
int * indices
Definition: tclMatrix.h:91
int dim
Definition: tclMatrix.h:70
int tracing
Definition: tclMatrix.h:72
tclMatrix PLDLLIMPEXP_TCLMAT * Tcl_GetMatrixPtr(Tcl_Interp *interp, const char *matName)
Definition: tclMatrix.c:424
static int argc
Definition: qt.cpp:48
int nindices
Definition: tclMatrix.h:87
int(* tclMatrixXtnsnProc)(tclMatrix *pm, Tcl_Interp *interp, int argc, const char *argv[])
Definition: tclMatrix.h:356
Mat_float * fdata
Definition: tclMatrix.h:76
struct tclMatrixXtnsnDescr tclMatrixXtnsnDescr
Tcl_Interp * interp
Definition: tclMatrix.h:79
char * name
Definition: tclMatrix.h:74
Mat_int * idata
Definition: tclMatrix.h:77
#define MAX_ARRAY_DIM
Definition: tclMatrix.h:52
#define PLDLLIMPEXP_TCLMAT
Definition: pldll.h:121
int PLDLLIMPEXP_TCLMAT Tcl_MatrixInstallXtnsn(const char *cmd, tclMatrixXtnsnProc proc)
Definition: tclMatrix.c:464
int type
Definition: tclMatrix.h:64
int PLDLLIMPEXP_TCLMAT Matrix_Init(Tcl_Interp *)
Definition: matrixInit.c:27
float PLFLT
Definition: plplot.h:163
#define I3D(i, j, k)
Definition: tclMatrix.h:56
int Tcl_MatrixCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
static Tcl_Interp * interp
Definition: tkMain.c:120
PLFLT Mat_float
Definition: tclMatrix.h:38
int len
Definition: tclMatrix.h:69
tclMatrixXtnsnProc cmdproc
Definition: tclMatrix.h:362