Using CONNECT/C++

A guide to the CONNECT/C++ class library for C++ developers

 

Class Hierarchy

Introduction

Features and Benefits

 

Client Class Overview

-          Data object classes

-          Function evaluation classes

-          Client-to-engine connection classes

-          Database classes

 

Architectural Features

-          CSPobject

-          Constructors and generating functions

-          Copy constuctors

-          Assignment operators

-          Overloading operators

-          Converting CSPobject to s_object pointer

-          Subscripting operators

-          Automatic type conversions

-          Subscript and replacement operators

-          Subscript and arithmetic operators

-          Matrix computations

-          Printing to stdout

-          Named objects

-          Evaluation frames for unnamed objects

 

Using CONNECT/C++ in .Call

 

CSPengineConnect

-          Overview

-          Class members

 

CSPevaluator

-          Overview

-          Class members

 

CSPnumeric

-          Overview

-          Class members

 

CSPinteger

-          Overview

-          Class members

 

CSPcharacter

-          Overview

-          Class members

 

CSPcall

-          Overview

-          Class members

 

CSParray

-          Overview

-          Class members

 

CSPmatrix

-          Overview

-          Class members

 


S-PLUS Foundation Class Library (CONNECT/C++) Version 6.0

 

This chart shows the inheritance trees for specific classes in CONNECT/C++.


CONNECT/C++ Introduction

Taken together, the classes in the CONNECT/C++ Foundation Class Library make up a "client application framework" — the framework on which you build a client application for the S engine that can create data objects, perform operations on objects, call S functions, evaluate S syntax, and get results.

 

You use specific classes in CONNECT/C++ to set up a connection to the S engine, create and operate on data objects, call S functions, and evaluate S syntax.  Notification of changes to objects, output from functions and evaluations, and database attaches and detaches are managed by the class which sets up the connection to the S engine.

 

There are several example client applications provided in the installation directory, if you chose to have Samples installed during setup.

 

-          HELLO demonstrates how to create a simple client application.

-          SPLLM is similar to HELLO but creates an LM object.

-          SSC demonstrates how to create a simple S engine client with expression evaluation and result output as well as notification on object modifications.

-          DMatrix demonstrates how to create and operate on matrices using CSPmatrix.

-          GaussSDL demonstrates how to use CONNECT/C++ in .Call applications.

-          Euler demonstrates how to use CONNECT/C++ CSPcall class.

 

These samples are located in the samples directory under S_HOME.

 

Source code for the CONNECT/C++ class library is included in the sconnect directory under S_HOME.

CONNECT/C++ Features and Benefits

The CONNECT/C++ Foundation Class Library is an object-oriented C++ interface to the S engine that allows a developer to write a client program and S-PLUS modules using data objects and structures from the S engine, run S functions, as well as evaluate S syntax and get results.  The foundation classes are for C++ developers who want to construct client applications that will use the S engine for data processing and computation.

 

The class library provides the following features and benefits in a C++ client application and S-PLUS modules:

 

·         Classes which encapsulate the details of connecting to and working with the S engine allow a significant reduction in the effort and code requirements to write a client application using the S engine.

·         Classes provide methods and properties that allow access to all major S objects.  This allows the developer to create and work with S objects without having to know the details of the structure of the objects themselves.

·         Automatic reference counting of S objects means that objects are automatically cleaned up when scope changes in the program.

·         Powerful Vector, Array, and Matrix classes allow for fast and powerful data manipulation through easy to use methods.

·         S functions may be called from the client given the name of the function and a list of arguments to pass.  This enables the client to access S functions and get results easily.

 

·         Override-able event handler methods provide notification to the client application when S objects change and when output is available from evaluations or data operations.

·         Persistant objects with names associated with the S database can be created and initialized in one call.  This cuts down the code overhead in the client application when creating objects.

CONNECT/C++ Client Class Overview

The class library provides a set of classes that can be used to create a client application to create and manipulate persistant data objects, run S functions, parse and evaluate S expressions, and receive output and notification when objects are changed or when databases are attached and detached.

 

The following sections provide an overview of specific categories of classes used to accomplish these operations in a client application.

Data object classes

These classes provide methods to create and operate on arrays, matrices, and vectors.  To use these classes to create a data object in a client application, simply call the object constructor or call the Create() method.  For a persistant object, specify the name of the object if any and an S syntax expression you wish to be parsed and evaluated and then assigned the result to this object in order to initialize it with data.  Alternatively, a data object can be constructed using a form of the constructor that takes an optional S syntax expression as an argument.  This is useful if named (persistant) objects are not required, but intialization is required.  Once the object is created, methods can be used to operate on the object.

 

To receive notification in the client when a data object changes, create a new class in the client application derived from the appropriate base class and override the virtual methods for handling object notification.  When a named object is modified or removed, those virtual methods in the client are called.

 

For more information on using specific data object classes, please see the appropriate section on the specific class.

Function evaluation classes

The CSPcall class allows S functions to be evaluated with arguments passed to the function from the client.  Arguments are objects derived from CSPobject, which may include data objects and other S objects.  Results are returned as a CSPobject to the client.  To use this class, simply call the object constructor with the name of the function to run and any arguments you wish to pass from the client to the function.

 

For more information on using CSPcall, please see the section on this class.

Client-to-engine connection classes

The CSPengineConnect class manages a connection between the client and the S engine.  This connection permits creation of objects in the permanent frame, creation of persistent unnamed objects outside of .Call routines, notification in the client when databases are attached or detached, output routing to the client, and evaluation of S syntax expressions.

 

To use CSPengineConnect, create a new class derived from CSPengineConnect in the client, override the virtual methods for receiving database attach/detach notification, and output notification, and add a member variable to the client application class object to record a reference to a single instance of this derived class.

 

Use of the CSPengineConnect class is only necessary when one or more of the following features is desired in the client program:

-          Integrate S+ engine DLLs with another application (client)

-          Notification in the client when databases are attached or detached and when changes are made in persistent objects.

-          Output redirected to the client

 

For more information on using CSPengineConnect, please see the section on this class.

Evaluator classes

 

The CSPevaluator class manages memory resource, errors and the top-evaluation frame.  Although it is optional, instantiating an object of CSPevalutor class at the top of a try block can speedup the code, and the corresponding catch block will receive an exception error when unexpected error occurs in the S engine. 

 

To use CSPevaluator, create an instance of this class at the top of a try block as shown below:

 

double minValue = 0;

try

{

       //Open top-level-evalutor (frame 1) if it is close

       CSPevaluator sEvaluator;

       CSPnumeric myNumeric = sEvaluator.eval("1:10");

       minValue = myNumeric.Min(); //minValue = 1

 

} //Close top-level-evaluator when sEvaluator is out of scope

catch(...)

{

       //Unexpected error occurred in the engine

}

 

For more information on using CSPevaluator, please see the section on this class.

CONNECT/C++ Architectural Features

The following sections describe the basic architectural featues in the class library and some of the specific programming features available in the library that make it possible to perform S operations efficiently in client programs and modules written in C++.  Classes and methods discussed in this section are fully documented in the reference sections for the classes.

 

CSPobject – the abstract base class

 

CSPobject is the abstract base class of most all of the classes that represent S classes.  It provides common functionality to its derived classes, and its most important data member is:

 

s_object* CSPobject::m_ps_object

 

A class that represents an S class inherits m_ps_object because CSPobject is its base class.  As a smart pointer, a derived class of CSPobject provides safer methods to manipulate the data pointed by m_ps_object as compared to using global C functions.   For example, the constructor, the destructor, and the assignment operators automatically increment and decrement reference counting whenever appropriate to provide the same data sharing mechanism as that of the SV4 language.

 

All CSPobject-derived classes have a method called IsValid() which allows you to test whether the member m_ps_object is valid or not.

 

Constructors and Generating Functions

 

CSPclass::CSPclass(const char* pszExpression);

// pszExpression is a string representing valid S code.

 

where ‘class’ is a CSPobject-derived object

 

Often, S generating functions are more convenient than the S method new.  Similarly, constructors of CONNECT/C++ classes can provide the same convenience.  This form of the object constructor parses and evaluates pszExpression and uses the resultant S object as its value.  Normally, pszExpression should contain an S expression that calls to an appropriate generating function.  However, it works for any S expression that returns a valid S object and the constructor automatically coerces the returned object to the class that it represents.  It increments the reference count upon completion, as well.  In case of errors, the constructor throws an exception in the client application.

 

For example:

 

CSPevaluator s;

 

CSPinteger x("1:4");                // x<-1:4

CSPnumeric y("fuel.frame[,1]");     // y<-as(fuel.frame[,1], 'numeric')

CSPnumeric z("new('numeric')");     // z<- new('numeric')

CSPmatrix A("matrix(1:4, nrow=2)");      // A<-matrix(1:4,nrow=2)

CSPmatrix B("1:4");                 // B<-as(1:4, 'matrix')

 

// Do something with x,y,z,A, and B

 

Copy Constructors

 

Two forms of copy constructors are available:

 

CSPclass::CSPclass(const CSPclass& sObject);

CSPclass::CSPclass(s_object* ps_object);

 

