PLplot 5.15.0
Loading...
Searching...
No Matches
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
39
40#if defined ( MSDOS )
41typedef long Mat_int;
42#else
43typedef int Mat_int;
44#endif
45
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
62typedef 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.
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
148class TclMatFloat {
149 tclMatrix *matPtr;
150public:
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
240class TclMatInt {
241 tclMatrix *matPtr;
242public:
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
335extern "C" {
336//--------------------------------------------------------------------------
337#endif
338
339// Tcl package initialisation function
340
341int PLDLLIMPEXP_TCLMAT Matrix_Init( Tcl_Interp* );
342
343// This procedure is invoked to process the "matrix" Tcl command.
344
345int
346Tcl_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
352Tcl_GetMatrixPtr( Tcl_Interp *interp, const char *matName );
353
354// Some stuff for handling extension subcommands.
355
356typedef int ( *tclMatrixXtnsnProc )( tclMatrix *pm, Tcl_Interp *interp,
357 int argc, const char *argv[] );
358
365
367
368#ifdef __cplusplus
369}
370#endif
371
372#endif // __TCLMATRIX_H__
#define PLDLLIMPEXP_TCLMAT
Definition pldll.h:121
float PLFLT
Definition plplot.h:163
static int argc
Definition qt.cpp:48
static char ** argv
Definition qt.cpp:49
struct tclMatrixXtnsnDescr * next
Definition tclMatrix.h:363
tclMatrixXtnsnProc cmdproc
Definition tclMatrix.h:362
Mat_int * idata
Definition tclMatrix.h:77
int n[MAX_ARRAY_DIM]
Definition tclMatrix.h:71
char * name
Definition tclMatrix.h:74
int nindices
Definition tclMatrix.h:87
Mat_float * fdata
Definition tclMatrix.h:76
Tcl_Interp * interp
Definition tclMatrix.h:79
int * indices
Definition tclMatrix.h:91
int tracing
Definition tclMatrix.h:72
@ TYPE_FLOAT
Definition tclMatrix.h:46
@ TYPE_INT
Definition tclMatrix.h:46
struct tclMatrixXtnsnDescr tclMatrixXtnsnDescr
#define I3D(i, j, k)
Definition tclMatrix.h:56
int Mat_int
Definition tclMatrix.h:43
int PLDLLIMPEXP_TCLMAT Matrix_Init(Tcl_Interp *)
Definition matrixInit.c:27
PLFLT Mat_float
Definition tclMatrix.h:38
int(* tclMatrixXtnsnProc)(tclMatrix *pm, Tcl_Interp *interp, int argc, const char *argv[])
Definition tclMatrix.h:356
tclMatrix PLDLLIMPEXP_TCLMAT * Tcl_GetMatrixPtr(Tcl_Interp *interp, const char *matName)
Definition tclMatrix.c:424
int Tcl_MatrixCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
#define MAX_ARRAY_DIM
Definition tclMatrix.h:52
int PLDLLIMPEXP_TCLMAT Tcl_MatrixInstallXtnsn(const char *cmd, tclMatrixXtnsnProc proc)
Definition tclMatrix.c:464
#define I2D(i, j)
Definition tclMatrix.h:57
static Tcl_Interp * interp
Definition tkMain.c:120