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