where ‘class’ is a CSPobject-derived object

 

The copy constructor of a CONNECT/C++ class behaves like an S assignment operator when the S object name is first used.  They both share the same data with the object names used to construct them.  However, for the CONNECT/C++ classes sharing is not possible if the classes are incompatible.  It increments the reference count upon completion.

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("1:4"); // x<-1:4

CSPnumeric u(x);           // u<-x # u shares data with x

CSPmatrix A(x);                   // A<-as(x,'matrix') # A shares data with x

CSPcharacter v(x);         // v<-as(x,'character') # no sharing

 

s_object* ps_object = x.GetPtr(); //Get pointer to s_object*

CSPnumeric U(ps_object);   // U shares data with x

CSPmatrix a(ps_object);           // a shares data with x

 

Assignment operators

 

CSPclass& CSPclass::operator=(const CSPclass& sObject);

 

where ‘class’ is a CSPobject-derived object

 

The assignment operator of an CONNECT/C++ class behaves like an S assignment operator when the S object name is already used.  However, the left-hand-side object of the operator = is an existing and valid object.  It decrements reference count on the old object and increments reference count on the new object before swapping the two object pointers.

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("1:4"); // x<-1:4

CSPnumeric u = x;    // u<-new('numeric'); u<-x # u shares data with x

CSPmatrix A = x;     // A<-new('matrix'); A<-as(x,'matrix') # no sharing

 

CSPnumeric y; // y<-new("numeric")

u = y;      // u<-y # u switches to share data with y

A = y; // A<-as(y,'matrix') # A switches to share data with y

 

Overloading Operators

 

CSPclass& CSPclass::operator+(const CSPclass& sObject);

CSPclass& CSPclass::operator-(const CSPclass& sObject);

CSPclass& CSPclass::operator*(const CSPclass& sObject);

CSPclass& CSPclass::operator/(const CSPclass& sObject);

 

where ‘class’ is a CSPobject-derived object

 

CONNECT/C++ contains some useful overloading operator such as +, -, * and /.  These operators perform element-by-element operations in the same way as in the S language.  However, the * operator for the matrix class is different.  The operator for CSPmatrix is a real matrix multiplication operator equivalent to the S %*% operator.

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("1:4"); // x<-1:4

CSPnumeric y ("4:1"); // y<-4:1

y = y+x*x;    // y<-y+x*x

 

CSPmatrix A("matrix(1:4,nrow=2)"); // A <- matrix(1:4,nrow=2)

CSPmatrix B("matrix(4:1,nrow=2)"); // B <- matrix(4:1,nrow=2)

CSPmatrix D = A*A + B*B;   // D <- A %*% A + B %*% B

 

Converting CSPobject to s_object*

 

s_object* CSPobject::operator*();

s_object* CSPobject::operator&();

 

Sometimes, an application needs to access the s_object* directly.  For example, the arguments and the return value of all .Call interfaces must be s_object*.  CSPobject provides a convenient way to automatically convert to s_object*.  Simply use a CSPobject wherever a s_object* is required.  It automatically invokes a conversion operator that returns the s_object* as appropriate. 

 

For example:

 

s_object* myCall()

{

       CSPnumeric x("1:10");

       return x;

}

s_object *pReturn = myCall();

 

The return statement, return x, first typecasts x to type s_object*.  This invokes the operator *() of the CSPnumeric class (derived from CSPobject) which ensures that the destructor of x does not delete the object, even if the reference count drops to zero.

Subscripting Operators

 

CSPproxy CSPvector::operator()(long lIndex);

// Fortran style indexing starting from index 1

 

CSPproxy CSParray::operator()(long l1, long l2=1, …);

// Fortran style indexing and ordering

 

CONNECT/C++ contains some useful overloading subscripting operators ‘()’ for the derived classes CSPvector and CSParray and their derived classes such as CSPnumeric and CSPmatrix.  The proxy class of the returned object provides supports for read/write and mixed-mode operations.

Automatic type conversions

 

Automatic conversions from CSPproxy to scalar C++ built-in types such as long and double invoke the template function below:

 

Template<class T>

CSPproxy::operator T() const; // rvalue

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("c(0.1, 0.2, 0.8, 0.9)");   // x<- c(0.1, 0.2, 0.8, 0.9)

double d = x(1);     // d <-x[1] # d is 0.1

d = d + x(2);        // d<- d+x[1] # d is 0.3

double e = (long) x(1);    // e<-as.integer(x[2]) # e is 0

long n = x(1);             // n <-as.integer(x[1]) # n is 0

n = n + x(2);        // n <- n+as.integer(x[2]) # n is still 0

 

and as another example:

 

CSPevaluator s;

 

CSPmatrix A("matrix(c(0.1, 0.2, 0.8, 0.9),  2)");

       // A<- matrix(c(0.1, 0.2, 0.8, 0.9),  2)

 

double d = A(1,1);   // d <-A[1,1] # d is 0.1

d = d + A(2,1);            // d<- d+A[2,1] # d is 0.3

long e = (long) A(2,1);    // e<-as.integer(A[2,1]) # e is 0

long n = A(1,1);     // n <-as.integer(A[1,1]) # n is 0

n = n + A(2,1);            // n <- n+as.integer(A[2,1]) # n is still 0

 

Subscript and Replacement Operations

 

CSPproxy& CSPproxy::operator=(long);

CSPproxy& CSPproxy::operator=(double);

CSPproxy& CSPproxy::operator=(const CSPproxy&);

 

If a subscript operator of a CSPobject-derived class returns a lvalue object of CSPproxy, the operation involves replacing an element of the S object.  Since writing data is not possible for a shared S object, CSPproxy must determine whether to copy data before replacing its elements.  This action occurs in one of its overloaded assignment operations.

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("1:4"); // x<- 1:4

x(1) = 0.0;                // x[1]<- 0 # x is not share, simply set x[1] to 0.0

x(2) = x(1);         // x[2]<- x[1] # x is not share, simply set x[2] to 0.0

CSPnumeric y(x);     // y<- x # y shares data with x

y(1)= 10.0;                // y[1]<- 10 #copy and replace: y[1] is 10 and x[1] is 0

 

Subscript and Arithmetic Operations

 

+, -, * and /

long CSPproxy::operator+(long)

double CSPproxy::operator+(double)

 

Some overloaded operators are available to support mixed-mode arithmetic operations involving subscripting objects of classes derived from CSPobject. These operators perform mixed-mode operations following the same rules as S:

 

For example:

 

CSPevaluator s;

 

CSPnumeric x("1:4"); // x<- 1:4

CSPnumeric y(x);     // y<- x # y shares data with x

 

CSPmatrix A("matrix(1:4,nrow=2)"); // A <- matrix(1:4,nrow=2)

double e = A(1,1)+A(1,2);                // e <- A[1,1] + A[1,2]

A(1,2) = e*(A(1,1)+A(2,1));              // A[1,2] <- e*(A[1,1]+A[2,1])

A(2,2) = x(1)*A(1,1)+y(2)*A(2,1); // A[1,2] <- x[1]*A[1,1]+y[2]*A[2,1]

 

CSParray X("array(1:16, c(2,2,2,2))");   // X<-array(1:16, c(2,2,2,2))

X(1,1,1,1) = X(2,1,1,1) + e;             // X[1,1,1,1] <- X[2,1,1,1]+e;

X(2,1,1,1) = y(1) - X(2,1,1,1);       // X[2,1,1,1] <- y[1] - X[2,1,1,1];

X(1,2,1,1) = A(1,1) * X(2,1,1,1);     // X[1,2,1,1] = A[1,1] * X[2,1,1,1];

 

Matrix computations

 

double CSPmatrix::ConditionNumber(void);

CSPmatrix SPL_Multiply(const CSPmatrix& A, const CSPmatrix& B);

CSPnumeric SPL_Multiply(const CSPmatrix& A, const CSPnumeric& x);

 

Some overloaded functions are available for matrix computations.  These computations are multi-threaded on some platforms (currently Win/NT on Intel multi-processor machines).

 

For example:

 

CSPevaluator s;

 

CSPmatrix A("matrix(5:8, nrow=2)");

 // A<- matrix(5:8, nrow=2)

CSPmatrix B(A);                                        // B<- A

CSPmatrix D = SPL_Multiply(A, B); // D<-A %*% B

 

CSPnumeric x("1:2");              // x<- rnorm(2)

CSPnumeric y = SPL_Multiply(A, x); // y<- A %*% x

 

Printing to stdout

void CSPobject::Print(void);

 

For example:

 

CSPevaluator s;

 

CSPcharacter message("'hello'");  // message <- 'hello'

message.Print();                                // print(message)

 

CSPmatrix M("matrix(1:4,nrow=2)"); // M<-matrix(1:4, nrow=2)

M.Print();                                       // print(M)

 

Named Persistant Objects

All CSPobject-derived objects are placeholders for an s_object that exists in the engine.  So, this C++ object can reference a s_object or none at all, depending on whether the member s_object pointer points to a valid s_object.  All CSPobject-derived classes have a method called IsValid() which allows you to test whether it is pointing to a valid s_object or not.

 

