Using Matrix Objects


A Matrix object is used to convert a whole matrix of data from one unit to the other in one operation. The Object Properties dialog of a Matrix object looks like the following:

 

Generate/Matrix.jpg

 

You can enter the number of columns, rows, and sheets into the corresponding fields. SansGUI will allocate the memory to store your data and create the specified data grids for editing. There is a limited number of sheets supported by SansGUI. You can type in a large number (e.g. 1000) in the Value field of the Number of Sheets attribute to let SansGUI report the limit to you. The last field, User Data, has the Unit shown for the entire matrix data. Select the source unit before entering your data into the matrix and select the target unit to convert the values in the whole matrix. The cell at the upper-left corner of each Data sheet indicates which unit is currently associated with the data. You have to come back to the Specification tab to select a different unit. You can use Ctrl+PageUp and Ctrl+PageDown key combinations to switch among tabs.

Check Data Button

The Check Data button triggers no operation by default. You can override this default behavior as needed. However, the internal data for the entire matrix are stored and manipulated in their base unit only. Values of different units are shown in the presentation layer (user interface), not the data manipulation layer (program access). Also, the matrix data is stored in column-major order to simplify the data transfer process with programming environments such as Fortran and Matlab.

Load Data Button

The Load Data button triggers no operation by default. We normally override two functions to resize the matrix and populate its data:

You are encouraged to read Chapter 6 Overriding Simulator Routines of the SansGUI User's Guide to find out all the details. Here we include two overriding routines implemented in either MSVC++ or CVF as examples. When you have the user overriding DLL built, you need to enter the DLL paths in the DLL Override tab so that the functions can be called when you click on the Load Data button. If you do not know how to enter the DLL paths into the Dynamic-Linked Library fields, please check the Specifying File Paths section. Also, please note that the matrix data is stored in column-major order to simplify the data transfer process with programming environments such as Fortran and Matlab.

MSVC++ Example

The example routines simply specify 100 rows and 100 columns in the data matrix and populate each data cell with a floating point value consisting of:

The highlighted code sections (in red) are manually entered; others are from the skeleton code for user overriding functions in the SansGUI environment.

/* Matrix.cpp - sample user DLL override framework for C/C++

 * Copyright (C) 2000-2001 ProtoDesign, Inc.

 * SansGUI(tm) licensee has the permission to copy and modify the codes in this file

 * under the terms in the license agreement.

 */

 

#include <stdio.h>

#include <string.h>

 

#define SG_OVERRIDE_FUNC /* to use the function declarations in SGdll.h */

#include "SGdll.h"

#undef SG_OVERRIDE_FUNC /* just release the special definition */

 

#define SG_NDX_ICOLS 0 /* iCols - Number of Columns */

#define SG_NDX_IROWS 1 /* iRows - Number of Rows */

#define SG_NDX_ISHEETS 2 /* iSheets - Number of Sheets */

#define SG_NDX_FUSER 3 /* fUser - User Data in Matrix */

#define MATRIX_SIZE 100

 

/* ===========================================================================

 * SG_xLoadSize - called before SG_xLoad is called for resizing array

 * ---------------------------------------------------------------------------

 */

SG_RET_CODE SG_xLoadSize(SG_OBJ *const self,

                         SG_OBJ *const simCtrl, SG_OBJ *const chgChild,

                         SG_OBJ *const refObjs[], const INT *const piRefObjs,

                         SG_OBJ *const adjObjs[], const INT *const piAdjObjs,

                         SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,

                         TCHAR *const cMessage, const INT iMsgLen,

                         TCHAR *const cCommand, const INT iCmdLen,

                         SG_FILE *const pOutFile )

{

    if (!SG_IsSchemaOK(self->nSGobjSchema))

        return SG_R_SCHM; /* always check the object's schema version */

 

    /* TODO: put your simulator code here */

    /* Specify the size of the matrix for SansGUI to allocate */

    self->zValues[SG_NDX_ICOLS].iData[0] = MATRIX_SIZE;

    self->zValues[SG_NDX_IROWS].iData[0] = MATRIX_SIZE;

 

    return SG_R_OK;

}

/* ===========================================================================

 * SG_xLoad - called when the user clicks on the Load Data button in editor

 * ---------------------------------------------------------------------------

 */

SG_RET_CODE SG_xLoad(SG_OBJ *const self,

                         SG_OBJ *const simCtrl, SG_OBJ *const chgChild,

                         SG_OBJ *const refObjs[], const INT *const piRefObjs,

                         SG_OBJ *const adjObjs[], const INT *const piAdjObjs,

                         SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,

                         TCHAR *const cMessage, const INT iMsgLen,

                         TCHAR *const cCommand, const INT iCmdLen,

                         SG_FILE *const pOutFile )

{

    const INT iCols = self->zValues[SG_NDX_ICOLS].iData[0];

    const INT iRows = self->zValues[SG_NDX_IROWS].iData[0];

    int i, j;

 

    if (!SG_IsSchemaOK(self->nSGobjSchema))

        return SG_R_SCHM; /* always check the object's schema version */

 

    /* TODO: put your simulator code here */

    /* Populate the matrix (column-major order) with Row.Col (1-based) values */

    for (i = 0; i < iCols; i++)

        for (j = 0; j < iRows; j++)

            self->zValues[SG_NDX_FUSER].fData[i * iCols + j] =

                  (float)(i + 1) / (float)iCols + (float)(j + 1);

 

    return SG_R_OK;

}

