/[ascend]/trunk/models/test/blackbox/bboxtest.c
ViewVC logotype

Annotation of /trunk/models/test/blackbox/bboxtest.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1045 - (hide annotations) (download) (as text)
Fri Jan 5 06:46:08 2007 UTC (15 years, 7 months ago) by johnpye
File MIME type: text/x-csrc
File size: 8370 byte(s)
fixing ERROR_REPORTER to ERROR_REPORTER_HERE.
1 johnpye 1032 /* ASCEND modelling environment
2     Copyright (C) 2006 Carnegie Mellon University
3    
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2, or (at your option)
7     any later version.
8    
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     GNU General Public License for more details.
13    
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place - Suite 330,
17     Boston, MA 02111-1307, USA.
18     *//**
19     @file
20     black box semantics test.
21     *//*
22     by Ben Allan
23     Created: July 4, 2006
24     Version: $Revision: 1.5 $
25     Date last modified: $Date: 1997/07/18 12:20:07 $
26     */
27    
28     #include <utilities/ascConfig.h>
29 johnpye 1035 #include <utilities/ascMalloc.h>
30 johnpye 1032 #include <compiler/compiler.h>
31     #include <compiler/packages.h>
32     #include <compiler/instance_enum.h>
33     #include <utilities/ascPanic.h>
34     /* next 4 needed only because we use RealAtomValue on the DATA instance. */
35     #include <compiler/fractions.h>
36     #include <compiler/dimen.h>
37     #include <compiler/atomvalue.h>
38     #include <compiler/instquery.h>
39 johnpye 1039
40 johnpye 1032 #include <compiler/extcall.h>
41    
42 johnpye 1039 /* #define BBOXTEST_DEBUG */
43 johnpye 1032
44 johnpye 1039 ExtBBoxInitFunc bboxtest_preslv;
45     ExtBBoxFunc bboxtest_fex;
46     ExtBBoxFunc bboxtest_jex;
47     ExtBBoxFinalFunc bboxtest_final;
48     #define N_INPUT_ARGS 1 /* formal arg count */
49     #define N_OUTPUT_ARGS 1 /* formal arg count */
50 johnpye 1032
51 johnpye 1039 extern
52     ASC_EXPORT(int) bboxtest_register(void){
53     double epsilon = 1.0e-14;
54 johnpye 1032
55 johnpye 1039 char bboxtest_help[] = "This tests a simple black box y=k*x."
56     " The value 'k' is provided to the blackbox as a data argument.";
57 johnpye 1032
58 johnpye 1039 return CreateUserFunctionBlackBox("bboxtest"
59     ,&bboxtest_preslv
60     ,&bboxtest_fex, &bboxtest_jex
61     ,NULL, &bboxtest_final
62     ,N_INPUT_ARGS, N_OUTPUT_ARGS
63     ,bboxtest_help
64     ,epsilon
65     );
66     }
67 johnpye 1032
68 johnpye 1039 /*------------------------------------------------------------------------------
69     forward decls
70     */
71    
72 johnpye 1032 struct BBOXTEST_problem {
73     double coef; /* coef in y=coef*x*/
74     int n; /* number of equations. */
75     };
76    
77 johnpye 1039 static int GetCoef( struct Instance *data, struct BBOXTEST_problem *problem);
78    
79     static int CheckArgsOK(struct Instance *data
80     ,struct gl_list_t *arglist, struct BBOXTEST_problem *problem
81     );
82    
83     static int DoCalculation(struct BBoxInterp *interp
84     ,int ninputs, int noutputs
85     ,double *inputs, double *outputs
86     );
87    
88     int DoDeriv(struct BBoxInterp *interp, int ninputs, double *jacobian);
89    
90     #ifndef EXTERNAL_EPSILON
91     #define EXTERNAL_EPSILON 1.0e-12
92     #endif
93    
94 johnpye 1032 /*----------------------------------------------------------------------------*/
95    
96 johnpye 1039 /**
97     This function is one of the registered functions. It operates in
98     mode 'last_call'.
99    
100     In 'last_call' mode, the memory associated with the problem is
101     released.
102     */
103     void bboxtest_final(struct BBoxInterp *interp){
104     struct BBOXTEST_problem *problem;
105    
106     if(interp->task != bb_last_call){
107     ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unexpected call to last_call fn");
108     return;
109     }
110    
111     if(interp->user_data != NULL) {
112     problem = (struct BBOXTEST_problem *)interp->user_data;
113     problem->coef *= -1;
114     problem->n *= -1;
115     ASC_FREE(problem);
116     interp->user_data = NULL;
117     }
118     }
119     /**
120     This function is one of the registered functions. It operates in
121     mode first_call.
122     It creates a BBOXTEST_problem and calls a number of routines to check
123     the arguments (data and arglist) and to cache the information
124     processed away in the BBOXTEST_problem structure.
125    
126     In last_call mode, the memory associated with the problem is
127     released.
128    
129     @return 0 on success
130     */
131     int bboxtest_preslv(struct BBoxInterp *interp,
132     struct Instance *data,
133     struct gl_list_t *arglist
134    
135     ){
136     struct BBOXTEST_problem *problem;
137    
138     if(interp->task != bb_first_call){
139 johnpye 1045 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unexpected call to first_call fn");
140 johnpye 1039 return -1;
141     }
142    
143     if(interp->user_data!=NULL){
144     #ifdef BBOXTEST_DEBUG
145     CONSOLE_DEBUG("user_data has already been allocated, no need to reallocate");
146     #endif
147     return 0;
148     }
149    
150     problem = ASC_NEW(struct BBOXTEST_problem);
151     if(CheckArgsOK(data,arglist,problem)){
152     CONSOLE_DEBUG("Problem with arguments");
153     ASC_FREE(problem);
154     return -2;
155     }
156    
157     /* store the BBTEST_problem in the user_data pointer */
158     interp->user_data = (void *)problem;
159     return 0; /* success */
160     }
161    
162     /*----------------------------------------------------------------------------*/
163    
164     /**
165     Evaluate residuals
166    
167     @return 0 on success
168     */
169     int bboxtest_fex(struct BBoxInterp *interp,
170     int ninputs,
171     int noutputs,
172     double *inputs,
173     double *outputs,
174     double *jacobian
175     ){
176     (void)jacobian;
177     return DoCalculation(interp, ninputs, noutputs, inputs, outputs);
178     }
179    
180     /*
181     Evaluate jacobian
182     @return 0 on success
183     */
184     int bboxtest_jex(struct BBoxInterp *interp,
185     int ninputs,
186     int noutputs,
187     double *inputs,
188     double *outputs,
189     double *jacobian
190     ){
191     (void)noutputs;
192     (void)outputs;
193     (void)inputs;
194    
195     return DoDeriv(interp, ninputs, jacobian);
196     }
197    
198     /*------------------------------------------------------------------------------
199     utility routines
200     */
201    
202 johnpye 1032 static int GetCoef( struct Instance *data, struct BBOXTEST_problem *problem){
203    
204 johnpye 1035 if(!data){
205 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"expecting a data instance to be provided");
206 johnpye 1035 return 5;
207 johnpye 1032 }
208 johnpye 1035 if(InstanceKind(data)!=REAL_CONSTANT_INST) {
209 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"expecting a real constant instance.");
210 johnpye 1035 return 6;
211 johnpye 1032 }
212    
213     problem->coef = RealAtomValue(data);
214     return 0;
215     }
216    
217     static int CheckArgsOK(struct Instance *data,
218     struct gl_list_t *arglist,
219     struct BBOXTEST_problem *problem
220     ){
221     unsigned long len,ninputs,noutputs;
222    
223     if (!arglist) {
224 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"External function argument list does not exist.");
225 johnpye 1032 return 1;
226     }
227     len = gl_length(arglist);
228     if (!len) {
229 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"No arguments to external function statement.");
230 johnpye 1035 return 2;
231 johnpye 1032 }
232     if ((len!=(N_INPUT_ARGS+N_OUTPUT_ARGS))) {
233 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Number of arguments does not match"
234     " the external function"
235     " prototype(array_of_realatom[set],array_of_realatom[set],real_constant"
236     );
237 johnpye 1035 return 3;
238 johnpye 1032 }
239    
240     ninputs = CountNumberOfArgs(arglist,1,N_INPUT_ARGS);
241     noutputs = CountNumberOfArgs(arglist,N_INPUT_ARGS+1,
242     N_INPUT_ARGS+N_OUTPUT_ARGS);
243     if (ninputs != noutputs) {
244 johnpye 1034 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Length of input, output arguments mismatched.");
245 johnpye 1035 return 4;
246 johnpye 1032 }
247    
248     problem->n = (int)ninputs;
249    
250 johnpye 1035 return GetCoef(data,problem); /* get the coef, return 0 on success means all was ok */
251 johnpye 1032 }
252    
253     /*
254     This function provides support to bboxtest_fex which is one of the
255     registered functions. The input variables are x[set]
256     The output variables are y[set]. We do our loop
257     based on the ascend standard that sets are arbitrarily but
258     consistently ordered if they contain the same values.
259     */
260    
261     static int DoCalculation(struct BBoxInterp *interp,
262     int ninputs, int noutputs,
263     double *inputs,
264     double *outputs
265     ){
266     struct BBOXTEST_problem *problem;
267     int c;
268     double coef;
269    
270 johnpye 1034 if(ninputs != noutputs){
271     ERROR_REPORTER_HERE(ASC_PROG_ERR,"ninputs != noutputs");
272     return -1;
273     }
274 johnpye 1035 if(interp->user_data == NULL){
275     ERROR_REPORTER_HERE(ASC_PROG_ERR,"user_data not supplied");
276     return -2;
277     }
278 johnpye 1032 problem = (struct BBOXTEST_problem *)interp->user_data;
279     coef = problem->coef;
280    
281     for (c=0; c < ninputs; c++) {
282     outputs[c] = coef * inputs[c];
283     }
284    
285     #ifdef BBOXTEST_DEBUG
286 johnpye 1034 CONSOLE_DEBUG("instance = %p",interp->user_data);
287 johnpye 1032 for(c=0;c<ninputs;c++) {
288 johnpye 1034 CONSOLE_DEBUG("x[%d] = %12.8g",c,inputs[c]);
289 johnpye 1032 }
290     for (c=0;c<noutputs;c++) {
291 johnpye 1034 CONSOLE_DEBUG("y[%d] = %20.8g",c,outputs[c]);
292 johnpye 1032 }
293     #endif /* BBOXTEST_DEBUG */
294    
295     interp->status = calc_all_ok;
296     return 0;
297     }
298    
299 johnpye 1039 int DoDeriv(struct BBoxInterp *interp, int ninputs, double *jacobian){
300 johnpye 1032 int i; int len;
301     double coef;
302 johnpye 1034 if(interp==NULL){
303     ERROR_REPORTER_HERE(ASC_PROG_ERR,"interp==NULL");
304     return -1;
305     }
306     if(interp->user_data==NULL){
307     ERROR_REPORTER_HERE(ASC_PROG_ERR,"interp->user_data==NULL");
308     return -2;
309     }
310 johnpye 1032 coef = ((struct BBOXTEST_problem *)interp->user_data)->coef;
311     len = ninputs*ninputs;
312    
313     #ifdef BBOXTEST_DEBUG
314 johnpye 1034 CONSOLE_DEBUG("instance = %p",interp->user_data);
315 johnpye 1032 #endif
316     for (i = 0; i< len; i++) {
317     jacobian[i] = 0;
318     }
319    
320     for (i = 0; i< ninputs; i++) {
321     jacobian[i*ninputs+i] = coef;
322     }
323     #ifdef BBOXTEST_DEBUG
324     for(i=0; i<len; i++) {
325 johnpye 1034 CONSOLE_DEBUG("J[%d] = %12.8g", i, jacobian[i]);
326 johnpye 1032 }
327     #endif
328     return 0;
329     }

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22