All named objects are created in a permanent frame associated with an S database and are, therefore, persistent between calls and between sessions in the S engine.  When you create a new CSPobject in your client program, a new s_object is created in the S engine.  When you delete this CSPobject, the s_object is also released in the engine.  However, when you execute S syntax to remove the s_object that your CSPobject points to, such as by using ‘rm(myObject)’, or you call the Remove() method on the object, the CSPobject is not deleted in your client.  The OnRemove() method of the CSPobject in your client is called and the base class version of this method “disconnects” your CSPobject from the now released s_object by setting the member s_object pointer to NULL.  After this event, calling IsValid() on the CSPobject will return FALSE.

 

Deleting the CSPobject in your client program does not automatically remove the permanent frame s_object in the S engine that this CSPobject refers to.  You must call the method Remove() to remove the s_object from the engine.

 

You can create named objects using the Create() method of the various object classes derived from CSPobject, such as CSPnumeric.  Whenever these objects are modified, the OnModify() method is called in your client program.  Whenever these objects are removed, the OnRemove() method is called in your client program.  Only named objects support this kind of client program notification.

 

To create a named object in your client, first derive a new class from the appropriate CSPobject-derived class, such as CSPnumeric.  Then, construct an instance of this derived class using the constructor, then call the Create() method to specify the name you wish to give the object.  It is important to derive a new class from the CSPobject-derived class instead of just using the base class directly in your client because the OnModify() and OnRemove() methods are virtual and must be overridden in your derived class in the client in order to be notified when these events occur.

 

A CSPobject can be modified in one of two ways.  It can be modified in the client program by using the operators available for the object to assign and operate on the elements of the object.  When this kind of modification is done, it is necessary to call the Commit() method on the object to commit it to the S engine before any changes to the object are reflected in the persistent s_object that is referenced by the object in the client.  Another way it can be modified is by evaluating S syntax, such as by using CSPengineConnect::SyncParseEval().  When this kind of modification is done, it is not necessary to call Commit() on the object, as the s_object is automatically updated by the S engine.  For both kinds of modification, the OnModify() method of the CSPobject is called in the client program.  It is important to call the base class OnModify() in your override of OnModify().  This allows the base class to update the member s_object pointer to point to the newly modified s_object in the engine.

 

The s_object member of a CSPobject can be removed (invalidated) in one of two ways.  It can be removed in the client program by calling the Remove() method on the CSPobject.  This method removes the s_object from the permanent frame and triggers a call to the OnRemove() method of the CSPobject in the client program.  The base class version of OnRemove(), which should be called at the end of the overridden version in the client, releases the member s_object from the CSPobject.  Another way it can be removed is by executing S syntax, such as by CSPengineConnect::SyncParseEval().  This also triggers a call to the OnRemove() method of the CSPobject  in the client program.

 

For examples of using CSPobject-derived classes in a client program and responding to OnModify() and OnRemove() notifications, see the example C++ client program called SSC installed with the program in the samples subdirectory.

 

Storage frames for unnamed objects

Normally, when you create an unnamed CSPobject in a client routine that you call via .Call, the s_object corresponding to this CSPobject is “alive” or is valid until the routine ends and scope changes out of the routine.  For more information on using CONNECT/C++ in .Call applications, see Using CONNECT/C++ in .Call.

 

If you create an unnamed CSPobject when the S evaluator is not open, the s_object corresponding to this CSPobject may not be valid.  This is usually not adequate for most client applications.  Therefore, you need to do the following to ensure that unnamed CSPobjects created in a client application do not go away until the end of the client routine:

 

