38 |
#include "utilities/ascSignal.h" |
#include "utilities/ascSignal.h" |
39 |
#include "compiler/compiler.h" |
#include "compiler/compiler.h" |
40 |
#include "utilities/ascMalloc.h" |
#include "utilities/ascMalloc.h" |
41 |
|
#include "utilities/ascPanic.h" |
42 |
#include "solver/mtx.h" |
#include "solver/mtx.h" |
43 |
#include "solver/slv_types.h" |
#include "solver/slv_types.h" |
44 |
#include "solver/rel.h" |
#include "solver/rel.h" |
68 |
/** |
/** |
69 |
*** Array/vector operations |
*** Array/vector operations |
70 |
*** ---------------------------- |
*** ---------------------------- |
71 |
|
*** slv_create_vector(low,high) |
72 |
|
*** slv_init_vector(vec,low,high) |
73 |
|
*** slv_destroy_vector(vec) |
74 |
*** slv_zero_vector(vec) |
*** slv_zero_vector(vec) |
75 |
*** slv_copy_vector(vec1,vec2) |
*** slv_copy_vector(vec1,vec2) |
76 |
*** prod = slv_inner_product(vec1,vec2) |
*** prod = slv_inner_product(vec1,vec2) |
79 |
*** slv_write_vector(file,vec) |
*** slv_write_vector(file,vec) |
80 |
**/ |
**/ |
81 |
|
|
82 |
|
struct vector_data *slv_create_vector(int32 low, int32 high) |
83 |
|
{ |
84 |
|
struct vector_data *result; |
85 |
|
|
86 |
|
result = (struct vector_data *)ascmalloc(sizeof(struct vector_data)); |
87 |
|
if (NULL == result) |
88 |
|
return NULL; |
89 |
|
|
90 |
|
result->rng = NULL; |
91 |
|
result->vec = NULL; |
92 |
|
if (0 != slv_init_vector(result, low, high)) { |
93 |
|
ascfree(result); |
94 |
|
result = NULL; |
95 |
|
} |
96 |
|
return result; |
97 |
|
} |
98 |
|
|
99 |
|
int slv_init_vector(struct vector_data *vec, int32 low, int32 high) |
100 |
|
{ |
101 |
|
int32 new_size; |
102 |
|
|
103 |
|
if ((low < 0) || (high < low)) |
104 |
|
return 1; |
105 |
|
|
106 |
|
if (NULL == vec) |
107 |
|
return 2; |
108 |
|
|
109 |
|
if (NULL == vec->rng) { |
110 |
|
vec->rng = (mtx_range_t *)ascmalloc(sizeof(mtx_range_t)); |
111 |
|
if (NULL == vec->rng) |
112 |
|
return 3; |
113 |
|
} |
114 |
|
vec->rng = mtx_range(vec->rng, low, high); |
115 |
|
|
116 |
|
new_size = high + 1; |
117 |
|
if (NULL == vec->vec) { |
118 |
|
vec->vec = (real64 *)ascmalloc((new_size)*sizeof(real64)); |
119 |
|
if (NULL == vec->vec) { |
120 |
|
ascfree(vec->rng); |
121 |
|
vec->rng = NULL; |
122 |
|
return 3; |
123 |
|
} |
124 |
|
} |
125 |
|
else { |
126 |
|
vec->vec = (real64 *)ascrealloc(vec->vec, (new_size)*sizeof(real64)); |
127 |
|
} |
128 |
|
|
129 |
|
vec->accurate = FALSE; |
130 |
|
return 0; |
131 |
|
} |
132 |
|
|
133 |
|
void slv_destroy_vector(struct vector_data *vec) |
134 |
|
{ |
135 |
|
if (NULL != vec) { |
136 |
|
if (NULL != vec->rng) |
137 |
|
ascfree(vec->rng); |
138 |
|
if (NULL != vec->vec) |
139 |
|
ascfree(vec->vec); |
140 |
|
ascfree(vec); |
141 |
|
} |
142 |
|
} |
143 |
|
|
144 |
void slv_zero_vector( struct vector_data *vec) |
void slv_zero_vector( struct vector_data *vec) |
145 |
{ |
{ |
146 |
real64 *p; |
real64 *p; |
147 |
int32 len; |
int32 len; |
148 |
|
|
149 |
|
asc_assert((NULL != vec) && |
150 |
|
(NULL != vec->rng) && |
151 |
|
(NULL != vec->vec) && |
152 |
|
(vec->rng->low >= 0) && |
153 |
|
(vec->rng->low <= vec->rng->high)); |
154 |
|
|
155 |
p = vec->vec + vec->rng->low; |
p = vec->vec + vec->rng->low; |
156 |
len = vec->rng->high - vec->rng->low + 1; |
len = vec->rng->high - vec->rng->low + 1; |
157 |
mtx_zero_real64(p,len); |
mtx_zero_real64(p,len); |
162 |
real64 *p1,*p2; |
real64 *p1,*p2; |
163 |
int32 len; |
int32 len; |
164 |
|
|
165 |
|
asc_assert((NULL != vec1) && |
166 |
|
(NULL != vec1->rng) && |
167 |
|
(NULL != vec1->vec) && |
168 |
|
(vec1->rng->low >= 0) && |
169 |
|
(vec1->rng->low <= vec1->rng->high) && |
170 |
|
(NULL != vec2) && |
171 |
|
(NULL != vec2->rng) && |
172 |
|
(NULL != vec2->vec) && |
173 |
|
(vec2->rng->low >= 0)); |
174 |
|
|
175 |
p1 = vec1->vec + vec1->rng->low; |
p1 = vec1->vec + vec1->rng->low; |
176 |
p2 = vec2->vec + vec2->rng->low; |
p2 = vec2->vec + vec2->rng->low; |
177 |
len = vec1->rng->high - vec1->rng->low + 1; |
len = vec1->rng->high - vec1->rng->low + 1; |
182 |
#define USEDOT TRUE |
#define USEDOT TRUE |
183 |
/* USEDOT = TRUE is a winner on alphas, hps, and sparc20 */ |
/* USEDOT = TRUE is a winner on alphas, hps, and sparc20 */ |
184 |
real64 slv_inner_product(struct vector_data *vec1 , |
real64 slv_inner_product(struct vector_data *vec1 , |
185 |
struct vector_data *vec2) |
struct vector_data *vec2) |
186 |
/** |
/** |
187 |
*** Computes inner product between vec1 and vec2, returning result. |
*** Computes inner product between vec1 and vec2, returning result. |
188 |
*** vec1 and vec2 may overlap or even be identical. |
*** vec1 and vec2 may overlap or even be identical. |
194 |
#endif |
#endif |
195 |
int32 len; |
int32 len; |
196 |
|
|
197 |
|
asc_assert((NULL != vec1) && |
198 |
|
(NULL != vec1->rng) && |
199 |
|
(NULL != vec1->vec) && |
200 |
|
(vec1->rng->low >= 0) && |
201 |
|
(vec1->rng->low <= vec1->rng->high) && |
202 |
|
(NULL != vec2) && |
203 |
|
(NULL != vec2->rng) && |
204 |
|
(NULL != vec2->vec) && |
205 |
|
(vec2->rng->low >= 0)); |
206 |
|
|
207 |
p1 = vec1->vec + vec1->rng->low; |
p1 = vec1->vec + vec1->rng->low; |
208 |
p2 = vec2->vec + vec2->rng->low; |
p2 = vec2->vec + vec2->rng->low; |
209 |
len = vec1->rng->high - vec1->rng->low + 1; |
len = vec1->rng->high - vec1->rng->low + 1; |
246 |
real64 value, *vvec, *pvec; |
real64 value, *vvec, *pvec; |
247 |
int32 lim; |
int32 lim; |
248 |
|
|
249 |
lim=prod->rng->high; |
asc_assert((NULL != vec) && |
250 |
pvec=prod->vec; |
(NULL != vec->rng) && |
251 |
vvec=vec->vec; |
(NULL != vec->vec) && |
252 |
|
(vec->rng->low >= 0) && |
253 |
|
(vec->rng->low <= vec->rng->high) && |
254 |
|
(NULL != prod) && |
255 |
|
(NULL != prod->rng) && |
256 |
|
(NULL != prod->vec) && |
257 |
|
(prod->rng->low >= 0) && |
258 |
|
(prod->rng->low <= prod->rng->high) && |
259 |
|
(NULL != mtx)); |
260 |
|
|
261 |
|
lim = prod->rng->high; |
262 |
|
pvec = prod->vec; |
263 |
|
vvec = vec->vec; |
264 |
if( transpose ) { |
if( transpose ) { |
265 |
for(nz.col = prod->rng->low ; nz.col <= lim ; ++(nz.col) ) { |
for(nz.col = prod->rng->low ; nz.col <= lim ; ++(nz.col) ) { |
266 |
pvec[nz.col] = 0.0; |
pvec[nz.col] = 0.0; |
282 |
} |
} |
283 |
} |
} |
284 |
|
|
285 |
void slv_write_vector(FILE *fp,struct vector_data *vec) |
void slv_write_vector(FILE *fp, struct vector_data *vec) |
286 |
/** |
/** |
287 |
*** Outputs a vector. |
*** Outputs a vector. |
288 |
**/ |
**/ |
289 |
{ |
{ |
290 |
int32 ndx,hi; |
int32 ndx,hi; |
291 |
real64 *vvec; |
real64 *vvec; |
292 |
|
|
293 |
|
if (NULL == fp) { |
294 |
|
FPRINTF(ASCERR, "Error writing vector in slv_write_vector: NULL file pointer.\n"); |
295 |
|
return; |
296 |
|
} |
297 |
|
if ((NULL == vec) || |
298 |
|
(NULL == vec->rng) || |
299 |
|
(NULL == vec->vec) || |
300 |
|
(vec->rng->low < 0) || |
301 |
|
(vec->rng->low > vec->rng->high)) { |
302 |
|
FPRINTF(ASCERR, "Error writing vector in slv_write_vector: uninitialized vector.\n"); |
303 |
|
return; |
304 |
|
} |
305 |
|
|
306 |
vvec = vec->vec; |
vvec = vec->vec; |
307 |
hi = vec->rng->high; |
hi = vec->rng->high; |
308 |
FPRINTF(fp,"Norm = %g, Accurate = %s, Vector range = %d to %d\n", |
FPRINTF(fp,"Norm = %g, Accurate = %s, Vector range = %d to %d\n", |
349 |
#undef AVMAGIC |
#undef AVMAGIC |
350 |
#define AVMAGIC 10 |
#define AVMAGIC 10 |
351 |
#endif |
#endif |
352 |
|
|
353 |
|
asc_assert((NULL != p1) && (NULL != p2) && (len >= 0)); |
354 |
|
|
355 |
m = len / AVMAGIC; |
m = len / AVMAGIC; |
356 |
n = len % AVMAGIC; |
n = len % AVMAGIC; |
357 |
if (p1!=p2) { |
if (p1!=p2) { |
463 |
*** slv_print_rel_name(out,sys,rel) |
*** slv_print_rel_name(out,sys,rel) |
464 |
*** slv_print_dis_name(out,sys,dvar) |
*** slv_print_dis_name(out,sys,dvar) |
465 |
*** slv_print_logrel_name(out,sys,lrel) |
*** slv_print_logrel_name(out,sys,lrel) |
466 |
*** NOt yet implemented correctly: |
*** NOT yet implemented correctly: |
467 |
*** slv_print_obj_name(out,obj) |
*** slv_print_obj_name(out,obj) |
468 |
*** slv_print_var_sindex(out,var) |
*** slv_print_var_sindex(out,var) |
469 |
*** slv_print_rel_sindex(out,rel) |
*** slv_print_rel_sindex(out,rel) |
472 |
*** slv_print_obj_index(out,obj) |
*** slv_print_obj_index(out,obj) |
473 |
**/ |
**/ |
474 |
|
|
|
FILE *slv_get_output_file(fp) |
|
|
FILE *fp; |
|
475 |
/** |
/** |
476 |
*** Returns fp if fp!=NULL, or a file pointer |
*** Returns fp if fp!=NULL, or a file pointer |
477 |
*** open to nul device if fp == NULL. |
*** open to nul device if fp == NULL. |
478 |
**/ |
**/ |
479 |
|
FILE *slv_get_output_file(FILE *fp) |
480 |
{ |
{ |
481 |
static FILE *nuldev = NULL; |
static FILE *nuldev = NULL; |
482 |
static char fname[] = "/dev/null"; |
#ifndef __WIN32__ |
483 |
|
const char fname[] = "/dev/null"; |
484 |
|
#else |
485 |
|
const char fname[] = "nul"; |
486 |
|
#endif |
487 |
|
|
488 |
if( fp==NULL ) { |
if( fp == NULL ) { |
489 |
if(nuldev==NULL) |
if(nuldev == NULL) |
490 |
if( (nuldev=fopen(fname,"w")) == NULL ) { |
if( (nuldev = fopen(fname,"w")) == NULL ) { |
491 |
FPRINTF(stderr,"ERROR: (slv) get_output_file\n"); |
FPRINTF(stderr,"ERROR: slv_get_output_file\n"); |
492 |
FPRINTF(stderr," Unable to open %s.\n",fname); |
FPRINTF(stderr," Unable to open %s.\n",fname); |
493 |
} |
} |
494 |
fp=nuldev; |
fp = nuldev; |
495 |
} |
} |
496 |
return(fp); |
return(fp); |
497 |
} |
} |
502 |
|
|
503 |
void slv_print_var_name( FILE *out,slv_system_t sys, struct var_variable *var) |
void slv_print_var_name( FILE *out,slv_system_t sys, struct var_variable *var) |
504 |
{ |
{ |
505 |
char *name=NULL; |
char *name = NULL; |
506 |
if (out == NULL || sys == NULL || var == NULL) return; |
if (out == NULL || sys == NULL || var == NULL) return; |
507 |
name = var_make_name(sys,var); |
name = var_make_name(sys,var); |
508 |
if( *name == '?' ) FPRINTF(out,"%d",var_sindex(var)); |
if( *name == '?' ) FPRINTF(out,"%d",var_sindex(var)); |
519 |
ascfree(name); |
ascfree(name); |
520 |
} |
} |
521 |
|
|
522 |
void slv_print_dis_name( FILE *out,slv_system_t sys, struct dis_discrete *dvar) |
void slv_print_dis_name( FILE *out, slv_system_t sys, struct dis_discrete *dvar) |
523 |
{ |
{ |
524 |
char *name=NULL; |
char *name=NULL; |
525 |
if (out == NULL || sys == NULL || dvar == NULL) return; |
if (out == NULL || sys == NULL || dvar == NULL) return; |
540 |
} |
} |
541 |
|
|
542 |
#ifdef NEWSTUFF |
#ifdef NEWSTUFF |
543 |
void slv_print_obj_name(out,obj) |
void slv_print_obj_name(FILE *out, obj_objective_t obj) |
|
FILE *out; |
|
|
obj_objective_t obj; |
|
544 |
{ |
{ |
545 |
char *name; |
char *name; |
546 |
name = obj_make_name(obj); |
name = obj_make_name(obj); |
550 |
} |
} |
551 |
#endif |
#endif |
552 |
|
|
553 |
void slv_print_var_sindex(out,var) |
void slv_print_var_sindex(FILE *out, struct var_variable *var) |
|
FILE *out; |
|
|
struct var_variable *var; |
|
554 |
{ |
{ |
555 |
FPRINTF(out,"%d",var_sindex(var)); |
FPRINTF(out,"%d",var_sindex(var)); |
556 |
} |
} |
557 |
|
|
558 |
void slv_print_rel_sindex(out,rel) |
void slv_print_rel_sindex(FILE *out, struct rel_relation *rel) |
|
FILE *out; |
|
|
struct rel_relation *rel; |
|
559 |
{ |
{ |
560 |
FPRINTF(out,"%d",rel_sindex(rel)); |
FPRINTF(out,"%d",rel_sindex(rel)); |
561 |
} |
} |
562 |
|
|
563 |
void slv_print_dis_sindex(out,dvar) |
void slv_print_dis_sindex(FILE *out, struct dis_discrete *dvar) |
|
FILE *out; |
|
|
struct dis_discrete *dvar; |
|
564 |
{ |
{ |
565 |
FPRINTF(out,"%d",dis_sindex(dvar)); |
FPRINTF(out,"%d",dis_sindex(dvar)); |
566 |
} |
} |
567 |
|
|
568 |
void slv_print_logrel_sindex(out,lrel) |
void slv_print_logrel_sindex(FILE *out, struct logrel_relation *lrel) |
|
FILE *out; |
|
|
struct logrel_relation *lrel; |
|
569 |
{ |
{ |
570 |
FPRINTF(out,"%d",logrel_sindex(lrel)); |
FPRINTF(out,"%d",logrel_sindex(lrel)); |
571 |
} |
} |
572 |
|
|
573 |
#ifdef NEWSTUFF |
#ifdef NEWSTUFF |
574 |
void slv_print_obj_index(out,obj) |
void slv_print_obj_index(FILE *out, obj_objective_t obj) |
|
FILE *out; |
|
|
struct rel_relation *rel; |
|
575 |
{ |
{ |
576 |
FPRINTF(out,"%d",obj_index(obj)); |
FPRINTF(out,"%d",obj_index(obj)); |
577 |
} |
} |
580 |
#define destroy_array(p) \ |
#define destroy_array(p) \ |
581 |
if( (p) != NULL ) ascfree((p)) |
if( (p) != NULL ) ascfree((p)) |
582 |
|
|
|
int slv_direct_solve(slv_system_t server, struct rel_relation *rel, |
|
|
struct var_variable *var, FILE *fp, |
|
|
real64 epsilon, int ignore_bounds, int scaled) |
|
583 |
/** |
/** |
584 |
*** Attempt to directly solve the given relation (equality constraint) for |
*** Attempt to directly solve the given relation (equality constraint) for |
585 |
*** the given variable, leaving the others fixed. Returns an integer |
*** the given variable, leaving the others fixed. Returns an integer |
591 |
*** |
*** |
592 |
*** The variable bounds will be upheld, unless they are to be ignored. |
*** The variable bounds will be upheld, unless they are to be ignored. |
593 |
**/ |
**/ |
594 |
|
int slv_direct_solve(slv_system_t server, struct rel_relation *rel, |
595 |
|
struct var_variable *var, FILE *fp, |
596 |
|
real64 epsilon, int ignore_bounds, int scaled) |
597 |
{ |
{ |
598 |
int32 able,status; |
int32 able, status; |
599 |
int nsolns,allsolns; |
int nsolns, allsolns; |
600 |
real64 *slist,save; |
real64 *slist, save; |
601 |
|
|
602 |
slist = relman_directly_solve_new(rel,var,&able,&nsolns,epsilon); |
slist = relman_directly_solve_new(rel,var,&able,&nsolns,epsilon); |
603 |
if( !able ) { |
if( !able ) { |
613 |
save = var_value(var); |
save = var_value(var); |
614 |
var_set_value(var,var_lower_bound(var)); |
var_set_value(var,var_lower_bound(var)); |
615 |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
616 |
relman_eval(rel,&status,SAFE_FIX_ME); |
(void)relman_eval(rel,&status,SAFE_FIX_ME); |
617 |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
618 |
if (scaled) { |
if (scaled) { |
619 |
if( relman_calc_satisfied_scaled(rel,epsilon) ) break; |
if( relman_calc_satisfied_scaled(rel,epsilon) ) break; |
625 |
save = var_value(var); |
save = var_value(var); |
626 |
var_set_value(var,var_upper_bound(var)); |
var_set_value(var,var_upper_bound(var)); |
627 |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
628 |
relman_eval(rel,&status,SAFE_FIX_ME); |
(void)relman_eval(rel,&status,SAFE_FIX_ME); |
629 |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
630 |
if (scaled) { |
if (scaled) { |
631 |
if( relman_calc_satisfied_scaled(rel,epsilon) ) break; |
if( relman_calc_satisfied_scaled(rel,epsilon) ) break; |
636 |
} else { |
} else { |
637 |
var_set_value(var,slist[nsolns]); |
var_set_value(var,slist[nsolns]); |
638 |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPush(SIGFPE,SIG_IGN); |
639 |
relman_eval(rel,&status,SAFE_FIX_ME); |
(void)relman_eval(rel,&status,SAFE_FIX_ME); |
640 |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
Asc_SignalHandlerPop(SIGFPE,SIG_IGN); |
641 |
break; |
break; |
642 |
} |
} |
657 |
} |
} |
658 |
|
|
659 |
|
|
|
int slv_direct_log_solve(slv_system_t server, struct logrel_relation *lrel, |
|
|
struct dis_discrete *dvar, FILE *fp, int perturb, |
|
|
struct gl_list_t *insts) |
|
660 |
/** |
/** |
661 |
*** Attempt to directly solve the given relation (equality constraint) for |
*** Attempt to directly solve the given relation (equality constraint) for |
662 |
*** the given variable, leaving the others fixed. Returns an integer |
*** the given variable, leaving the others fixed. Returns an integer |
668 |
*** of the variable and display an error message. |
*** of the variable and display an error message. |
669 |
*** -1 ==> No solution found. |
*** -1 ==> No solution found. |
670 |
**/ |
**/ |
671 |
|
int slv_direct_log_solve(slv_system_t server, struct logrel_relation *lrel, |
672 |
|
struct dis_discrete *dvar, FILE *fp, int perturb, |
673 |
|
struct gl_list_t *insts) |
674 |
{ |
{ |
675 |
int32 able; |
int32 able; |
676 |
int32 nsolns, c; |
int32 nsolns, c; |
699 |
} |
} |
700 |
} |
} |
701 |
|
|
702 |
|
#endif /* SLV_INSTANCES */ |
703 |
|
|
704 |
#endif |
int32 **slv_lnkmap_from_mtx(mtx_matrix_t mtx, mtx_region_t *clientregion) |
|
|
|
|
int32 **slv_lnkmap_from_mtx(mtx_matrix_t mtx, int32 len, int32 m) |
|
705 |
{ |
{ |
706 |
int32 **map,*data,rl; |
int32 **map, *data, rl, order; |
707 |
real64 val; |
real64 val; |
708 |
mtx_coord_t coord; |
mtx_coord_t coord; |
709 |
|
mtx_range_t range; |
710 |
|
mtx_region_t region; |
711 |
|
|
712 |
if (mtx==NULL) { |
if (mtx == NULL) { |
713 |
FPRINTF(stderr,"Warning: slv_lnkmap_from_mtx called with null mtx\n"); |
FPRINTF(stderr,"Warning: slv_lnkmap_from_mtx called with null mtx\n"); |
714 |
return NULL; |
return NULL; |
715 |
} |
} |
716 |
data=(int32 *)ascmalloc((m+2*len)*sizeof(int32)); |
|
717 |
map=(int **)ascmalloc(m*sizeof(void *)); |
order = mtx_order(mtx); |
718 |
for(coord.row=0; coord.row < m; coord.row ++) { |
if (clientregion != NULL) { |
719 |
rl=mtx_nonzeros_in_row(mtx,coord.row,mtx_ALL_COLS); |
if ((clientregion->row.low < 0) || |
720 |
map[coord.row]=data; |
(clientregion->row.high > (order-1)) || |
721 |
data[0]=rl; |
(clientregion->col.low < 0) || |
722 |
|
(clientregion->col.high > (order-1))) { |
723 |
|
FPRINTF(stderr,"Warning: slv_lnkmap_from_mtx called with null or invalid region\n"); |
724 |
|
return NULL; |
725 |
|
} |
726 |
|
mtx_region(®ion, clientregion->row.low, clientregion->row.high, |
727 |
|
clientregion->col.low, clientregion->col.high); |
728 |
|
} else { |
729 |
|
mtx_region(®ion, 0, order-1, 0, order-1); |
730 |
|
} |
731 |
|
|
732 |
|
range.low = region.col.low; |
733 |
|
range.high = region.col.high; |
734 |
|
|
735 |
|
data = (int32 *)ascmalloc((order+2*mtx_nonzeros_in_region(mtx, ®ion))*sizeof(int32)); |
736 |
|
if (NULL == data) { |
737 |
|
return NULL; |
738 |
|
} |
739 |
|
map = (int32 **)ascmalloc(order*sizeof(int32 *)); |
740 |
|
if (NULL == map) { |
741 |
|
ascfree(data); |
742 |
|
return NULL; |
743 |
|
} |
744 |
|
for (coord.row=0 ; coord.row<region.row.low ; ++coord.row) { |
745 |
|
map[coord.row] = data; |
746 |
|
data[0] = 0; |
747 |
|
++data; |
748 |
|
} |
749 |
|
for(coord.row=region.row.low ; coord.row <= region.row.high ; coord.row ++) { |
750 |
|
rl = mtx_nonzeros_in_row(mtx, coord.row, &range); |
751 |
|
map[coord.row] = data; |
752 |
|
data[0] = rl; |
753 |
data++; |
data++; |
754 |
coord.col=mtx_FIRST; |
coord.col = mtx_FIRST; |
755 |
while( val=mtx_next_in_row(mtx,&coord,mtx_ALL_COLS), |
while( val = mtx_next_in_row(mtx, &coord, &range), |
756 |
coord.col != mtx_LAST) { |
coord.col != mtx_LAST) { |
757 |
data[0]=coord.col; |
data[0] = coord.col; |
758 |
data[1]= (int32)ascnint(val); |
data[1] = (int32)ascnint(val); |
759 |
data+=2; |
data += 2; |
760 |
} |
} |
761 |
} |
} |
762 |
|
for (coord.row=(region.row.high+1) ; coord.row<order ; ++coord.row) { |
763 |
|
map[coord.row] = data; |
764 |
|
data[0] = 0; |
765 |
|
++data; |
766 |
|
} |
767 |
return map; |
return map; |
768 |
} |
} |
769 |
int32 **slv_create_lnkmap(int m, int n, int len, int *hi, int *hj) { |
|
770 |
|
int32 **slv_create_lnkmap(int m, int n, int len, int *hi, int *hj) |
771 |
|
{ |
772 |
mtx_matrix_t mtx; |
mtx_matrix_t mtx; |
773 |
mtx_coord_t coord; |
mtx_coord_t coord; |
774 |
int32 i, **map; |
int32 i, **map; |
775 |
|
|
776 |
mtx=mtx_create(); |
mtx = mtx_create(); |
777 |
|
if (NULL == mtx) { |
778 |
|
FPRINTF(stderr,"Warning: slv_create_lnkmap called with null mtx\n"); |
779 |
|
return NULL; |
780 |
|
} |
781 |
mtx_set_order(mtx,MAX(m,n)); |
mtx_set_order(mtx,MAX(m,n)); |
782 |
for (i=0;i <len; i++) { |
for (i=0 ; i<len ; i++) { |
783 |
coord.row=hi[i]; |
if ((hi[i] >= m) || (hj[i] >= n)) { |
784 |
coord.col=hj[i]; |
FPRINTF(stderr,"Warning: index out of range in slv_create_lnkmap\n"); |
785 |
|
mtx_destroy(mtx); |
786 |
|
return NULL; |
787 |
|
} |
788 |
|
coord.row = hi[i]; |
789 |
|
coord.col = hj[i]; |
790 |
mtx_fill_value(mtx,&coord,(real64)i); |
mtx_fill_value(mtx,&coord,(real64)i); |
791 |
} |
} |
792 |
map=slv_lnkmap_from_mtx(mtx,len,m); |
map = slv_lnkmap_from_mtx(mtx,mtx_ENTIRE_MATRIX); |
793 |
mtx_destroy(mtx); |
mtx_destroy(mtx); |
794 |
return map; |
return map; |
795 |
} |
} |
796 |
|
|
797 |
void slv_destroy_lnkmap(int32 **map) { |
|
798 |
|
void slv_destroy_lnkmap(int32 **map) |
799 |
|
{ |
800 |
if (NOTNULL(map)) { |
if (NOTNULL(map)) { |
801 |
ascfree(map[0]); |
ascfree(map[0]); |
802 |
ascfree(map); |
ascfree(map); |
803 |
} |
} |
804 |
} |
} |
805 |
|
|
806 |
void slv_write_lnkmap(FILE *fp, int32 m, int32 **map) { |
void slv_write_lnkmap(FILE *fp, int32 m, int32 **map) |
807 |
|
{ |
808 |
int32 i,j,nv, *v; |
int32 i,j,nv, *v; |
809 |
if (ISNULL(map)) { |
if (ISNULL(map)) { |
810 |
FPRINTF(stderr,"slv_write_lnkmap: Cannot write NULL lnkmap\n"); |
FPRINTF(stderr,"slv_write_lnkmap: Cannot write NULL lnkmap\n"); |