/* ===========================================================================

 */

CVF Example

The example routines simply specify 100 rows and 100 columns in the data matrix and populate each data cell with a floating point value consisting of:

The highlighted code sections (in red) are manually entered; others are from the skeleton code for user overriding functions in the SansGUI environment. There is a fillMatrix subroutine that demonstrates how simple it is to access a multi-dimensional matrix using an assumed-shape array in Fortran.

! Matrix.f - sample user DLL override framework for Fortran

! Copyright (C) 2000-2001 ProtoDesign, Inc.

! SansGUI(tm) licensee has the permission to copy and modify the codes in this file

! under the terms in the license agreement.

 

! ======================================================================

! SG_xLoadSize - called before SG_xLoad is called for resizing array

! ----------------------------------------------------------------------

      integer function SG_xLoadSize(self, &

     & simCtrl, chgChild, &

     & pRefObjs, iRefObjs, &

     & pAdjObjs, iAdjObjs, &

     & pLnkObjs, iLnkObjs, &

     & cMessage, cCommand, pOutFile )

!DEC$ IF DEFINED (_DLL)

!DEC$ ATTRIBUTES DLLEXPORT :: SG_xLoadSize

!DEC$ END IF

      include "SGdllf.h"

 

      ! TODO: declare your local variables here

      integer, dimension(*) :: iCols

      integer, dimension(*) :: iRows

      POINTER(PTR_iCols, iCols)

      POINTER(PTR_iRows, iRows)

      integer, parameter :: SG_NDX_ICOLS = 1

      integer, parameter :: SG_NDX_IROWS = 2

      integer, parameter :: MATRIX_SIZE = 100

 

      if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then

          SG_xLoadSize = SG_R_SCHM

          return

      end if

 

      ! TODO: put your simulator code here

      ! Specify the size of the Matrix for SansGUI to allocate

      PTR_zValues = self%pzValues

      PTR_iCols = zValues(SG_NDX_ICOLS)%vData

      PTR_iRows = zValues(SG_NDX_IROWS)%vData

      iCols(1) = MATRIX_SIZE

      iRows(1) = MATRIX_SIZE

 

      SG_xLoadSize = SG_R_OK

      return

      end

! ======================================================================

! SG_xLoad - called when the user clicks on the Load Data button in editor

! ----------------------------------------------------------------------

      integer function SG_xLoad(self, &

     & simCtrl, chgChild, &

     & pRefObjs, iRefObjs, &

     & pAdjObjs, iAdjObjs, &

     & pLnkObjs, iLnkObjs, &

     & cMessage, cCommand, pOutFile )

!DEC$ IF DEFINED (_DLL)

!DEC$ ATTRIBUTES DLLEXPORT :: SG_xLoad

!DEC$ END IF

      include "SGdllf.h"

 

      ! TODO: declare your local variables here

      integer, dimension(*) :: iCols

      integer, dimension(*) :: iRows

      real*4, dimension(*) :: fUser

      integer :: i, j

      POINTER(PTR_iCols, iCols)

      POINTER(PTR_iRows, iRows)

      POINTER(PTR_fUser, fUser)

      integer, parameter :: SG_NDX_ICOLS = 1

      integer, parameter :: SG_NDX_IROWS = 2

      integer, parameter :: SG_NDX_FUSER = 4

 

      if (self%nSGobjSchema .ne. SG_OBJ_SCHEMA) then

          SG_xLoad = SG_R_SCHM

          return

      end if

 

      ! TODO: put your simulator code here

      ! Populate the matrix (column-major order) with Row.Col (1-based) values

      PTR_zValues = self%pzValues

      PTR_iCols = zValues(SG_NDX_ICOLS)%vData

      PTR_iRows = zValues(SG_NDX_IROWS)%vData

      PTR_fUser = zValues(SG_NDX_FUSER)%vData

 

      ! Treat the data array here as a linear (1-dimensional) array

      !do i = 1, iCols(1)

      ! do j = 1, iRows(1)

      ! fUser((i - 1) * iCols(1) + j) = REAL(i) / REAL(iCols(1)) + j

      ! end do

      !end do

 

      ! call fillMatrix subroutine to process the data array as 2-dimensional

      call fillMatrix(fUser, iRows(1), iCols(1))

 

      SG_xLoad = SG_R_OK

      return

      end

! ======================================================================

! fillMatrix - populate the data array as 2-dimensional, column-major order

! ----------------------------------------------------------------------

      subroutine fillMatrix(matrix, numRows, numCols)

      integer :: numRows, numCols

      intent (in) numRows, numCols

      real*4, dimension(numRows, numCols) :: matrix

      integer :: i, j

 

      do i = 1, numCols

          do j = 1, numRows

              matrix(j, i) = REAL(i) / REAL(numCols) + j

          end do

      end do

 

      return

      end

! ======================================================================

 



Welcome to Unit Conversion for SansGUI Using Table Objects Using Unit SimControl Objects

Unit Conversion for SansGUI Version 1.1

Copyright 2001-2003 ProtoDesign, Inc. All rights reserved.

http://protodesign-inc.com