Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/matc/src/optim.c
3196 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library (in file ../LGPL-2.1); if not, write
19
* to the Free Software Foundation, Inc., 51 Franklin Street,
20
* Fifth Floor, Boston, MA 02110-1301 USA
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* MATC code optimizer. Not used at the moment.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 27 Sep 1995
40
*
41
* Modified by:
42
*
43
* Date of modification:
44
*
45
******************************************************************************/
46
47
/*
48
* $Id: optim.c,v 1.1.1.1 2005/04/14 13:29:14 vierinen Exp $
49
*
50
* $Log: optim.c,v $
51
* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen
52
* initial matc automake package
53
*
54
* Revision 1.2 1998/08/01 12:34:52 jpr
55
*
56
* Added Id, started Log.
57
*
58
*
59
*/
60
61
#include "elmer/matc.h"
62
63
TREE *optimtree(TREE *root)
64
{
65
int constant = TRUE, csize = 0;
66
int constsubs;
67
68
TREE *tptr, *tprev, *prevroot;
69
TREE *subs, *prevsubs;
70
71
VARIABLE *subvar, *stmp;
72
73
tptr = tprev = root;
74
prevroot = NULL;
75
76
while(tptr)
77
{
78
constsubs = TRUE; subs = NULL; subvar = NULL;
79
80
if (SUBS(tptr) != (TREE *)NULL)
81
{
82
subs = SUBS(tptr) = optimtree(SUBS(tptr));
83
if (subs == (TREE *)NULL) error("it's not worth it.\n");
84
if (ETYPE(subs) != ETYPE_CONST || LINK(subs) != NULL)
85
constsubs = FALSE;
86
prevsubs = subs; subs = NEXT(subs);
87
88
while(subs != (TREE *)NULL)
89
{
90
subs = optimtree(subs);
91
if (subs == (TREE *)NULL) error("it's not worth it.\n");
92
if (ETYPE(subs) != ETYPE_CONST || LINK(subs) != NULL)
93
constsubs = FALSE;
94
NEXT(prevsubs) = subs; prevsubs = subs;
95
subs = NEXT(subs);
96
}
97
98
if (constsubs)
99
{
100
subs = SUBS(tptr);
101
subvar = stmp = CDATA(subs);
102
subs = NEXT(subs);
103
while(subs)
104
{
105
NEXT(stmp) = CDATA(subs);
106
subs = NEXT(subs); stmp = NEXT(stmp);
107
}
108
}
109
110
subs = SUBS(tptr); SUBS(tptr) = NULL;
111
}
112
113
switch(ETYPE(tptr))
114
{
115
/******************************************************
116
some kind of existing identifier.
117
*******************************************************/
118
case ETYPE_NAME:
119
{
120
int constargs = TRUE, con = FALSE, argcount = 0;
121
VARIABLE *parroot, *par, *tmp = NULL;
122
TREE *args, *prevargs;
123
COMMAND *com;
124
125
if (ARGS(tptr) != (TREE *)NULL)
126
{
127
args = ARGS(tptr) = optimtree(ARGS(tptr));
128
if (args == (TREE *)NULL) error("it's not worth it.\n");
129
if (ETYPE(args) != ETYPE_CONST || LINK(args) != NULL)
130
constargs = FALSE;
131
prevargs = args; args = NEXT(args); argcount++;
132
133
while(args != (TREE *)NULL)
134
{
135
args = optimtree(args);
136
if (args == (TREE *)NULL) error("it's not worth it.\n");
137
if (ETYPE(args) != ETYPE_CONST || LINK(args) != NULL)
138
constargs = FALSE;
139
NEXT(prevargs) = args; prevargs = args;
140
args = NEXT(args); argcount++;
141
}
142
}
143
144
if ((com = com_check(SDATA(tptr))) != NULL && constargs)
145
{
146
if (com -> flags && CMDFLAG_CE)
147
{
148
149
if (argcount < com->minp || argcount > com->maxp)
150
{
151
if (com->minp == com->maxp)
152
{
153
fprintf(math_err,
154
"Builtin function [%s] requires %d argument(s).\n",
155
SDATA(tptr), com->minp);
156
error("");
157
}
158
else
159
{
160
fprintf(math_err,
161
"Builtin function [%s] takes from %d to %d argument(s).\n",
162
SDATA(tptr), com->minp, com->maxp);
163
error("");
164
}
165
}
166
167
args = ARGS(tptr);
168
if (args)
169
{
170
parroot = par = CDATA(args);
171
args = NEXT(args);
172
while(args)
173
{
174
NEXT(par) = CDATA(args);
175
args = NEXT(args); par = NEXT(par);
176
}
177
}
178
179
if (com->flags & CMDFLAG_PW)
180
{
181
tmp = com_pointw((double (*)())com->sub, parroot);
182
}
183
else
184
{
185
tmp = (*com->sub)(parroot);
186
}
187
188
par = parroot;
189
while(par)
190
{
191
parroot = NEXT(par);
192
NEXT(par) = NULL;
193
par = parroot;
194
}
195
196
if (tmp != (VARIABLE *)NULL)
197
{
198
199
TREE *newroot;
200
201
newroot = newtree();
202
if (tptr == root)
203
root = newroot;
204
else
205
LINK(tprev) = newroot;
206
207
NEXT(newroot) = NEXT(tptr);
208
NEXT(tptr) = (TREE *)NULL;
209
LINK(newroot) = LINK(tptr);
210
LINK(tptr) = (TREE *)NULL;
211
free_tree(tptr);
212
tptr = newroot;
213
ETYPE(tptr) = ETYPE_CONST;
214
CDATA(tptr) = tmp;
215
if (constsubs)
216
{
217
if (!constant) prevroot = tprev;
218
con = TRUE;
219
csize += NROW(tmp) * NCOL(tmp);
220
}
221
}
222
}
223
}
224
225
constant = con;
226
}
227
break;
228
229
/******************************************************
230
single constant
231
*******************************************************/
232
case ETYPE_NUMBER:
233
if (constsubs) {
234
if (!constant) prevroot = tprev;
235
constant = TRUE;
236
csize++;
237
}
238
break;
239
240
case ETYPE_STRING:
241
if (constsubs)
242
{
243
if (!constant) prevroot = tprev;
244
constant = TRUE;
245
csize += strlen(SDATA(tptr));
246
}
247
break;
248
249
/******************************************************
250
huh ?
251
*******************************************************/
252
case ETYPE_EQUAT:
253
{
254
TREE *leftptr;
255
256
LEFT(tptr) = leftptr = optimtree(LEFT(tptr));
257
258
if (
259
leftptr != NULL && ETYPE(leftptr)==ETYPE_CONST && LINK(leftptr) == NULL
260
)
261
{
262
263
TREE *newroot;
264
265
newroot = leftptr;
266
if (tptr == root)
267
root = newroot;
268
else
269
LINK(tprev) = newroot;
270
271
NEXT(newroot) = NEXT(tptr);
272
NEXT(tptr) = (TREE *)NULL;
273
LINK(newroot) = LINK(tptr);
274
LINK(tptr) = (TREE *)NULL;
275
LEFT(tptr) = (TREE *)NULL;
276
free_tree(tptr);
277
tptr = newroot;
278
if (constsubs)
279
{
280
if (!constant) prevroot = tprev;
281
constant = TRUE;
282
csize += NROW(CDATA(tptr)) * NCOL(CDATA(tptr));
283
}
284
}
285
else
286
constant = FALSE;
287
}
288
break;
289
290
/******************************************************
291
left oper [right]
292
oper = divide, multiply, transpose, power,...
293
*******************************************************/
294
case ETYPE_OPER:
295
{
296
VARIABLE *tmp = (VARIABLE *)NULL;
297
TREE *leftptr, *rightptr;
298
MATRIX *opres = NULL;
299
300
leftptr = LEFT(tptr) = optimtree(LEFT(tptr));
301
rightptr = RIGHT(tptr) = optimtree(RIGHT(tptr));
302
303
if (leftptr != NULL && rightptr != NULL)
304
{
305
if (ETYPE(leftptr) == ETYPE_CONST && ETYPE(rightptr) == ETYPE_CONST)
306
{
307
if (LINK(leftptr) == NULL && LINK(rightptr) == NULL)
308
{
309
opres = ((MATRIX *(*)(MATRIX *, MATRIX *)) (VDATA(tptr)))
310
(CDATA(leftptr)->this, CDATA(rightptr)->this);
311
NEXT(CDATA(leftptr)) = NULL;
312
}
313
}
314
}
315
else if (leftptr != NULL && ETYPE(leftptr) == ETYPE_CONST)
316
{
317
if (LINK(leftptr) == NULL)
318
opres = ((MATRIX *(*)(MATRIX *, MATRIX *)) (VDATA(tptr)))
319
(CDATA(leftptr)->this, NULL);
320
}
321
else if (rightptr != NULL && ETYPE(rightptr) == ETYPE_CONST)
322
{
323
if (LINK(rightptr) == NULL)
324
opres = ((MATRIX *(*)(MATRIX *, MATRIX *)) (VDATA(tptr)))
325
(CDATA(rightptr)->this, NULL);
326
}
327
328
if (opres != NULL)
329
{
330
TREE *newroot;
331
332
tmp = (VARIABLE *)ALLOCMEM(VARIABLESIZE);
333
tmp->this = opres;
334
REFCNT(tmp) = 1;
335
336
newroot = newtree();
337
if (tptr == root)
338
root = newroot;
339
else
340
LINK(tprev) = newroot;
341
342
NEXT(newroot) = NEXT(tptr);
343
NEXT(tptr) = (TREE *)NULL;
344
LINK(newroot) = LINK(tptr);
345
LINK(tptr) = (TREE *)NULL;
346
free_tree(tptr);
347
tptr = newroot;
348
ETYPE(tptr) = ETYPE_CONST;
349
CDATA(tptr) = tmp;
350
if (constsubs)
351
{
352
if (!constant) prevroot = tprev;
353
constant = TRUE;
354
csize += NROW(tmp) * NCOL(tmp);
355
}
356
}
357
else
358
constant = FALSE;
359
360
}
361
break;
362
}
363
364
if (constsubs && constant && subs)
365
{
366
if (CDATA(tptr))
367
{
368
csize -= NROW(CDATA(tptr)) * NCOL(CDATA(tptr));
369
stmp = CDATA(tptr);
370
NEXT(stmp) = subvar;
371
if ((CDATA(tptr) = com_el(stmp)) != NULL)
372
{
373
csize += NROW(CDATA(tptr)) * NCOL(CDATA(tptr));
374
}
375
var_delete_temp(stmp);
376
}
377
free_tree(subs);
378
SUBS(tptr) = NULL;
379
}
380
else if (constsubs && subs)
381
{
382
SUBS(tptr) = subs;
383
while(subvar)
384
{
385
stmp = NEXT(subvar);
386
NEXT(subvar) = NULL;
387
subvar = stmp;
388
}
389
}
390
else if (subs)
391
{
392
SUBS(tptr) = subs;
393
}
394
else
395
{
396
SUBS(tptr) = NULL;
397
}
398
399
constant &= constsubs;
400
401
if (!constant && csize > 0)
402
{
403
404
int i = 0, j = 0, k = 0;
405
TREE *ptr, *newroot;
406
407
newroot = newtree();
408
ETYPE(newroot) = ETYPE_CONST;
409
410
if (prevroot != (TREE *)NULL)
411
ptr = LINK(prevroot);
412
else
413
ptr = root;
414
415
if (ETYPE(ptr) == ETYPE_STRING)
416
CDATA(newroot) = var_temp_new(TYPE_STRING, 1, csize);
417
else if (ETYPE(ptr) == ETYPE_NUMBER)
418
CDATA(newroot) = var_temp_new(TYPE_DOUBLE, 1, csize);
419
else if (ETYPE(ptr) == ETYPE_CONST)
420
CDATA(newroot) = var_temp_new(TYPE(CDATA(ptr)), 1, csize);
421
422
while(ptr != tptr)
423
{
424
switch(ETYPE(ptr))
425
{
426
case ETYPE_NUMBER:
427
M(CDATA(newroot),0,i++)=DDATA(ptr);
428
break;
429
case ETYPE_STRING:
430
for(j = 0; j < strlen(SDATA(ptr)); j++)
431
M(CDATA(newroot),0,i++)=(double)SDATA(ptr)[j];
432
break;
433
case ETYPE_CONST:
434
j = MATSIZE(CDATA(ptr));
435
memcpy(&M(CDATA(newroot),0,i),MATR(CDATA(ptr)),j);
436
i += (j>>3);
437
break;
438
}
439
ptr = LINK(ptr);
440
}
441
442
LINK(newroot) = tptr;
443
LINK(tprev) = (TREE *)NULL;
444
if (prevroot != (TREE *)NULL)
445
{
446
free_tree(LINK(prevroot));
447
LINK(prevroot) = newroot;
448
}
449
else
450
{
451
NEXT(newroot) = NEXT(root);
452
NEXT(root) = NULL;
453
free_tree(root);
454
root = newroot;
455
}
456
constant = FALSE;
457
csize = 0;
458
}
459
460
tprev = tptr;
461
tptr = LINK(tptr);
462
}
463
464
if (constant && csize > 0)
465
{
466
int i = 0, j = 0, k = 0;
467
TREE *ptr, *newroot;
468
469
newroot = newtree();
470
ETYPE(newroot) = ETYPE_CONST;
471
472
if (prevroot != (TREE *)NULL)
473
ptr = LINK(prevroot);
474
else
475
ptr = root;
476
477
if (ETYPE(ptr) == ETYPE_STRING)
478
CDATA(newroot) = var_temp_new(TYPE_STRING, 1, csize);
479
else if (ETYPE(ptr) == ETYPE_NUMBER)
480
CDATA(newroot) = var_temp_new(TYPE_DOUBLE, 1, csize);
481
else if (ETYPE(ptr) == ETYPE_CONST)
482
CDATA(newroot) = var_temp_new(TYPE(CDATA(ptr)), 1, csize);
483
484
while(ptr)
485
{
486
switch(ETYPE(ptr))
487
{
488
case ETYPE_NUMBER:
489
M(CDATA(newroot), 0, i++) = DDATA(ptr);
490
break;
491
case ETYPE_STRING:
492
for(j = 0; j < strlen(SDATA(ptr)); j++)
493
M(CDATA(newroot), 0, i++) = (double)SDATA(ptr)[j];
494
break;
495
case ETYPE_CONST:
496
j = MATSIZE(CDATA(ptr));
497
memcpy(&M(CDATA(newroot),0,i),MATR(CDATA(ptr)),j);
498
i += (j>>3);
499
break;
500
}
501
ptr = LINK(ptr);
502
}
503
504
if (prevroot != (TREE *)NULL)
505
{
506
free_tree(LINK(prevroot));
507
LINK(prevroot) = newroot;
508
}
509
else
510
{
511
NEXT(newroot) = NEXT(root);
512
NEXT(root) = NULL;
513
if (ETYPE(root) == ETYPE_CONST && LINK(root) == NULL)
514
{
515
NROW(CDATA(newroot)) = NROW(CDATA(root));
516
NCOL(CDATA(newroot)) = NCOL(CDATA(root));
517
}
518
free_tree(root);
519
root = newroot;
520
}
521
}
522
else if (constant)
523
{
524
free_tree(root);
525
root = NULL;
526
}
527
528
return root;
529
}
530
531
532
CLAUSE *optimclause(CLAUSE *root)
533
{
534
CLAUSE *cptr = root;
535
536
while(cptr)
537
{
538
539
switch(cptr->data)
540
{
541
/************************************************************
542
Function definition
543
************************************************************/
544
case funcsym:
545
cptr -> this = optimtree(cptr->this);
546
LINK(cptr) = optimclause(LINK(cptr));
547
return root;
548
549
/***************************************************************
550
statement
551
****************************************************************/
552
case assignsym:
553
if (cptr->this)
554
{
555
cptr->this = optimtree(cptr->this);
556
}
557
LINK(cptr)->this = optimtree(LINK(cptr)->this);
558
cptr = LINK(cptr);
559
break;
560
561
/***************************************************************
562
if statement
563
****************************************************************/
564
case ifsym:
565
566
cptr -> this = optimtree(cptr->this);
567
LINK(cptr) = optimclause(LINK(cptr));
568
cptr = cptr->jmp;
569
if (cptr->data == elsesym)
570
{
571
LINK(cptr) = optimclause(LINK(cptr));
572
cptr = cptr -> jmp;
573
}
574
break;
575
576
/***************************************************************
577
while statement
578
****************************************************************/
579
case whilesym:
580
581
cptr -> this = optimtree(cptr->this);
582
LINK(cptr) = optimclause(LINK(cptr));
583
cptr = cptr->jmp;
584
break;
585
586
/***************************************************************
587
for statement
588
****************************************************************/
589
case forsym:
590
591
LINK(cptr->this) = optimtree(LINK(cptr->this));
592
LINK(cptr) = optimclause(LINK(cptr));
593
cptr = cptr->jmp;
594
break;
595
596
case endsym:
597
return root;
598
}
599
600
cptr = LINK(cptr);
601
}
602
return root;
603
}
604
605