/[ascend]/trunk/base/generic/solver/logblock.c
ViewVC logotype

Contents of /trunk/base/generic/solver/logblock.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1695 - (show annotations) (download) (as text)
Wed Dec 26 08:23:08 2007 UTC (12 years, 6 months ago) by jpye
File MIME type: text/x-csrc
File size: 7383 byte(s)
Fixed up some debug output and lint, formatting.
tubebank model currently causes crash as noted in bug #350.
1 /* ASCEND modelling environment
2 Copyright (C) 1998, 2006-2007 Carnegie Mellon University
3 Copyright (C) 1996 Benjamin Andrew Allan
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 *//*
20 @file
21 block partitioning for logic problems. Extracted from slv_stdcalls.*
22 *//*
23 created John Pye 2007 from slv_stdcalls.h, orig by Ben Allan 1996.
24 */
25
26 #include "logblock.h"
27
28 #include <utilities/ascMalloc.h>
29 #include <general/mathmacros.h>
30 #include <linear/mtx_basic.h>
31 #include <system/slv_stdcalls.h>
32 #include <system/logrelman.h>
33
34 #include "solver.h"
35
36 /* #define SLBPDEBUG *//* slv_log_block_partition debugging */
37
38 /*
39 * returns 0 if ok, OTHERWISE if madness detected.
40 */
41 int slv_log_block_partition(slv_system_t sys)
42 {
43 #ifdef SLBPDEBUG
44 FILE *fp;
45 #endif
46 struct logrel_relation **lrp;
47 struct dis_discrete **dvp;
48 mtx_region_t *newblocks;
49 dof_t *d;
50 int32 nrow,ncol;
51 int32 ncolpfix, nrowpun, vlenmnv;
52 mtx_matrix_t mtx;
53 int32 order, rank;
54 int32 c,len,dvlen,r,lrlen;
55 dis_filter_t dvf;
56 logrel_filter_t lrf;
57
58 lrp = slv_get_solvers_logrel_list(sys);
59 dvp = slv_get_solvers_dvar_list(sys);
60 lrlen = slv_get_num_solvers_logrels(sys);
61 dvlen = slv_get_num_solvers_dvars(sys);
62 if (lrlen ==0 || dvlen == 0) return 1;
63 order = MAX(lrlen,dvlen);
64
65 lrf.matchbits = (LOGREL_ACTIVE);
66 lrf.matchvalue = (LOGREL_ACTIVE);
67 dvf.matchbits = (DIS_INCIDENT | DIS_BVAR | DIS_ACTIVE);
68 dvf.matchvalue = (DIS_INCIDENT | DIS_BVAR | DIS_ACTIVE);
69
70 /* nrow plus unincluded logrels */
71 nrowpun = slv_count_solvers_logrels(sys,&lrf);
72 /* ncol plus fixed discrete vars */
73 ncolpfix = slv_count_solvers_dvars(sys,&dvf);
74
75 dvf.matchbits = (DIS_BVAR);
76 dvf.matchvalue = 0;
77
78 /* dvlen minus non boolean vars */
79 vlenmnv = dvlen - slv_count_solvers_dvars(sys,&dvf);
80
81 lrf.matchbits = (LOGREL_INCLUDED | LOGREL_ACTIVE);
82 lrf.matchvalue = (LOGREL_INCLUDED | LOGREL_ACTIVE);
83 dvf.matchbits = (DIS_INCIDENT | DIS_BVAR | DIS_FIXED | DIS_ACTIVE);
84 dvf.matchvalue = (DIS_INCIDENT | DIS_BVAR | DIS_ACTIVE);
85
86 nrow = slv_count_solvers_logrels(sys,&lrf);
87 ncol = slv_count_solvers_dvars(sys,&dvf);
88
89 mtx = slv_get_sys_mtx(sys);
90 mtx_set_order(mtx,order);
91
92 if (slv_make_log_incidence_mtx(sys,mtx,&dvf,&lrf)) {
93 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failure in creating incidence matrix.");
94 mtx_destroy(mtx);
95 return 1;
96 }
97
98 mtx_output_assign(mtx,lrlen,dvlen);
99 rank = mtx_symbolic_rank(mtx);
100 if (rank == 0 ) return 1;
101 if (rank < nrow) {
102 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"rank < nrow. Dependent logical relations?");
103 }
104 if (rank < ncol) {
105 if ( nrow != rank) {
106 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"rank < ncol and nrow != rank. Excess of columns?");
107 } else {
108 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"rank<ncol but nrow==rank. Degrees of freedom?");
109 }
110 }
111 if (ncol == nrow) {
112 if (ncol == rank) {
113 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"System of logical relations does not require inference.\n");
114 }
115 if (ncol != rank) {
116 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"but ncol!=rank. Rank deficient?");
117 }
118 }
119 mtx_partition(mtx);
120 /* copy the block list. there is at least one if rank >=1 as above */
121 len = mtx_number_of_blocks(mtx);
122 newblocks = ASC_NEW_ARRAY(mtx_region_t,len);
123 if (newblocks == NULL) {
124 mtx_destroy(mtx);
125 return 2;
126 }
127 for (c = 0 ; c < len; c++) {
128 mtx_block(mtx,c,&(newblocks[c]));
129 }
130 slv_set_solvers_log_blocks(sys,len,newblocks); /* give it to the system */
131 d = slv_get_log_dofdata(sys);
132 d->structural_rank = rank;
133 d->n_rows = nrow;
134 d->n_cols = ncol;
135 d->n_fixed = ncolpfix - ncol;
136 d->n_unincluded = nrowpun - nrow;
137 d->reorder.partition = 1; /* yes */
138 d->reorder.basis_selection = 0; /* none yet */
139 d->reorder.block_reordering = 0; /* none */
140
141 #ifdef SLBPDEBUG
142 fp = fopen("/tmp/sbp1.plot","w+");
143 if (fp !=NULL) {
144 mtx_write_region_plot(fp,mtx,mtx_ENTIRE_MATRIX);
145 fclose(fp);
146 }
147 #endif
148
149 len = vlenmnv - 1; /* row of last possible boolean variable */
150 for (c=ncol; len > c ; ) { /* sort the fixed out of inactive */
151 r = mtx_col_to_org(mtx,c);
152 if ( dis_fixed(dvp[r]) && dis_active(dvp[r])) {
153 c++;
154 } else {
155 mtx_swap_cols(mtx,c,len);
156 len--;
157 }
158 }
159
160 /* Now, leftover columns are where we want them.
161 * That is, unassigned incidence is next to assigned and fixed on right with
162 * no columns which do not correspond to dis vars in the range 0..dvlen-1.
163 */
164 /* there aren't any nonincident dvars in the solvers dvarlist, so
165 * we now have the columns in |assigned|dof|fixed|inactive|nonvars| order */
166
167 /* rows 0->lrlen-1 should be actual logrels, though, and not phantoms.
168 * At this point we should have
169 * rows - assigned
170 * - unassigned w/incidence
171 * - unincluded and included w/out free incidence and inactive mixed.
172 */
173
174 /* sort unincluded logrelations to bottom of good region */
175 /* this is needed because the idiot user may have fixed everything */
176 /* in a logrelation, but we want those rows not to be confused with */
177 /* unincluded rows.*/
178 len = lrlen - 1; /* row of last possible relation */
179 /* sort the inactive out of the unassigned/unincluded */
180 for (c=rank; len > c ; ) {
181 r = mtx_row_to_org(mtx,c);
182 if ( logrel_active(lrp[r])) {
183 c++;
184 } else {
185 mtx_swap_rows(mtx,c,len);
186 len--;
187 }
188 }
189
190 /* sort the unincluded out of the unassigned */
191 len = nrowpun - 1; /* row of last possible unassigned/unincluded relation */
192 for (c=rank; len > c ; ) {
193 r = mtx_row_to_org(mtx,c);
194 if ( logrel_included(lrp[r]) ) {
195 c++;
196 } else {
197 mtx_swap_rows(mtx,c,len);
198 len--;
199 }
200 }
201
202 #ifdef SLBPDEBUG
203 fp = fopen("/tmp/sbp2.plot","w+");
204 if(fp !=NULL){
205 mtx_write_region_plot(fp,mtx,mtx_ENTIRE_MATRIX);
206 fclose(fp);
207 }
208 #endif
209
210 /* These functions are called for slv_block_partitioning, but I do not
211 * know if I need them here:
212 *
213 * now, at last we have cols in the order we want the lists to
214 * be handed to the solver. So, we need to reset the dvar sindex values
215 * and reorder the lists.
216 */
217
218 #if USEDCODE
219 if (reindex_dvars_from_mtx(sys,0,dvlen-1,mtx)) {
220 mtx_destroy(mtx);
221 return 2;
222 }
223 #endif /* USEDCODE */
224
225 /*
226 * now, at last we have rows jacobian in the order we want the lists to
227 * be handed to the solvers. So, we need to reset the rel sindex values.
228 */
229
230 #if USEDCODE
231 if (reindex_logrels_from_mtx(sys,0,lrlen-1,mtx)) {
232 mtx_destroy(mtx);
233 return 2;
234 }
235 #endif /* USEDCODE */
236
237 return 0;
238 }
239

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