1 |
#include <utilities/ascConfig.h> |
2 |
#include <compiler/compiler.h> |
3 |
#include <compiler/packages.h> |
4 |
#include <compiler/instance_enum.h> |
5 |
#include <compiler/fractions.h> |
6 |
#include <compiler/dimen.h> |
7 |
#include <compiler/expr_types.h> |
8 |
#include <general/list.h> |
9 |
#include <compiler/sets.h> |
10 |
|
11 |
#include <compiler/atomvalue.h> |
12 |
#include <compiler/instquery.h> |
13 |
#include <compiler/extcall.h> |
14 |
#include "bisect.h" |
15 |
|
16 |
static int CheckArgTypes(struct gl_list_t *branch){ |
17 |
struct Instance *i; |
18 |
enum inst_t kind; |
19 |
unsigned long len,c; |
20 |
|
21 |
len = gl_length(branch); |
22 |
if (!len) |
23 |
return 1; |
24 |
for (c=1;c<=len;c++) { |
25 |
i = (struct Instance *)gl_fetch(branch,c); |
26 |
if (i) { |
27 |
kind = InstanceKind(i); |
28 |
if ((kind!=REAL_ATOM_INST)&&(kind!=REAL_INST)) { |
29 |
FPRINTF(stderr,"Incorrect types of arguements given\n"); |
30 |
return 1; |
31 |
} |
32 |
} else { |
33 |
FPRINTF(stderr,"NULL arguements given\n"); |
34 |
return 1; |
35 |
} |
36 |
} |
37 |
return 0; /* all should be ok */ |
38 |
} |
39 |
|
40 |
static int CheckArgVector(struct gl_list_t *branch){ |
41 |
if (!branch) { |
42 |
FPRINTF(stderr,"Empty arglists given\n"); |
43 |
return 1; |
44 |
} |
45 |
if (CheckArgTypes(branch)) |
46 |
return 1; |
47 |
return 0; |
48 |
} |
49 |
|
50 |
/** |
51 |
This function expects 3 arguements; the calling protocol |
52 |
from ASCEND it expects to be invoked as: |
53 |
|
54 |
set_values(x1:array of generic_reals, |
55 |
x2:array of generic_reals, |
56 |
m: generic_real); |
57 |
|
58 |
The dimension of both x1, and x2 are expected to be the same; |
59 |
|
60 |
*/ |
61 |
static int CheckArgs_SetValues(struct gl_list_t *arglist){ |
62 |
struct gl_list_t *branch; |
63 |
unsigned long len, dim1, dim2; |
64 |
char *error_msg = "all ok"; |
65 |
|
66 |
if (!arglist) { |
67 |
error_msg = "No arguement list given"; |
68 |
goto error; |
69 |
} |
70 |
len = gl_length(arglist); |
71 |
if (len!=3) { |
72 |
error_msg = "Incorrect # args given, 3 were expected"; |
73 |
goto error; |
74 |
} |
75 |
|
76 |
branch = (struct gl_list_t *)gl_fetch(arglist,1); |
77 |
if (CheckArgVector(branch)) |
78 |
return 1; |
79 |
dim1 = gl_length(branch); |
80 |
|
81 |
branch = (struct gl_list_t *)gl_fetch(arglist,2); |
82 |
if (CheckArgVector(branch)) |
83 |
return 1; |
84 |
dim2 = gl_length(branch); |
85 |
|
86 |
if (dim1!=dim2) { |
87 |
error_msg = "Inconsistent dimensions for the input vectors"; |
88 |
goto error; |
89 |
} |
90 |
|
91 |
/* check the multiplying term. |
92 |
*/ |
93 |
branch = (struct gl_list_t *)gl_fetch(arglist,3); |
94 |
if (!branch) { |
95 |
error_msg = "No multiplier term given"; |
96 |
goto error; |
97 |
} |
98 |
|
99 |
dim2 = gl_length(branch); |
100 |
if (dim2!=1) { |
101 |
error_msg = "A single multiplying term was expected; more than 1 given"; |
102 |
goto error; |
103 |
} |
104 |
return 0; /* if here all should be ok */ |
105 |
|
106 |
error: |
107 |
FPRINTF(stderr,"%s\n",error_msg); |
108 |
return 1; |
109 |
} |
110 |
|
111 |
|
112 |
int do_set_values_eval( struct Instance *i, struct gl_list_t *arglist, void *userdata){ |
113 |
unsigned long dimension,c; |
114 |
struct gl_list_t *inputs, *outputs, *branch; |
115 |
double value,multiplier,calculated; |
116 |
int result; |
117 |
|
118 |
result = CheckArgs_SetValues(arglist); |
119 |
if (result) |
120 |
return 1; |
121 |
inputs = (struct gl_list_t *)gl_fetch(arglist,1); |
122 |
outputs = (struct gl_list_t *)gl_fetch(arglist,2); |
123 |
dimension = gl_length(inputs); |
124 |
branch = (struct gl_list_t *)gl_fetch(arglist,3); |
125 |
multiplier = RealAtomValue(gl_fetch(branch,1)); |
126 |
|
127 |
for (c=1;c<=dimension;c++) { |
128 |
value = RealAtomValue(gl_fetch(inputs,c)); |
129 |
i = (struct Instance *)gl_fetch(outputs,c); |
130 |
calculated = value*multiplier; |
131 |
SetRealAtomValue(i,calculated,(unsigned)0); |
132 |
FPRINTF(stdout,"value %g, multiplier %g, newvalue %g\n", |
133 |
value, multiplier,calculated); |
134 |
} |
135 |
return 0; |
136 |
} |
137 |
|
138 |
|
139 |
/** |
140 |
This function expects 3 arguements; the calling protocol |
141 |
from ASCEND it expects to be invoked as: |
142 |
|
143 |
set_values(x1:array of generic_reals, |
144 |
x2:array of generic_reals, |
145 |
y:array of generic_reals); |
146 |
|
147 |
The dimension of x1, x2 and y are expected to be the same; |
148 |
|
149 |
*/ |
150 |
static int CheckArgs_Bisection(struct gl_list_t *arglist){ |
151 |
struct gl_list_t *branch; |
152 |
unsigned long len,c; |
153 |
unsigned long dim1=0, dim2=0; |
154 |
char *error_msg = "all ok"; |
155 |
|
156 |
if (!arglist) { |
157 |
error_msg = "No arguement list given"; |
158 |
goto error; |
159 |
} |
160 |
len = gl_length(arglist); |
161 |
if (len!=3) { |
162 |
error_msg = "Incorrect # args given, 3 were expected"; |
163 |
goto error; |
164 |
} |
165 |
|
166 |
for (c=1;c<=len;c++) { |
167 |
branch = (struct gl_list_t *)gl_fetch(arglist,c); |
168 |
if (CheckArgVector(branch)) |
169 |
return 1; |
170 |
if (dim1==0) { /* get the dimension of the first vector */ |
171 |
dim1 = dim2 = gl_length(branch); |
172 |
} else { |
173 |
dim2 = gl_length(branch); |
174 |
if (dim1!=dim2) { |
175 |
error_msg = "Inconsistent dimensions given"; |
176 |
goto error; |
177 |
} |
178 |
} |
179 |
} |
180 |
return 0; |
181 |
|
182 |
error: |
183 |
FPRINTF(stderr,"%s\n",error_msg); |
184 |
return 1; |
185 |
} |
186 |
|
187 |
int do_bisection_eval( struct Instance *i, struct gl_list_t *arglist, void *userdata){ |
188 |
unsigned long dimension,c; |
189 |
struct gl_list_t *vector1, *vector2, *outputs; |
190 |
double value1, value2, calculated; |
191 |
int result; |
192 |
|
193 |
result = CheckArgs_Bisection(arglist); |
194 |
if (result) |
195 |
return 1; |
196 |
vector1 = (struct gl_list_t *)gl_fetch(arglist,1); |
197 |
vector2 = (struct gl_list_t *)gl_fetch(arglist,2); |
198 |
outputs = (struct gl_list_t *)gl_fetch(arglist,3); |
199 |
dimension = gl_length(vector1); /* get the dimension of the vectors */ |
200 |
|
201 |
for (c=1;c<=dimension;c++) { |
202 |
value1 = RealAtomValue(gl_fetch(vector1,c)); |
203 |
value2 = RealAtomValue(gl_fetch(vector2,c)); |
204 |
i = (struct Instance *)gl_fetch(outputs,c); |
205 |
calculated = (value1 + value2)/2.0; |
206 |
SetRealAtomValue(i,calculated,(unsigned)0); |
207 |
} |
208 |
return 0; |
209 |
} |
210 |
|
211 |
int Bisection (void){ |
212 |
|
213 |
char set_values_help[] = |
214 |
"This function accepts 3 args, The first 2 arg vectors of equal\n" |
215 |
"length. The second is a multiplier to be applied to each element\n" |
216 |
"of the first vector to yield the second vector.\n" |
217 |
"Example: do_set_values(x[1..n], y[1..n], multiplier[1..n]).\n"; |
218 |
|
219 |
char bisection_help[] = |
220 |
"This function accepts 3 args, each of which must be vectors.\n" |
221 |
"It will bisect find the midpoint by bisection.\n" |
222 |
"Example: do_bisection(x[1..n],x_par[1..n], y[1..n]). \n"; |
223 |
|
224 |
int result; |
225 |
result = CreateUserFunctionMethod("do_set_values", |
226 |
do_set_values_eval, |
227 |
3,set_values_help,NULL,NULL); |
228 |
result += CreateUserFunctionMethod("do_bisection", |
229 |
do_bisection_eval, |
230 |
3,bisection_help,NULL,NULL); |
231 |
return result; |
232 |
} |
233 |
|