Use the ConnectC ++ module to interact with C ++ in S-Plus

xiaoxiao2021-03-13  203

Introduction

Connect / C is an interface tool that interacts with S-language and C . It provides the convenience of using C to integrate the SPLUS engine in it, and it can also integrate C code into the SPLUS environment.

In order to allow inter-GUI and SPLUS communication, Connect / C is developed to provide such a frame (based on S statement version 4). In fact, the SPLUS7 GUI provides more comprehensive examples of using the Connect / C integrated SPLUS engine and C applications. Similarly, C developers can also use the same technique to interact with SPLUS

Connect / C is a C class library that uses these classes and their members to create and handle most local S objects.

In order to calculate the S expression in the C program and module, Connect / C provides a flexible mechanism that provides many examples of using these class libraries in Splus7.x, where some examples provide an equivalent to perform the same task. The S and C functions, where the C function is mostly running faster than the S code, of course, this also depends on the complexity of the code and the size of the data. These examples You can find in the Shome / Sconnect directory, where Shome is your SPLus installation directory.

Resource

For more information on Connect / C , see the SPlus7.0 Connect / C library help, if you reap, check the Shome / Connect / Help / ConnectC .class.library.htm file. This HTML file is a C Developer Guide for a Connect / C class library. It carefully discusses how to connect to the SPLUS engine, how to create data objects, call the SPLUS function and execute Splus syntax

Simple example: a simple application execution process

Connect / C is mainly used to achieve these two goals: establish a C app that can access the SPLUS function; create a C function that can be called by SPLUS, let's start a simple application

Establish a simple application

This example is a console program to create 2 SPLUS vectors in the app, then use splus to establish a linear model about these two vector.

This code starts a line containing a sconnect.h file, which is necessary, all CONECT / C code must reference this file. Then define a global SPLUS connection object, this class's name is CSPENGINECONNECT, which must be defined before the Motor function, which generates a connection between the customer application and the SPLUS, which will allow you to create a splus object, and as a database Notifications are issued when they are attached or unloaded to their customers, and S-language expressions can also be performed. The code looks like the following:

#include "sconnect.h"

// a Global Connection Object

CSPENGINECONNECT G_EngineConnect;

Int main (int Argc, char * argv [])

{

The first step of the main function is to create an actual connection object (connected to SPLUS)

// Create The Connection to S-PLUS

g_ENGINECONNECT.CREATE (ARGC, ARGV);

Then we build variables x, y, this cspnumeric is used to store digital vectors. This class is a class in CONNECT / C , which is used in C to represent objects in splus, and there are also many C classes corresponding to atomic objects in SPLUS (see Table 7.1); next to pass Establish an instance of this class using the CREATE method, assign this class to the SPLUS database through the Assign method, as follows // Create S Object with name "x" in the current data.

// Same AS x <-1: 10 at the command line. CSPNUMERIC SX;

SX.CREATE ("1:10", "x");

// Squaring SX, Which is The Same As S Expression

// Sy <- x * x in a Local frame, But Here We set it to local

// c variable sy. Cspnumeric sy = sx * sx;

// Assign the result as s Object with name "y" in the

// Current Database. Sy.assign ("y");

Finally, we prepare the right linear model, call SPLUS execution when the Connect / C method is appropriate, as follows

// Evaluate Z <-LM (Y ~ X)

g_ENGINECONNECT.SYNCPARSEEVAL ("Z <-LM (Y ~ X)");

Return 1;

}

The full code of this example is in Shome / Samples / SPLLM (WIN), this directory under the SHOM E / SCONNECT / SAMPLES / SPLM.

To run this app, open a command prompt or MS-DOS window (WIN) or compile (UNIX)

1. Change the current directory to the directory containing the code

CD Shome / Samples / SPLLM

(Win)

CD / SCONNECT / SAMPLES / SPLM

(UNIX, assume that the current path is Shome)

2. Compiler

MSDEV SPLLM.DSP / MAKE

(Win)

Splus7 chapter -sconnectapp * .cxx

Splus7 make

(UNIX)

3. If you check the environment variable PATH to confirm that it contains% shom e% / cmd, if not, you should add it before running the following steps.

4. Operating the program

SPLLM.EXE S_PROJ =.

(Win)

Splus7 exec S.App

(UNIX)

To verify the results, start the SPLUS Console (WIN) or start SPLUS (UNIX) in the same directory

SQPE.EXE S_PROJ =.

On the WIN platform, SPLUs will return to the following information

S-Plus: Copyright (C) 1988, 2005 Insightful Corp. Version 7.0 Release 1 for Microsoft Windows: 2005Working Data Will Be in E: /PROGRAMS/SPLUS7.0/USERS/rich

Or input

Splus7

On UNXI, you will return the following information:

S-Plus: Copyright (C) 1988, 2005 Insightful Corp. Version 7.0 Release 1 for Sun SPARC, SunOS 5.8: 2005

Working Data Will Be in .data

Then view the object x, y, and z:

[1]

1

2

3

4

> Y

[1]

1

4

9

16

>

x

5 6 7 8 9 10

25 36 49 64 81 100

> Z

Call:

LM (Formula = Y ~ X)

Coefficients:

(Intercept) x

-22 11

Degrees of freedom: 10 Total; 8 Residual

Residual Standard Error: 8.124038

An example of calling C functions through CALL

Gauss-SeiDel is a familiar technology that is used in a resolution of linear regression systems. This algorithm is very easy to achieve in SPLUS, as follows

Gaussseidel <-

# Gaussseidel Solves a Linear System Using Gauss-SEIDEL

# ItERATIVE METHOD.

# Required Arguments:

# A and b is numeric Matrix and Vector respective.

# Value:

# A vector x, soliion 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 ity itys tol <-1.0e-4

MaxiTR <-1E4

# Validating

A <- as.matrix (a)

B <- as.numeric (b)

IF (ncol (a)! = ncol (a) || ncol (a)! = length (b))

STOP ("nrow (a)! = ncol (a) || 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 (X-xold) / x))

Return (x);

}

Warning ("Solution Does Not Converge / N")

Return (x)

}

In this code, a nesting loop may be written to a more efficient code, but we are just a demonstration. By using the CONNECT / C classes and methods, the following code implements the above similar functions.

These codes have a SCONNECT.H header file, so we can access the Sconnect / C library, the next step, which contains a header file that implements Gauss-SeiDel

# Include "sconnect.h"

# Include "gaussdl.h"

When we define the GaussseiDel object as an object of the S_Object class, it requests to interact with CALL

S_Object * Gaussseidel (S_Object * ps_a, s_object * ps_b)

As a typical code, we define S_EVALUATOR. Then embed our implementation code in the TRY-CATCH block, in the TRY block, the error that may happen can be captured. Below the following code

{

S_EVALUATOR

Try

{

// Hard-Coded Relative Tolerance and max iterations Double Tol = 1e-4;

Long Maxitr = 1000;

// constructing and validating C Objects

CSPNUMERICMATRIX A (PS_A); CSPNUMERIC B (PS_B);

IF (a.nrow ()! = a.ncol () || a.ncol ()! = B.Length ())

Problem "a.nrow ()! = A.ncol () || a.ncol ()! = B.LENGTH ()" Error;

The actual Gauss-SeiDel step is as follows:

// Begin Gauss-SeiDel Step

CSPNUMERIC X = B;

For (long k = 1; k <= maxi; k )

{

CSPNUMERIC XOLD = X;

For (long i = 1; i <= a.nrow (); i )

{

Double S = a (i, i) * x (i);

For (long (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 (X-Xold) / x))

Return (x);

}

Problem "Solution Does Not Converge" WARN

Return (x);

}

Catch (...)

{

}

Return (BLT_IN_NULL); // Return The Built-in Null Object

}

Compile and execute C on UNXI

This example code is under Shom E / Sconnect / Samples / Gaussdl, C code in Gaussdl.cxx

Compile and execute C code

1. Change the current directory to the directory containing the code

CD Shome / Sconnect / Samples / Gausssdl

2. Compile shared library

Splus7 chapter -sconnectlib * .cxx

Splus7 make

3. Run SPLUS

Splus7

Generate makefile through Chapter, compiled code just needs to add the make command after SPLUS, as step 2

Set an environment variable properly before MAKE

The Make tool performs the necessary command to compile and connect C code to the shared object S.so

Note: -sconnectlib is requested to include the Connect / C library

Call CONNECT / C is fast than SPLUS code, below is a comparison, running in Pentium 3 512 memory, Win platform, matrix A is 100 rows 100 rows

> A <-mtrix (RNORM (10000), NROW = 100); DIAG (a) <- SEQ (Ncol (a),

Ncol (a)) # make it diagonally Dominant

> B <-RNORM (100);

> Sys.time ({x1 <-gaussseidel (a, b)})

[1] 19.328 19.354

Below is a comparison running on the Solaris machine, the matrix is ​​also 100 columns 100 lines.

[1] 37.00 39.35

> Sys.time ({x2 <-. Call ('Gaussseidel', A, B)})

We compare (via sys.time) output from different platforms:

[1] 0.07 0.07

Win

[1] 0.04 0.04

T.

It can be seen that the same CONNECT / C version is 250 times faster than WIN, and it is more than 1000 times higher than the pure SPLUS version.

转载请注明原文地址:https://www.9cbs.com/read-128995.html

New Post(0)