-          Create an instance of a CSPevaluator at the top of the scope “{“.

-          Create and use any unnamed CSPobject-derived objects in the client.

For example:

 

{

       CSPevaluator s;

       CSPnumeric x(“1:10”);

      

}

 

For named objects, you do not have to use the above approach:  simply create named CSPobject-derived objects using the constructor and a call to CSPobject::Create().  For further information, see CSPengineConnect::OpenTopLevelEval(), CSPengineConnect::CloseTopLevelEval(), and the Create() method for the object type to be created.

 

Using CONNECT/C++ in .Call

 

CONNECT/C++ can be used as an effective tool for building reasonably efficient .Call interfaces.  The class library reflects the hierarchy of the SV4 class system.  Almost every CONNECT/C++ class mimics an S class defined in the S language.  Such a class encapsulates S data the same way as the internal C structure that represents the S object of an S class.  Many of its public member functions perform the same operations as their corresponding S methods.  Because each class is a wrapper of the structure pointer s_object* used by all .Call interfaces, using CONNECT/C++ inside a .Call interface is easy.

 

NOTE: Only several CONNECT/C++ classes and limited numbers of member functions are available in the current S-PLUS 6.0 release.

An example

 

The S function below implements Gauss-Seidel iterative method for solving a linear system.  The input matrix should be diagonally dominant for its solution to converge. The stronger diagonally dominant is the faster convergent rate.  This sample is also on disk in the S_HOME/samples/GaussSDL directory.

 

gaussSeidel<-

# gaussSeidel solves a linear system using Gauss-Seidel iterative method.

# REQUIRED ARGUMENTS:

#      A and b are numeric matrix and vector respectively.

# VALUE:

#      a vector x, solution of A x = b

#

# Usage:

#  A<-matrix(rnorm(100),nrow=10)

#  diag(A)<-seq(ncol(A),ncol(A)) #Make it diagonally dominant

#  b<-rnorm(ncol(A))

#  sys.time({x1<-gaussSeidel(A,b)})

function(A,b)

{     

       # Hard-coded relative tolerance and max iterations

       tol<-1.0e-4

       maxItr<-1e4

 

       # Validating

       A <- as.matrix(A)

       b <- as.numeric(b)

       if(ncol(A) != length(b))

              stop("ncol(A) != length(b)")

 

       # Begin Gauss-Seidel step 

       x<-b

       for(k in 1:maxItr)

       {

              xOld<-x

              for(i in 1:nrow(A))

              {   

                     s<- A[i,i]*x[i]

                     for(j in 1:ncol(A))

                           s <- s - A[i,j]*x[j]

                     x[i] <- (b[i]+s)/A[i,i]

              }

              # Check convergence; continue if necessary

              if(max(abs((x-xOld)/x)) < tol)

                     return(x);

       }     

       warning("Solution does not converge\n")

       return(x)

}

 

A C++ function using CONNECT/C++ that performs the same task as the above listed S code is implemented as follows:

 

#include "sconnect.h"

#include "gausssdl.h"

 

s_object* gaussSeidel(s_object* ps_A, s_object* ps_b)

/**********************************************************************

gaussSeidel solves a linear system using Gauss-Seidel iterative method.

 

REQUIRED ARGUMENTS:

 ps_A and ps_b are numeric matrix and vector respectively.

 

VALUE:

 a vector x, solution of A x = b

 

S FUNCTION EQUIVALENT: 

 gaussSeidel() defined in gausssdl.ssc

 

Usage:

 A<-matrix(rnorm(100),nrow=10)

 diag(A)<-seq(ncol(A),ncol(A))            # Make it diagonally dominant

 b<-rnorm(ncol(A))

 source('gausssdl.ssc')                   # S version of gaussSeidel

 sys.time({x1<-gaussSeidel(A,b)})         # timing the S version

 sys.time({x2<-.Call('gaussSeidel',A,b)}) # timing the .Call version

 all.equal(x1,x2)                         # Should return T

*********************************************************************/

{    

  S_EVALUATOR

  try

  {

    //Hard-coded relative tolerance and max iterations

    double tol =1e-4;

    long maxItr = 1000;

                    

    //Constructing and validating C++ objects

    CSPmatrix A(ps_A);

    CSPnumeric b(ps_b);

    if(A.ncol() != b.length())

      PROBLEM "A.ncol() != b.length()" ERROR;

             

    //Begin Gauss-Seidel step

    CSPnumeric x=b;

    for(long k =1; k<= maxItr; k++)

    {

      CSPnumeric xOld = x;

      for(long i= 1; i <= A.nrow(); i++)

      {   

        double s = A(i,i) * x(i);

        for(long j = 1; j <= A.ncol(); j++)

          s  = s - A(i,j) * x(j);

        x(i) = (b(i)+s)/A(i,i);

      }

      //Check convergence; continue if necessary

      if(Max(abs((x-xOld)/x)) < tol)

                       return(x);

    }

    PROBLEM "Solution does not converge" WARN;

    return(x);

  }

  catch(...)

  {

  }

  return(blt_in_NULL); //return the build-in NULL object

}

 

 

 


 

CSPengineConnect Overview

The CSPengineConnect class manages a connection between the client and the S engine.  This connection permits creation of persistant objects associated with databases, persistant objects not associated with databases, temporary objects, notification in the client when databases are attached or detached, output routing to the client, parsing, and evaluating S syntax expressions.

 

To use CSPengineConnect, create a new class derived from CSPengineConnect in the client, override the virtual methods for receiving database attach/detach notification, and output notification, and add a member variable to the client application class object to record a reference to a single instance of this derived class.  This class instance will receive notifications and output routing.

 

Only the most recently created instance of the CSPengineConnect-derived class will receive notification in the client.  Multiple instances of CSPengineConnect classes are not supported in client programs.

 

Use of a CSPengineConnect-derived class is only necessary when one of the following features is desired in the client program:

-          Create objects on the permanent frame

-          Create unnamed objects that persist between calls or routines outside of a .Call (see below)

-          Notification in the client when databases are attached or detached

-          Output redirected to the client

 

Evaluation frames for unnamed objects

Normally, when you create an unnamed CSPobject in a client routine that you call via .Call, the s_object corresponding to this CSPobject is “alive” or is valid until the routine ends and scope changes out of the routine.  For more information on using CONNECT/C++ in .Call applications, see Using CONNECT/C++ in .Call.

 

If you create a unnamed CSPobject in a routine outside of a .Call in a client application, the s_object corresponding to this CSPobject is only valid until the constructor returns to the caller.  This is usually not adequate for most client applications.  Therefore, to ensure that unnamed CSPobjects created in a client application do not go away until the end of the client routine, do the following:

 

-          Create an instance of a CSPevaluator at the top of scope “{“.

-          Create any unnamed CSPobject-derived objects in the client.

 

Class Members  |  Hierarchy chart

 

Required includes:

 

#include "spengcon.h"

 

Samples:

 

S_HOME/samples/ssc

 

See Also:

 

Client-To-Engine connection classes

 


CSPengineConnect class members

 

Construction

S syntax evaluation

Objects in permanent frame

Persistent unnamed objects

Output

Notification

 

Construction

 

CSPengineConnect

 

Constructs a CSPengineConnect object in various ways.

 

Create

Creates connection between client and S engine, allowing specification of command line arguments and a dll search list.

 

S syntax evaluation

 

SyncParseEval

Parses and evaluates an expression in S syntax.

 

Objects in permanent frame

 

CreateObject

Creates an S object in a permanent frame and returns a pointer to a s_object pointer.

 

Assign

Assigns an S object and a name for the object to a permanent frame.

 

get

Gets the first occurance of a named S object in the permanant frames.  Returns a pointer to the s_object found.

 

Output

 

ReadStdout

Reads text output sent to stdout by the engine.

 

ReadStderr

Reads text output sent to stderr by the engine.

 

Notification

 

OnAttach

Called when a database is attached.

 

OnDetach

Called when a database is detached.

 

OnOutput

Called when there is output to be displayed in the client as a result of operations or errors from the S engine.

 

CSPengineConnect Overview  |  Hierarchy chart

 


CSPengineConnect::CSPengineConnect

 

CSPengineConnect()

CSPengineConnect(int argc, char* argv[], char *dlllist[])

 

Parameters

 

argc

Number of arguments present in argument list argv[], not including final null.

 

argv

Array of char * to be passed to the S engine as a startup argument list.  Contents of this argument list can consist of the same options that can be passed as the command-line to SQPE.EXE.

 

dlllist

OPTIONAL Array of char * which specifies the list of DLLs to search for symbols as needed by the S engine to resolve calls.  Elements of this list can include dll file names without path or fully qualified dll pathnames.  No wildcards are allowed.

 

Remarks

 

Use the constructor with the argc, argv[], and dlllist[] parameters if you need to create a CSPengineConnect-derived object and initialize the connection at the same time.  Normally, a member of the client application class is used and the Create() method is called later during initialization of the client application.

 

To create an engine connection in the client, derive a class from CSPengineConnect and create a member variable in the client application class to store an instance to this class.  Call the Create() method on this member during the client application initialization routine.  Pass the list of arguments and dlls to Create().  If the client application is based on MFC, do this during the CWinApp::InitInstance() routine in the client.

 

Example

 

// NOTE: Make sure S_HOME environment variable is set

//       before running this example.

 

int argc = 2;

char *argv[2];

 

// argv[0] is always expected to be the client program name

argv[0] = "DocumentSamples.exe";

 

// Get the value of S_HOME from the environment

// argv[1] is set to be the current S_HOME environment setting

if ( !pszSHOMEenv || !*pszSHOMEenv )

       pszSHOMEenv = getenv( "S_HOME" );

if ( pszSHOMEenv )

{

       static char szArg[_MAX_PATH];

       sprintf( szArg, "S_HOME=%s", pszSHOMEenv );

       argv[1] = szArg;

}

 

// Initialize the connection

BOOL bSuccess = m_myEngineConnect.Create(argc, argv);

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

CSPengineConnect::Create()


CSPengineConnect::Create

 

virtual int Create(int argc, char* argv[], char *dlllist[])

 

Return Value

 

1 if successful, 0 if not.

 

Parameters

 

argc

Number of arguments present in argument list argv[], not including final null.

 

argv

Array of char * to be passed to the S engine as a startup argument list.  Contents of this argument list can consist of the same options that can be passed as the command-line to SQPE.EXE.

 

dlllist

OPTIONAL Array of char * which specifies the list of DLLs to search for symbols as needed by the S engine to resolve calls.  Elements of this list can include dll file names without path or fully qualified dll pathnames.  No wildcards are allowed.

 

Remarks

 

Use this method to initialize the client-engine connection.  Normally, a member of the client application class, derived from CSPengineConnect is used and the Create() method is called during initialization of the client application.

 

To create an engine connection in the client, derive a class from CSPengineConnect and create a member variable in the client application class to store an instance to this class.  Call the Create() method on this member during the client application initialization routine.  Pass the list of arguments and dlls to Create().  If the client application is based on MFC, do this during the CWinApp::InitInstance() routine in the client.

 

Example

 

// NOTE: Make sure S_HOME environment variable is set

//       before running this example.

 

int argc = 2;

char *argv[2];

 

// argv[0] is always expected to be the client program name

argv[0] = "DocumentSamples.exe";

argv[1] = "S_HOME=d:\\spluswin";

 

// Initialize the connection

BOOL bSuccess = m_myEngineConnect.Create(argc, argv);

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 


CSPengineConnect::SyncParseEval

 

int SyncParseEval(const char *pszExpression)

 

Return Value

 

1 if successful, 0 if not.

 

Parameters

 

pszExpression

Any valid S syntax.  If reserved characters are used in this expression string, they must be escaped properly, following C conventions.

 

 

Remarks

 

Use this method to parse and evaluate any valid S syntax and synchronize persistant objects with databases.  This method calls the Print method on the returned object from the evaluation to generate output which gets routed to the client application if the appropriate notification handler methods are overridden in the client CSPengineConnect-derived class.

 

This method may generate an exception in the client program if the S syntax in pszExpression results in an execution error.

 

Example

 

BOOL bSuccess = FALSE;

try

{

       char pszExpression[] =

            "assign( 'myVar',c('item1','item2'),immediate=T,where=1 )";

      bSuccess = m_myEngineConnect.SyncParseEval( pszExpression );

       if ( !bSuccess )

       {

              // Print error in the client program

       }

}

catch(...)

{

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

CSPengineConnect::CSPengineConnect()

 


CSPengineConnect::CreateObject

 

virtual s_object* CreateObject(

const char* pszClass,         // class name

          const char* pszName,         // object name

          const char* pszExpression = NULL,

long lDataBase = 1 )           // database

 

Return Value

 

Returns a pointer to the permanent frame object created if successful.  Returns NULL on failures.

 

Parameters

 

pszClass

Any valid S class name, such as ‘numeric’, ‘character’, etc.

 

pszName

Name of the object to create.

 

pszExpression

Optional S syntax to evaluate and assign the result of to the newly created object.

 

lDataBase

Database position to assign the newly created object to.

 

Remarks

 

Use this method to create a named object on a permanent frame.

 

Once created, the object will receive notification in the client, provided the CSPobject-derived class notification handlers are implemented in the client.

 

Example

 

The following example creates a new ‘numeric’ object named ‘MyNumeric’ on the permanent frame in database position 1 and initializes it to the sequence from 1 to 10, where CSPmyNumeric is a client class derived from CSPnumeric:

 

CSPmyNumeric myNumeric;

 

try

{

       myNumeric = m_myEngineConnect.CreateObject(

              "numeric",

              "MyNumeric",

              "1:10" );

}

catch(...)

{

       // Display exception error

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

CSPengineConnect::CSPengineConnect(), CSPengineConnect::Assign(), CSPengineConnect::get()

 


CSPengineConnect::Assign

 

virtual void Assign(

const char* pszName,         // object name

const CSPobject& spObject, // object to assign

long lDataBase = 1 );

 

Return Value

 

Generates an exception in the client upon failure.

 

Parameters

 

pszName

Name of the object to assign.

 

spObject

A reference to a CSPobject that is to be assigned to a permanent frame.

 

lDataBase

Database position to assign the object to.

 

Remarks

 

Assigns the CSPobject specified to a permanent frame in a database position using the object name specified.  You would normally use this method after you created an unnamed object using a CSPobject constructor in order to assign the object to a permanent frame and to give the object a name.

 

Once assigned, the object will receive notification in the client, provided the CSPobject-derived class notification handlers are implemented in the client.

 

Example

 

The following example creates a new unnamed ‘numeric’ object and initializes it to the sequence from 1 to 10.  Then a call to Assign() is made to name this object and assign it to a permanent frame in database position 1.  Note: CSPmyNumeric is a client class derived from CSPnumeric so notification will occur in the client when the object is modified:

 

CSPmyNumeric myNumeric( "1:10" );

try

{

       m_myEngineConnect.Assign(

              "MyNumeric",

              myNumeric );

}

catch(...)

{

       // Display exception error

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

CSPengineConnect::CSPengineConnect(), CSPengineConnect::CreateObject(), CSPengineConnect::get()

 


CSPengineConnect::get

 

virtual s_object * get(

const char* pszName );      // object name

 

Return Value

 

Returns the first occurrence of an object with the name specified, or NULL if not found or on errors.

 

Parameters

 

pszName

Name of the object to find in the permanent frames.

 

Remarks

 

Gets an object whose name is specified.  This method has the same semantics as the S function “get”.  This method will return only the first occurrence of an object with the name specified, if multiple objects exist.  The search order is the same as the S database search list.

 

Once assigned to a new CSPobject-derived object, the object will receive notification in the client, provided the CSPobject-derived class notification handlers are implemented in the client.

 

Example

 

The following example creates a new CSPmyNumeric object.  Then a call to Find() is made to find a numeric object by the name of ‘MyNumeric’.  If found, it is copied to the CSPmyNumeric object so notification will occur in the client.  Note: CSPmyNumeric is a client class derived from CSPnumeric so notification will occur in the client when the object is modified:

 

CSPmyNumeric myNumericFound;

CSPmyNumeric myNumeric;

 

try

{

       myNumeric = m_myEngineConnect.CreateObject(

              "numeric",

              "MyNumeric",

              "1:10" );

 

       myNumericFound = m_myEngineConnect.get( "MyNumeric" );

}

catch(...)

{

       // Display exception error

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

CSPengineConnect::CSPengineConnect(), CSPengineConnect::CreateObject(), CSPengineConnect::Assign()

 

 


CSPengineConnect::ReadStdout

 

virtual BOOL ReadStdout(

                   char* pszBuffer,          // output data buffer

                   long  nBufferSize         // size of data buffer

  )

 

Return Value

 

Returns TRUE if there are more text to be read else FALSE.

 

Parameters

 

pszBuffer

Buffers to receive the text character output.

 

nBufferSize

Maximum length of (char*) in the first argument.

 

 

 

Remarks

 

Read text output printed to stdout by the S engine.  This method allows the client to get a stream of output from the S engine and display it in response to notification that output is available.

 

Example

 

The following example shows how to read text output sent by the S engine to the stdout.

 

const long kMaxLen = 4888;

char szBuffer[kMaxLen];

try

{

       //Print some text

       m_myEngineConnect.SyncParseEval("print('Hello\n')");

 

       // Read text sent from the engine to the standard out

       m_myEngineConnect.ReadStdout(szBuffer, kMaxLen);

 

}

catch(...)

{

}

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 

CSPengineConnect::CSPengineConnect(), CSPengineConnect::ReadStderr(), CSPengineConnect::OnOutput()


CSPengineConnect::ReadStderr

 

virtual BOOL ReadStderr(

                   char* pszBuffer,          // output data buffer

                   long  nBufferSize         // size of data buffer

  )

 

Return Value

 

Returns TRUE if there are more text to be read else FALSE.

 

Parameters

 

pszBuffer

Buffers to receive the text character output.

 

nBufferSize

Maximum length of (char*) in the first argument.

 

 

Remarks

 

Read text output printed to stderr by the S engine.  This method allows the client to get a stream of output from the S engine and display it in response to notification that output is available.

 

Example

 

The following example shows how to read text output sent by the S engine to the stderr.

 

const long kMaxLen = 4888;

char szBuffer[kMaxLen];

 

try

{

       //Generate an error

       m_myEngineConnect.SyncParseEval("stop('This is an error')");

}

 

catch(...)

{

}

 

// Read text sent from the engine to the standard error

m_myEngineConnect.ReadStderr(szBuffer, kMaxLen);

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 

CSPengineConnect::CSPengineConnect(), CSPengineConnect::ReadStdout(), CSPengineConnect::OnOutput()

 


CSPengineConnect::OnAttach

 

virtual int OnAttach( s_object* ps_attached );

 

Parameters

 

ps_attached

An s_object pointer of class “attached” which represents the attached database.

 

 

Return Value

 

Return a 1 in your override of this method to indicate that the notification was successfully processed.  Otherwise return 0 on failure.

 

Remarks

 

To use this notification handler, derive a class from CSPengineConnect in the client program, and override the OnAttach() method in this class.

 

This method is called whenever a database is attached.  The attached database information is passed to the client in the ps_attached parameter as a pointer to an s_object of class “attached”.

 

Example

 

The following example shows the OnAttach() notification handler overridden in a CSPengineConnect-derived class called CMyEngineConnect in a client application.  This handler will be called whenever a database is attached:

 

int CSPmyEngineConnect::OnAttach(s_object* ps_attached)

{

       // Perform any client operations here, such as printing

       // out a notification in the client program

       PRINT_ON_ATTACH( ps_attached );

      

      return 1;

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 

CSPengineConnect::CSPengineConnect(), CSPengineConnect::OnDetach(), CSPengineConnect::OnOutput()

 


CSPengineConnect::OnDetach

 

virtual int OnDetach( s_object* ps_attached );

 

Parameters

 

ps_attached

An s_object pointer of class “attached” which represents the detached database.

 

 

Return Value

 

Return a 1 in your override of this method to indicate that the notification was successfully processed.  Otherwise return 0 on failure.

 

Remarks

 

To use this notification handler, derive a class from CSPengineConnect in the client program, and override the OnDetach() method in this class.

 

This method is called whenever a database is detached.  The detached database information is passed to the client in the ps_attached parameter as a pointer to an s_object of class “attached”.

 

Example

 

The following example shows the OnDetach() notification handler overridden in a CSPengineConnect-derived class called CMyEngineConnect in a client application.  This handler will be called whenever a database is attached:

 

int CSPmyEngineConnect::OnDetach(s_object* ps_attached)

{

       // Perform any client operations here, such as printing

       // out a notification in the client program

       PRINT_ON_DETACH( ps_attached );

 

       return 1;

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 

CSPengineConnect::CSPengineConnect(), CSPengineConnect::OnAttach(), CSPengineConnect::OnOutput()

 


CSPengineConnect::OnOutput

 

virtual int OnOutput( void );

 

Return Value

 

Return a 1 in your override of this method to indicate that the notification was successfully processed.  Otherwise return 0 on failure.

 

Remarks

 

To use this notification handler, derive a class from CSPengineConnect in the client program, and override the OnOutput() method in this class.

 

This method is called whenever output (errors or normal output) is available from operations in the S engine.  In this handler, the client can get a handle to the S engine standard output and error channels and then read text on these channels and display it appropriately.

 

Example

 

The following example shows the OnOutput() notification handler overridden in a CSPengineConnect-derived class called CMyEngineConnect in a client application.  This handler will be called whenever output is available:

 

#include "stdafx.h"

#include "spl.h"

#include "myengcon.h"

 

#include "mainfrm.h"

#include "txstring.h"

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CMyEngineConnect::CMyEngineConnect()

       : CSPengineConnect()

{

}

 

CMyEngineConnect::CMyEngineConnect(int argc, char *argv[], char *dlllist[])

       : CSPengineConnect(argc, argv, dlllist)

{

}

 

CMyEngineConnect::~CMyEngineConnect()

{

}

 

int CMyEngineConnect::OnAttach( s_object* ps_attached)

{

       // Get db name and position

 

       CSPattached spAttached(ps_attached);

       CSPcharacter spDBName = spAttached.GetDatabaseName();

       long lPosition = spAttached.GetPosition();

 

       // Format message to display

       CTxString sMsg;

       sMsg.Format( "Attaching %s at position %d\r\n", (const char *)spDBName[0], lPosition );

 

       TRACE( sMsg );

 

       // Display message in output pane of application

       AppendToOutputPane( sMsg );

 

       return 1;

}

 

int CMyEngineConnect::OnDetach( s_object* ps_attached)

{

       // Get db name and position

 

       CSPattached spAttached(ps_attached);

       CSPcharacter spDBName = spAttached.GetDatabaseName();

       long lPosition = spAttached.GetPosition();

 

       // Format message to display

       CTxString sMsg;

       sMsg.Format( "Detaching %s at position %d\r\n", (const char *)spDBName[0], lPosition );

 

       TRACE( sMsg );

 

       // Display message in output pane of application

       AppendToOutputPane( sMsg );

 

       return 1;

}

 

int CMyEngineConnect::OnOutput( void )

{

       const long kMaxLen = 4888;

       char szTextOutputBuffer[kMaxLen];

       CTxString strText;

 

       try

       {

              // Read text sent from the engine to the standard out

              while(ReadStdout(szTextOutputBuffer, kMaxLen))

              {

                     strText.Unix2Dos(szTextOutputBuffer);

                     TRACE( "In CMyEngineConnect::OnOutput() with output: '%s'\n", (const char *)strText );      

                     AppendToOutputPane(strText); // Display message in output pane of window

              }

                          

              // Read text sent from the engine to the standard err

              while(ReadStdout(szTextOutputBuffer, kMaxLen))

              {

                     strText.Unix2Dos(szTextOutputBuffer);

                     TRACE( "In CMyEngineConnect::OnOutput() with error: '%s'\n", (const char *)strText );                    

                     AppendToOutputPane(strText); // Display message in output pane window

              }              

       }

       catch(...)

       {

                     strText.Format("PROBLEM reading standard out/err");

                     TRACE( "In CMyEngineConnect::OnOutput() with error: '%s'\n", (const char *)strText );

       }

 

       return 1;

}

 

CSPengineConnect Overview  |  Class Members  |  Hierarchy chart

 

See Also

 

CSPengineConnect::CSPengineConnect(), CSPengineConnect::OnAttach(), CSPengineConnect::OnDetach(), CSPengineConnect::ReadStdout(), CSPengineConnect::ReadStderr()

 


CSPevaluator Overview

The CSPevaluator class manages memory resources, errors and the top-evaluation frame.  Although it is optional, instantiating an object of CSPevalutor class at the top of a try block can speedup the code, and the corresponding catch block will receive an exception error when unexpected error occurs in the S engine. 

 

To use CSPevaluator, create an instance of this class at the top of a try block.  Then create objects as necessary.

 

Class Members  |  Hierarchy chart

 

Required includes:

 

#include "speval.h"

 

Samples:

 

 

See Also:

 

Client-To-Engine connection classes


CSPevaluator class members

 

Construction

CSPevaluator

Constructs a CSPevaluator object in various ways.

 

S syntax evaluation

eval

Parses and evaluates an expression in S syntax.

 

Top-level-evaluator

Open

Opens the top-level-evaluator if it is not open yet.

 

Close

Closes the top-level-evaluator.

 

IsOpen

Returns TRUE if the top-level-evaluator is open.

 

Other methods

allEqual

Comparing contents of two S objects.

 

CSPevalutor Overview  | Hierarchy chart


CSPevaluator::CSPevaluator

 

CSPevalutor()

 

Remarks

 

Use the default constructor in a try-block to ensure that the top-level-evaluation frame is open.  If the top-level-evaluation frame were not open yet, the default constructor would open it.  Then, if there is a server error in the engine an exception is thrown.  Your catch block should receive a exception object.  If there is no server error, the object of class CSPevaluator will close the top-level-evaluation frame when it desctructor is called. 

 

All S objects, created during the lifetime of a CSPevaluator object, are local objects by default.  These local objects are destroyed automatically when the CSPevaluator object is going out scope.  However, any global C++ object of class CSPobject attached to a local S object will automatically be re-attached to a global S object cloned from the local one.  This is automatically done when the local CSPevaluator object is going out of scope.

 

Example

 

The following example demonstrates the use of CSPevaluator::CSPevaluator()

 

CSPnumeric snPerm ;

 

try

{

       CSPevaluator s; //open top-level-evaluator by default

       CSPnumeric snLocal("c(1,2,3)");

       snPerm = snLocal;

}

catch(...)

{

}

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

 

CSPevaluator::Open(), CSPevaluator::Close(), CSPevaluator::IsOpen()

 


CSPevaluator::eval

 

s_object* eval(const char *pszExpression)

 

Return Value

 

S object result of evaluating the S expression.

 

Parameters

 

pszExpression

Any valid S syntax.  If reserved characters are used in this expression string, they must be escaped properly, following C conventions.

 

 

Remarks

 

Use this method to parse and evaluate any valid S syntax. 

 

This method may generate an exception in the client program if the S syntax in pszExpression results in an execution error.

 

Example

 

The following example demonstrates the use of CSPevaluator::eval()

 

CSPcharacter scharPerm ;

 

try

{

       CSPevaluator s; //open top-level-evaluator by default

       CSPcharacter sobjLocal = s.eval("'hello3'");

       scharPerm = sobjLocal;

}

catch(...)

{

}

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

CSPengineConnect::SyncParseEval(), CSPcall::Eval()

 


CSPevaluator::Open

 

BOOL Open()

 

Return Value

 

Returns TRUE if it opens the top-level-evaluator successfully else FALSE.

 

Remarks

 

This method opens the top-level-evaluation frame if it is not already open.  If the top-level-evaluator were already open, you can use this method to ensure a return of program control to a local block during a severed error occurred in the S engine.  The S engine (C code) performs a long jump when there is a severed error, CSPevaluator::Open() turns the long jump to an exception error in C++.

 

Example

 

The following example demonstrates the use of CSPevaluator::Open()

 

int nTest = 0;

 

CSPevaluator sEvaluator;   //Open top-level-evalutor

try

{

       sEvaluator.Open();         //Ensure no long jump out of this try block.

       sEvaluator.eval("stop()"); //exception will be thrown because of "stop()".

       nTest = -1;

 

}

catch(CSPexception& e)

{

       e.Print();

       nTest = 1;

}

catch(...)

{

}

//Here nTest == 1

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

 

CSPevaluator::Close(), CSPevaluator::IsOpen()

 


CSPevaluator::Close

 

BOOL Close()

 

Return Value

 

Returns TRUE if it closes the top-level-evaluator successfully else FALSE.

 

Remarks

 

This method closes the top-level-evaluation frame if it is currently open.  It will update all global C++ objects of class CSPobject to re-attach to global S objects cloned from the local ones if needed.

 

Example

 

The following example demonstrates the use of CSPevaluator::Close()

 

int nTest = 0;

 

try

{

       //open the top-level-evaluator if it is not open yet.

       CSPevaluator sEvaluator;

 

       //do some long evaluation of S expressions.

 

       sEvaluator.Close(); //Close the top-level-evaluator and cleanup memory.

       sEvaluator.Open();  //Re-open the top-level-evaluator.

 

       //do some more long evaluation of S expressions.

 

       nTest = 1;

}

catch(CSPexception& e)

{

       e.Print();

}

catch(...)

{

}

//Here nTest == 1

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

 

CSPevaluator::Open(), CSPevaluator::IsOpen()

 


CSPevaluator::IsOpen

 

BOOL IsOpen()

 

Return Value

 

Returns TRUE if top-level-evaluation frame is currently open else FALSE.

 

Remarks

 

This method tests if the top-level-evaluation frame is currently open.

 

Example

 

The following example demonstrates the use of CSPevaluator::IsOpen()

 

int nTest = 0;

 

try

{

       //open the top-level-evaluator if it is not open yet.

       CSPevaluator sEvaluator;

 

       //do some long evaluation of S expressions.

 

       sEvaluator.Close(); //Close the top-level-evaluator and cleanup memory.

       sEvaluator.Open();  //Re-open the top-level-evaluator.

 

       //do some more long evaluation of S expressions.

 

       nTest = 1;

}

catch(CSPexception& e)

{

       e.Print();

}

catch(...)

{

}

//Here nTest == 1

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

 

CSPevaluator::Open(), CSPevaluator::Close()


CSPevaluator::allEqual

 

BOOL allEqual(s_object* ps_ object1, s_object* ps_ object2)

BOOL allEqual(CSPobject sObject1, CSPobject sObject2)

 

Return Value

 

Return TRUE if the contents of the two objects are equal.

 

Parameters

 

ps_object1, ps_object2

Pointers to S objects

 

sObject1, sObject2

Objects of class CSPobject or the derived class of CSPobject

 

 

Remarks

 

Use this method to compare contents of two S objects.  This method is based on the S function “all.qual”.

 

Example

 

The following example demonstrates the use of CSPevaluator::eval()

 

int nTest=0;

try

{

       //open top-level-evaluator if it is not open yet.

       CSPevaluator sEvaluator;

 

       //Create the first object from an S expression

       CSPnumeric sobj1("1:3");

      

       //Create the second object from a double array

       double x[3]={1.0, 2.0, 3.0};

       CSPnumeric sobj2(x, 3);

 

       //Compare contents

       nTest = sEvaluator.allEqual(sobj1, sobj2) ? 1 : -1;

}

catch(...)

{

}

 

//Here nTest == 1

 

CSPevaluator Overview  | Class Members  | Hierarchy chart

 

See Also

CSPengineConnect::SyncParseEval(), CSPcall::Eval()

 


CSPnumeric Overview

The CSPnumeric class is similar to the ‘numeric’ class object in the S engine – it is a vector of doubles.  This class supports zero-based and one-based (Fortran style) indexing into the vector using various bracket operators on the left-hand and right-hand sides of the equation.

 

To use CSPnumeric, create an instance of a CSPnumeric class, and then use the bracket operators to set or get data.

 

To support notification in the client when the object is modified or removed, create a class in the client which is derived from CSPnumeric.  Override the OnModify() and OnRemove() notification methods in this class.  To use the CSPnumeric-derived class in the client, create an instance of this derived class.  Then call the Create() method to specify a name for the new object.  Finally, use the bracket operators to set or get data at specific locations in the vector, or use the assignment operator to copy vectors between different CSPnumeric objects.  After any modifications to the object in the client program, call the Commit() method to commit these changes to the S engine object pointed to by this CSPnumeric-derived object.  To remove the S engine object pointed to by this object, call the Remove() method.

 

Class Members  |  Hierarchy chart

 

Required includes:

 

#include "spnum.h"

 

Samples:

 

See Also:

 

CSPcharacter class overview, CSPinteger class overview, Client-To-Engine connection classes

 


CSPnumeric class members

 

Construction

Attributes

Operators

Arithmetic

Notification

 

Construction

 

CSPnumeric

 

Constructs a CSPnumeric object in various ways.

 

Create

Creates a named ‘numeric’ object in the S engine.

 

IsValid

Determines if the s_object that this object represents is valid.

 

Attributes

 

GetObjectName

Returns a string representing the object name.

 

length

Returns the number of elements in the vector.

 

SetAtDirect

Sets an element(s) directly into the vector without committing to the S database.

 

Operators

 

operator =

Assign one CSPnumeric to another by attaching the s_object member pointer and incrementing the reference count by 1.

 

operator []

Zero-based (C style) indexing for left-hand or right-hand side indexing into the vector.

 

operator ()

One-based (Fortran style) indexing for left-hand or right-hand side indexing into the vector.

 

operator +

Adds the elements of two CSPnumeric objects to create a new CSPnumeric object.

 

operator -

Subtracts the elements of two CSPnumeric objects to create a new CSPnumeric object.

 

operator *

Multiplies the elements of two CSPnumeric objects to create a new CSPnumeric object.

 

operator /

Divides the elements of two CSPnumeric objects to create a new CSPnumeric object.

 

Arithmetic

 

abs

Returns the absolute value of the elements of the vector.

 

Min

Returns the minimum value of all the elements of the vector.

 

Max

Returns the maximum value of all the elements of the vector.

 

Notification

 

Commit

Commits the modified object to the database.

 

Remove

Removes the object from the database.

 

OnModify

Called when the object is modified.

 

OnRemove

Called when the object is removed.

 

 

CSPNumeric Overview  |  Hierarchy chart


CSPnumeric:: CSPnumeric

 

CSPnumeric(long lLength)

CSPnumeric(double* pdValues, long lLength)

 

Parameters

 

lLength

Vector length.

 

pdValues

Pointer to an existing array of double.

 

 

Remarks

 

Use the constructor with the ‘lLength’ parameter if you need to create a CSPnumeric object and initialize it with length ‘lLength’.

 

Use the constructor with ‘pdValues’ and ‘lLength’ parameters if you need to create a CSPnumeric object and initialize it with data pointed by pdValues with length specified by lLength.

 

Example

 

The following example demonstrates the use of CSPnumeric::CSPnumeric(lLength)

 

int nTest=0;

try

{

       //open top-level-evaluator if it is not open yet.

       CSPevaluator sEvaluator;

 

       //Create an S object from an S expression

       CSPnumeric sobj1("numeric(3)");

      

       //Create an S object of length 3

       CSPnumeric sobj2(3L);

 

       //Compare contents

       nTest = sEvaluator.allEqual(sobj1, sobj2) ? 1 : -1;

}

catch(...)

{

}

//Here nTest == 1

 

The following example demonstrates the use of CSPnumeric::CSPnumeric(pdValues, lLength)

 

int nTest=0;

try

{

       //open top-level-evaluator if it is not open yet.

       CSPevaluator sEvaluator;

 

       //Create an S object from an S expression

       CSPnumeric sobj1("1:3");

      

       //Create an S object of length 3 from an array of double

       double pdValues[3]={1.0, 2.0, 3.0};

       CSPnumeric sobj2(pdValues, 3);

 

       //Compare contents

       nTest = sEvaluator.allEqual(sobj1, sobj2) ? 1 : -1;

}

catch(...)

{

}

//Here nTest == 1

 

CSPNumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create()

 


CSPnumeric::Create

 

virtual BOOL Create(

          const char* pszName = NULL,        // object name

          const char* pszExpression = NULL, // expression to initialize data

          long lDataBase = 1 )                     // database position

 

Parameters

 

pszName

Name of the object to create.

 

pszExpression

Optional S syntax to evaluate and assign the result of to the newly created object.

 

lDataBase

Database position to assign the newly created object to.

 

Return Value

 

Returns TRUE if object was successfully created, or FALSE if not.

 

Remarks

 

First construct a CSPnumeric object.  Then, use this method to create a named object and initialize it if needed with the result of an expression evaluation.

 

To support notification in the client when the object is modified or removed, create a class in the client which is derived from CSPnumeric.  Override the OnModify() and OnRemove() notification methods in this class.  To use the CSPnumeric-derived class in the client, create an instance of this derived class.  Then call the Create() method to specify a name for the new object.

 

Example

 

In the following example, a new CSPnumeric-derived class instance is created and the Create() method is called to name and initialize the object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::CSPnumeric()


CSPnumeric::IsValid

 

BOOL IsValid(void) const

 

Return Value

 

Returns TRUE if the s_object member is valid, or FALSE if not.

 

Remarks

 

Every CSPobject-derived object contains a member s_object pointer that the CSPobject represents in the client program.  This member can become invalid if the s_object is removed from the S engine, or it is detached from the CSPobject.  This method allows the client program to tell whether the member is valid or not.

 

Example

 

In the following example, a new CSPnumeric-derived class instance is created and the Create() method is called to name and initialize the object.  IsValid() is called and it returns TRUE.  Then the s_object is removed using the Remove() method.  IsValid() is called again and it returns FALSE.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

// Check whether the s_object is valid (it is)

BOOL bIsValidBefore = myNumeric.IsValid();

if ( bIsValidBefore == FALSE )

{

       // Print error in the client

}

 

// Remove this object from the S engine database.

// After this call, the CSPmyNumeric::OnRemove()

// method will be called in this client program.

if ( !myNumeric.Remove() )

{

       // Print error in client

}

 

// Check whether the s_object is valid (it is NOT)

BOOL bIsValidAfter = myNumeric.IsValid();

if ( bIsValidAfter == TRUE )

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::CSPnumeric(), CSPnumeric::Create(), CSPnumeric::Remove()

 

 


CSPnumeric::operator =

 

const CSPnumeric& operator = (const CSPnumeric& sobject)

 

Remarks

 

This operator will generate an exception in the client upon assignment failure or failure to coerce the right-hand side CSPnumeric object to a ‘numeric’ S engine type.

 

The assignment operator decrements the reference count on the s_object that the left-hand side CSPnumeric object represents.  Then it attaches the s_object of the right-hand side CSPnumeric object to the left-hand side CSPnumeric object.  The reference count of the s_object is incremented by 1 during this assignment.

 

Example

 

In the following example, a new CSPnumeric-derived class instance is created and the Create() method is called to name and initialize the object.  Then another CSPmyNumeric object is created and the first is assigned to the second.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( NULL, "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

try

{

       myNumeric2 = myNumeric;

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator ()

 


CSPnumeric::operator []

 

virtual double operator [] (int n)

 

Remarks

 

This operator will generate an exception in the client if the index is out of range or the s_object represented by the CSPnumeric object is invalid.

 

You can think of a CSPnumeric object as an array of doubles.  The overloaded subscript [] operator returns a single double specified by the zero-based index in n.  This operator can also be used to assign a double to a particular index in the array.

 

The major difference between this operator and the () operator, is that this operator is zero-based, the other is one-based.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the [] operator is used to get a double from one and assign it into an index in the other.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "11:20", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

try

{

       // Copy fourth double from 'myNumeric' to

       // second position in 'myNumeric2'

       myNumeric2[1] = myNumeric[3];

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator (), CSPnumeric::operator =, CSPnumeric::SetAtDirect()

 


CSPnumeric::operator ()

 

virtual double operator () (long n)

 

Remarks

 

This operator will generate an exception in the client if the index is out of range or the s_object represented by the CSPnumeric object is invalid.

 

You can think of a CSPnumeric object as an array of doubles.  The overloaded subscript () operator returns a single double specified by the one-based index in n.  This operator can also be used to assign a double to a particular index in the array.

 

The major difference between this operator and the [] operator, is that this operator is one-based, the other is zero-based.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the () operator is used to get a double from one and assign it into an index in the other.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "11:20", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

try

{

       // Copy third double from 'myNumeric' to

       // first position in 'myNumeric2'

       myNumeric2(1) = myNumeric(3);

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::SetAtDirect()

 


CSPnumeric::operator +

 

CSPnumeric CSPnumeric::operator+(const CSPnumeric& sRhs)

 

Remarks

 

This operator will generate an exception in the client if either the left-hand side or right-hand side CSPnumeric object is invalid.

 

This operator clones the left-hand side object and iterates through each element up to the last index of the shortest object.  For each element, the operator adds the right-hand side element to the left-hand side element.  The cloned object with the result of this operator on each element is returned.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the + operator is used to add the two (element-by-element) and assign the result to a third object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "11:20", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "1:10", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

// Add each element of 'myNumeric2' to

// each element of 'myNumeric'

CSPmyNumeric myNumeric3 = myNumeric + myNumeric2;

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::operator -, CSPnumeric::operator *, CSPnumeric::operator /

 


CSPnumeric::operator -

 

CSPnumeric CSPnumeric::operator-(const CSPnumeric& sRhs)

 

Remarks

 

This operator will generate an exception in the client if either the left-hand side or right-hand side CSPnumeric object is invalid.

 

This operator clones the left-hand side object and iterates through each element up to the last index of the shortest object.  For each element, the operator subtracts the right-hand side element to the left-hand side element.  The cloned object with the result of this operator on each element is returned.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the - operator is used to subtract the two (element-by-element) and assign the result to a third object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "11:20", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "1:10", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

// Subtract each element of 'myNumeric2' from

// each element of 'myNumeric'

CSPmyNumeric myNumeric3 = myNumeric - myNumeric2;

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::operator +, CSPnumeric::operator *, CSPnumeric::operator /

 


CSPnumeric::operator *

 

CSPnumeric CSPnumeric::operator*(const CSPnumeric& sRhs)

 

Remarks

 

This operator will generate an exception in the client if either the left-hand side or right-hand side CSPnumeric object is invalid.

 

This operator clones the left-hand side object and iterates through each element up to the last index of the shortest object.  For each element, the operator multiplies the left-hand side element by the right-hand side element.  The cloned object with the result of this operator on each element is returned.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the * operator is used to multiply the two (element-by-element) and assign the result to a third object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "11:20", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "1:10", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

// Multiply each element of 'myNumeric' by

// each element of 'myNumeric2'

CSPmyNumeric myNumeric3 = myNumeric * myNumeric2;

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::operator +, CSPnumeric::operator -, CSPnumeric::operator /

 


CSPnumeric::operator /

 

CSPnumeric CSPnumeric::operator/(const CSPnumeric& sRhs)

 

Remarks

 

This operator will generate an exception in the client if either the left-hand side or right-hand side CSPnumeric object is invalid.

 

This operator clones the left-hand side object and iterates through each element up to the last index of the shortest object.  For each element, the operator divides the left-hand side element by the right-hand side element.  The cloned object with the result of this operator on each element is returned.

 

Example

 

In the following example, two CSPnumeric-derived class instances are created and the Create() method is called to name and initialize each.  Then the / operator is used to divide the two (element-by-element) and assign the result to a third object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "11:20", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

CSPmyNumeric myNumeric2;

if ( myNumeric2.Create( "1:10", "MyNumeric2" ) != TRUE )

{

       // Print error in the client

}

 

// Divide each element of 'myNumeric' by

// each element of 'myNumeric2'

CSPmyNumeric myNumeric3 = myNumeric / myNumeric2;

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::operator +, CSPnumeric::operator -, CSPnumeric::operator *

 


CSPnumeric::abs

 

CSPnumeric abs( BOOL bValidate=TRUE ) const

 

Parameters

 

bValidate

If TRUE, will check whether this object is valid and generate an exception if not.  Validity check can be slow, so specify FALSE if the object is known to be valid.

 

Return Value

 

Returns a CSPnumeric object representing the absolute value of each element in this object.

 

Remarks

 

This operator will generate an exception in the client if this CSPnumeric object is invalid.

 

This operator clones this object and iterates through each element.  For each element, the operator sets the absolute value.  The cloned object with the result of this operator on each element is returned.

 

Example

 

In the following example, a CSPnumeric-derived class instances is created and the Create() method is called to name and initialize each.  Then the abs() method is used to return the absolute values in a third object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "-10:-1", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

// Take absolute value of each element in 'myNumeric'

// and return in new CSPmyNumeric object

CSPmyNumeric myNumeric2 = myNumeric.abs();

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::operator [], CSPnumeric::operator =, CSPnumeric::operator +, CSPnumeric::operator -, CSPnumeric::operator *, CSPnumeric::operator /

 


CSPnumeric::Min

 

double Min( BOOL bValidate = TRUE ) const

 

Parameters

 

bValidate

If TRUE, will check whether this object is valid and generate an exception if not.  Validity check can be slow, so specify FALSE if the object is known to be valid.

 

Return Value

 

Returns a double representing the minimum value of all the elements in this object.

 

Remarks

 

This operator will generate an exception in the client if this CSPnumeric object is invalid.

 

Example

 

In the following example, a CSPnumeric-derived class instances is created and the Create() method is called to name and initialize each.  Then the Min() method is used to return the minimum value in a double.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

double minValue = 0;

try

{

       // Return the minimum element of myNumeric

       minValue = myNumeric.Min();

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::Max()


CSPnumeric::Max

 

double Max( BOOL bValidate = TRUE ) const

 

Parameters

 

bValidate

If TRUE, will check whether this object is valid and generate an exception if not.  Validity check can be slow, so specify FALSE if the object is known to be valid.

 

Return Value

 

Returns a double representing the maximum value of all the elements in this object.

 

Remarks

 

This operator will generate an exception in the client if this CSPnumeric object is invalid.

 

Example

 

In the following example, a CSPnumeric-derived class instances is created and the Create() method is called to name and initialize each.  Then the Max() method is used to return the maximum value in the vector.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

double maxValue = 0;

try

{

       // Return the maximum element of myNumeric

       maxValue = myNumeric.Max();

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create(), CSPnumeric::Min()


CSPnumeric::GetObjectName

 

virtual const char* GetObjectName(void) const

 

Return Value

 

Returns a string representing the name of this object.

 

Remarks

 

This function will return NULL if the object is invalid or has no name.

 

Example

 

In the following example, a CSPnumeric-derived class instance is created and the Create() method is called to name and initialize it.  Then the GetObjectName() method is used to return the name of the object.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

char *pszName = NULL;

try

{

       // Get the name of myNumeric

       //

       // NOTE: Make a copy of the char * returned

       // by GetObjectName() before modifying it.

       pszName = (char *)myNumeric.GetObjectName();

       if ( !pszName || !*pszName )

              throw "Failed";

 

       // Print out pszName in the client

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

CSPnumeric::Create()


CSPnumeric::length

 

long length( BOOL bValidate = TRUE ) const

 

Parameters

 

bValidate

If TRUE, will check whether this object is valid and generate an exception if not.  Validity check can be slow, so specify FALSE if the object is known to be valid.

 

Return Value

 

Returns a long representing the number of elements in this object.

 

Remarks

 

This operator will generate an exception in the client if this CSPnumeric object is invalid.

 

Example

 

In the following example, a CSPnumeric-derived class instance is created and the Create() method is called to name and initialize it.  Then the length() method is used to return the number of elements in the vector.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create("1:10", "MyNumeric" ) != TRUE )

{

       // Print error in the client

}

 

long theLength = 0;

try

{

       // Return the length of myNumeric

       theLength = myNumeric.length();

       if ( theLength != 10 )

              throw "Failed";

}

catch(...)

{

       // Print error in the client

}

 

CSPnumeric Overview |  Class Members  |  Hierarchy chart

 

See Also

 

CSPnumeric::Create()


CSPnumeric::SetAtDirect

 

void SetAtDirect(int nIndex, double dElement, BOOL bValidate=TRUE);

void SetAtDirect(double* pdValues, long lStartIndex, long lEndIndex,

BOOL bValidate=TRUE);

 

Parameters

 

nIndex

The zero-based index to set the value at in the vector.

 

dElement

The double value to set.

 

bValidate

If TRUE, will check whether this object is valid and generate an exception if not.  Validity check can be slow, so specify FALSE if the object is known to be valid.

 

pdValues

An array of double values to set which MUST be at least as long as (lEndIndex-lStartIndex+1).

 

lStartIndex

The starting index in the vector (zero-based) to begin setting elements from the array pdValues.

 

lEndIndex

The ending index in the vector (zero-based) to stop setting elements from the array pdValues.

 

Remarks

 

This method will generate an exception in the client if lStartValue or lEndIndex are invalid indicies for the CSPnumeric it is called on.  The CSPnumeric you call this method on must be at least long as (lEndIndex-lStartIndex+1).

 

This method will set the value(s) specified by dElement or the array pdValues into the CSPnumeric vector you call it on.  If you specify an array of doubles (pdValues), this array must be at least as long as (lEndIndex-lStartIndex+1).

 

The method directly sets values in the vector of the CSPnumeric.  It changes the memory associated with the vector elements, but it does not commit the changed elements to the S database.  You must call Commit() to commit the changed values to the CSPnumeric vector in the S database.

 

Example

 

In the following example, a new CSPnumeric-derived class instance is created and the Create() method is called to name and initialize the object.  Then elements are set using the two forms of SetAtDirect.  The class CSPmyNumeric is implemented in the client and derived from CSPnumeric.

 

CSPmyNumeric myNumeric;

if ( myNumeric.Create( "1:10", "MyNumeric" ) != TRUE )

{

      // Print error in the client

}

 

double newValue = 66;

double newArray[] = { 77, 88, 99 };

try

{

      // Modify one of the values in the vector directly

      myNumeric.SetAtDirect( 2, newValue );

 

      // Modify a range of elements in the vector with

      // the values of the array 'newArray'.

      myNumeric.SetAtDirect( newArray, 6, 8 );

 

      // Commit this object to database one. After this

      // call, the CSPmyNumeric::OnModify() method will be

      // called in this client program.

      myNumeric.Commit();

}

catch(...)

{

      // Print error in the client

}