• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

tclMatrix.h

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

Generated on Wed Oct 12 2011 20:42:23 for PLplot by  doxygen 1.7.1