/* ASCEND modelling environment Copyright (C) 2006 Carnegie Mellon University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *//** @file Code to support testing of certain function logic. As usual, the test code is itself incorrect. The only place this stuff is being called is from interface.c, which is out of date. */ #include #include /* was compiler/actype.h */ #include #include #ifndef ASC_DEFAULT_ASCENDLIBRARY # error "Where is ASC_DEFAULT_ASCENDLIBRARY???" #endif #include #include #include #include #include "symtab.h" #include "functype.h" #include "expr_types.h" #include "extcall.h" #include "mathinst.h" #include "instance_enum.h" #include "instquery.h" #include "atomvalue.h" #include "find.h" #include "rel_blackbox.h" #include "vlist.h" #include "relation.h" #include "safe.h" #include "relation_util.h" #include "extfunc.h" #include #include #include "module.h" #include "packages.h" int something_for_packtest_to_compile =1; #ifdef TEST_RELOCATE /*--------------------------------------- TESTING FUNCTIONS The following functions may be called someone desirous of testing an external relation provided as a package. */ /** What's this do? -- JP */ static void LoadInputVector(struct gl_list_t *arglist, double *inputs, unsigned ninputs, unsigned long n_input_args) { struct Instance *inst; struct gl_list_t *input_list; unsigned long c,len; input_list = LinearizeArgList(arglist,1,n_input_args); if(!input_list)return; len = gl_length(input_list); if(len!=ninputs)return; /* somehow we had inconsistent data */ for (c=1;c<=len;c++) { inst = (struct Instance *)gl_fetch(input_list,c); inputs[c-1] = RealAtomValue(inst); } gl_destroy(input_list); } /** What's a black box, and what's a glass box? -- JP See Abbott thesis. - baa This function is, of course, a mess. */ int CallBlackBox(struct Instance *inst, CONST struct relation *rel) { struct Instance *data; struct BBoxInterp interp; struct ExternalFunc *efunc; struct ExtCallNode *ext; struct gl_list_t *arglist; unsigned long n_input_args, n_output_args; int nok = 0; unsigned long ninputs, noutputs; double *inputs = NULL, *outputs = NULL; double *jacobian = NULL; ExtBBoxInitFunc *init_func; ExtBBoxInitFunc *final_func; ExtBBoxFunc *eval_func; ExtBBoxFunc *deriv_func; UNUSED_PARAMETER(inst); ext = BlackBoxExtCall(rel); arglist = ExternalCallArgList(ext); data = ExternalCallDataInstance(ext); efunc = ExternalCallExtFunc(ext); init_func = GetInitFunc(efunc); final_func = GetFinalFunc(efunc); eval_func = GetValueFunc(efunc); deriv_func = GetDerivFunc(efunc); if (init_func && eval_func) { /* set up the interpreter. */ Init_BBoxInterp(&interp); #if 0 interp.nodestamp = ExternalCallNodeStamp(ext); #endif n_input_args = NumberInputArgs(efunc); n_output_args = NumberOutputArgs(efunc); ninputs = CountNumberOfArgs(arglist,1,n_input_args); noutputs = CountNumberOfArgs(arglist,n_input_args + 1, n_input_args+n_output_args); /* Create the work vectors. Load the input vector from the instance tree. */ inputs = ASC_NEW_ARRAY_CLEAR(double,ninputs); outputs = ASC_NEW_ARRAY_CLEAR(double,ninputs); jacobian = (double *)asccalloc(ninputs*noutputs,sizeof(double)); LoadInputVector(arglist,inputs,ninputs,n_input_args); /* * Call the init function. */ interp.task = bb_first_call; nok = (*init_func)(&interp,data,arglist); if (nok) goto error; /* * Call the evaluation function. */ interp.task = bb_func_eval; nok = (*eval_func)(&interp,ninputs,noutputs, inputs,outputs,jacobian); if (nok) goto error; /* * Call the derivative routine. */ if (deriv_func) { interp.task = bb_deriv_eval; nok = (*deriv_func)(&interp,ninputs,noutputs, inputs,outputs,jacobian); if (nok) goto error; } /* * Call the init function to shut down */ if (final_func) { interp.task = bb_last_call; nok = (*final_func)(&interp,data,arglist); if (nok) goto error; } } else{ FPRINTF(ASCERR,"External function not loaded\n"); return 1; } error: if (inputs) ascfree((char *)inputs); if (outputs) ascfree((char *)outputs); if (jacobian) ascfree((char *)outputs); if (nok) return 1; else return 0; } #if 0 /** When glassbox are registered, they must register a pointer to their function jump table. In other words, they must register a pointer to an 'array of pointers to functions'. This typedef just makes life a little cleaner. <-- what typedef?? -- JP */ int CallGlassBox(struct Instance *relinst, CONST struct relation *rel) { CONST struct gl_list_t *incidence; struct Instance *var; struct ExternalFunc *efunc; int index; long i; double *f, *x, *g; int m,mode,result; int n; ExtEvalFunc **evaltable, *eval_func; ExtEvalFunc **derivtable, *deriv_func; (void) relinst; incidence = RelationVarList(rel); if (!incidence) { FPRINTF(ASCERR,"Incidence list is empty -- nothing to evaluate\n"); return 0; } index = GlassBoxRelIndex(rel); efunc = GlassBoxExtFunc(rel); evaltable = GetValueJumpTable(efunc); eval_func = evaltable[index]; derivtable = GetDerivJumpTable(efunc); deriv_func = derivtable[index]; m = 0; /* FIX not sure what this should be !!! */ n = gl_length(incidence); f = (double *)asccalloc((1 + 2*n),sizeof(double)); x = &f[1]; g = &f[n+1]; for (i=0;i