PLplot: tclMatrix.h Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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