PLplot
5.10.0
|
00001 // -*-C++-*- 00002 // Copyright 1994, 1995 00003 // Maurice LeBrun mjl@dino.ph.utexas.edu 00004 // Institute for Fusion Studies University of Texas at Austin 00005 // 00006 // Copyright (C) 2004 Maurice LeBrun 00007 // 00008 // This file is part of PLplot. 00009 // 00010 // PLplot is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU General Public License as published by 00012 // the Free Software Foundation; either version 2 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // PLplot is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU General Public License 00021 // along with PLplot; if not, write to the Free Software 00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00023 // 00024 //-------------------------------------------------------------------------- 00025 // 00026 // Contains declarations for Tcl "Matrix" command. 00027 // C functions that need access to the matrix data will need 00028 // to include this file. 00029 // 00030 00031 #ifndef __TCLMATRIX_H__ 00032 #define __TCLMATRIX_H__ 00033 00034 #include "plplot.h" 00035 #include <tcl.h> 00036 00037 typedef PLFLT Mat_float; 00038 00039 #if defined ( MSDOS ) 00040 typedef long Mat_int; 00041 #else 00042 typedef int Mat_int; 00043 #endif 00044 00045 enum { TYPE_FLOAT, TYPE_INT }; 00046 00047 // Arrays are column dominant (normal C ordering) 00048 // Array elements are stored contiguously 00049 // Require dimension <= 3 for simplicity 00050 00051 #define MAX_ARRAY_DIM 3 00052 00053 // Useful macros for index calculations 00054 00055 #define I3D( i, j, k ) k + matPtr->n[2] * ( I2D( i, j ) ) 00056 #define I2D( i, j ) j + matPtr->n[1] * ( I1D( i ) ) 00057 #define I1D( i ) i 00058 00059 // Matrix operator data 00060 00061 typedef struct 00062 { 00063 int type; // Data type 00064 int len; // Total length of array 00065 int dim; // Number of dimensions 00066 int n[MAX_ARRAY_DIM]; // Holds array length in each dimension 00067 int tracing; // Set if not persistent 00068 00069 char *name; // Matrix operator name, malloc'ed 00070 00071 Mat_float *fdata; // Floating point data, malloc'ed 00072 Mat_int *idata; // Integer data, malloc'ed 00073 00074 Tcl_Interp *interp; // Interpreter where command is installed 00075 00076 // These do the put/get operations for each supported type 00077 00078 void ( *put )( ClientData clientData, Tcl_Interp* interp, int index, const char *string ); 00079 void ( *get )( ClientData clientData, Tcl_Interp* interp, int index, char *string ); 00080 } tclMatrix; 00081 00082 // Function prototypes 00083 00084 #ifdef __cplusplus 00085 //-------------------------------------------------------------------------- 00086 // // Since C++ does not generally have a per-platform ABI the way C 00087 // // does, we stick to a totally inline class declaration and 00088 // // definition. That way you don't have to keep a separate version of 00089 // // libplplot*.a for each compiler you'd like to use. 00090 // 00091 // // Start by setting up some important macros. 00092 // 00093 00094 #include <iostream> 00095 00096 #ifdef throw 00097 #define TCL_NO_UNDEF 00098 #endif 00099 00100 #ifndef throw 00101 #ifdef __hpux 00102 #if defined ( __GNUC__ ) || defined ( __lucid ) || defined ( __CENTERLINE__ ) \ 00103 || defined ( CENTERLINE_CLPP ) 00104 #define NO_XCPT 00105 #endif 00106 #else 00107 #define NO_XCPT 00108 #endif 00109 00110 #ifdef NO_XCPT 00111 #define try 00112 #define throw( a ) \ 00113 { cerr << "THROW: " << # a << " from " << __FILE__ \ 00114 << " line " << __LINE__ << endl << flush; abort(); } 00115 #define catch( a ) if ( 0 ) 00116 #define Throw 00117 #else 00118 #define Throw throw 00119 #endif 00120 #endif 00121 00122 #define tMat_Assert( a, b ) if ( !( a ) ) \ 00123 { using namespace std; \ 00124 cerr << "Assertion " << # a << " failed in " << __FILE__ \ 00125 << " at line " << __LINE__ << endl << flush; \ 00126 throw( b ); } 00127 00128 //-------------------------------------------------------------------------- 00129 // // class TclMatFloat 00130 // 00131 // // This class provides a convenient way to access the data of a 00132 // // tclMatrix from within compiled code. Someone should make clones of 00133 // // this class for the other tclMatrix supported data types. 00134 //-------------------------------------------------------------------------- 00135 00136 class TclMatFloat { 00137 tclMatrix *matPtr; 00138 public: 00139 TclMatFloat( tclMatrix * ptm ) 00140 : matPtr( ptm ) 00141 { 00142 tMat_Assert( matPtr->type == TYPE_FLOAT, "Type mismatch" ); 00143 } 00144 00145 int Dimensions() const 00146 { 00147 return matPtr->dim; 00148 } 00149 00150 int dim_size( int d ) const 00151 { 00152 tMat_Assert( d < matPtr->dim, "Range error." ); 00153 return matPtr->n[d]; 00154 } 00155 00156 void redim( int nx ) 00157 { 00158 free( matPtr->fdata ); 00159 matPtr->dim = 1; 00160 matPtr->n[0] = nx; 00161 matPtr->len = nx; 00162 matPtr->fdata = (Mat_float *) malloc( matPtr->len * 00163 sizeof ( Mat_float ) ); 00164 } 00165 00166 void redim( int nx, int ny ) 00167 { 00168 free( matPtr->fdata ); 00169 matPtr->dim = 2; 00170 matPtr->n[0] = nx; 00171 matPtr->n[1] = ny; 00172 matPtr->len = nx * ny; 00173 matPtr->fdata = (Mat_float *) malloc( matPtr->len * 00174 sizeof ( Mat_float ) ); 00175 } 00176 00177 void redim( int nx, int ny, int nz ) 00178 { 00179 free( matPtr->fdata ); 00180 matPtr->dim = 3; 00181 matPtr->n[0] = nx; 00182 matPtr->n[1] = ny; 00183 matPtr->n[2] = nz; 00184 matPtr->len = nx * ny * nz; 00185 matPtr->fdata = (Mat_float *) malloc( matPtr->len * 00186 sizeof ( Mat_float ) ); 00187 } 00188 00189 Mat_float& operator() ( int i ) 00190 { 00191 tMat_Assert( matPtr->dim == 1, "Wrong number of indicies." ); 00192 tMat_Assert( i >= 0 && i < matPtr->n[0], 00193 "Out of bounds reference" ); 00194 00195 return matPtr->fdata[i]; 00196 } 00197 00198 Mat_float& operator() ( int i, int j ) 00199 { 00200 tMat_Assert( matPtr->dim == 2, "Wrong number of indicies." ); 00201 tMat_Assert( i >= 0 && i < matPtr->n[0] && 00202 j >= 0 && j < matPtr->n[1], 00203 "Out of bounds reference" ); 00204 00205 return matPtr->fdata[I2D( i, j )]; 00206 } 00207 00208 Mat_float& operator() ( int i, int j, int k ) 00209 { 00210 tMat_Assert( matPtr->dim == 3, "Wrong number of indicies." ); 00211 tMat_Assert( i >= 0 && i < matPtr->n[0] && 00212 j >= 0 && j < matPtr->n[1] && 00213 k >= 0 && k < matPtr->n[2], 00214 "Out of bounds reference" ); 00215 00216 return matPtr->fdata[I3D( i, j, k )]; 00217 } 00218 }; 00219 00220 //-------------------------------------------------------------------------- 00221 // // class TclMatInt 00222 // 00223 // // This class provides a convenient way to access the data of a 00224 // // tclMatrix from within compiled code. This is just like TclMatFloat above, 00225 // // but for ints. 00226 //-------------------------------------------------------------------------- 00227 00228 class TclMatInt { 00229 tclMatrix *matPtr; 00230 public: 00231 TclMatInt( tclMatrix * ptm ) 00232 : matPtr( ptm ) 00233 { 00234 tMat_Assert( matPtr->type == TYPE_INT, "Type mismatch" ); 00235 } 00236 00237 int Dimensions() const 00238 { 00239 return matPtr->dim; 00240 } 00241 00242 int dim_size( int d ) const 00243 { 00244 tMat_Assert( d < matPtr->dim, "Range error." ); 00245 return matPtr->n[d]; 00246 } 00247 00248 void redim( int nx ) 00249 { 00250 free( matPtr->idata ); 00251 matPtr->dim = 1; 00252 matPtr->n[0] = nx; 00253 matPtr->len = nx; 00254 matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) ); 00255 } 00256 00257 void redim( int nx, int ny ) 00258 { 00259 free( matPtr->idata ); 00260 matPtr->dim = 2; 00261 matPtr->n[0] = nx; 00262 matPtr->n[1] = ny; 00263 matPtr->len = nx * ny; 00264 matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) ); 00265 } 00266 00267 void redim( int nx, int ny, int nz ) 00268 { 00269 free( matPtr->idata ); 00270 matPtr->dim = 3; 00271 matPtr->n[0] = nx; 00272 matPtr->n[1] = ny; 00273 matPtr->n[2] = nz; 00274 matPtr->len = nx * ny * nz; 00275 matPtr->idata = (Mat_int *) malloc( matPtr->len * sizeof ( Mat_int ) ); 00276 } 00277 00278 Mat_int& operator() ( int i ) 00279 { 00280 tMat_Assert( matPtr->dim == 1, "Wrong number of indicies." ); 00281 tMat_Assert( i >= 0 && i < matPtr->n[0], 00282 "Out of bounds reference" ); 00283 00284 return matPtr->idata[i]; 00285 } 00286 00287 Mat_int& operator() ( int i, int j ) 00288 { 00289 tMat_Assert( matPtr->dim == 2, "Wrong number of indicies." ); 00290 tMat_Assert( i >= 0 && i < matPtr->n[0] && 00291 j >= 0 && j < matPtr->n[1], 00292 "Out of bounds reference" ); 00293 00294 return matPtr->idata[I2D( i, j )]; 00295 } 00296 00297 Mat_int& operator() ( int i, int j, int k ) 00298 { 00299 tMat_Assert( matPtr->dim == 3, "Wrong number of indicies." ); 00300 tMat_Assert( i >= 0 && i < matPtr->n[0] && 00301 j >= 0 && j < matPtr->n[1] && 00302 k >= 0 && k < matPtr->n[2], 00303 "Out of bounds reference" ); 00304 00305 return matPtr->idata[I3D( i, j, k )]; 00306 } 00307 }; 00308 00309 #ifndef TCL_NO_UNDEF 00310 00311 #ifdef NO_XCPT 00312 #undef NO_XCPT 00313 #undef try 00314 #undef throw 00315 #undef Throw 00316 #undef catch 00317 #endif 00318 00319 #endif 00320 00321 #undef tMat_Assert 00322 00323 extern "C" { 00324 //-------------------------------------------------------------------------- 00325 #endif 00326 00327 // Tcl package initialisation function 00328 00329 int PLDLLIMPEXP_TCLMAT Matrix_Init( Tcl_Interp* ); 00330 00331 // This procedure is invoked to process the "matrix" Tcl command. 00332 00333 int 00334 Tcl_MatrixCmd( ClientData clientData, Tcl_Interp *interp, 00335 int argc, const char **argv ); 00336 00337 // Returns a pointer to the specified matrix operator's data. 00338 00339 tclMatrix PLDLLIMPEXP_TCLMAT * 00340 Tcl_GetMatrixPtr( Tcl_Interp *interp, const char *matName ); 00341 00342 // Some stuff for handling extension subcommands. 00343 00344 typedef int ( *tclMatrixXtnsnProc )( tclMatrix *pm, Tcl_Interp *interp, 00345 int argc, const char *argv[] ); 00346 00347 typedef struct tclMatrixXtnsnDescr 00348 { 00349 char *cmd; 00350 tclMatrixXtnsnProc cmdproc; 00351 struct tclMatrixXtnsnDescr *next; 00352 } tclMatrixXtnsnDescr; 00353 00354 int PLDLLIMPEXP_TCLMAT Tcl_MatrixInstallXtnsn( const char *cmd, tclMatrixXtnsnProc proc ); 00355 00356 #ifdef __cplusplus 00357 } 00358 #endif 00359 00360 #endif // __TCLMATRIX_H__