1 /*
2
3 Copyright (C) 2008-2021 Michele Martone
4
5 This file is part of librsb.
6
7 librsb is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 librsb is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with librsb; see the file COPYING.
19 If not, see <http://www.gnu.org/licenses/>.
20
21 */
22 /* @cond INNERDOC */
23 /*!
24 * @file
25 * @author Michele Martone
26 * @brief
27 * This source file contains postscript rendering functions.
28 * */
29
30 #include "rsb_internals.h"
31
32 RSB_INTERNALS_COMMON_HEAD_DECLS
33
34 typedef float rsb_rf_t; /* real float */
35 #define RSB_RR_LEVELS 16
36
37 #define RSB_PRINTF_MATRIX_TIME_ARGS(MTXAP) \
38 "ect: %5.2le"" " \
39 "est: %5.2le"" " \
40 "sat: %5.2le"" " \
41 "eit: %5.2le"" " \
42 "cpt: %5.2le" \
43 , \
44 (MTXAP)->ect, (MTXAP)->est, (MTXAP)->sat, (MTXAP)->eit, (MTXAP)->cpt
45
46 #define RSB_EPS_TRSL(DX,DY,SX,SY,XS,YS,MTXAP) DX = XS*(/*(MTXAP)->nc-*/(SX)); DY = YS*((MTXAP)->nr-(SY)); /* translate for EPS */
47 #define RSB_MTX_EFF_R(MTXAP) (MTXAP->bm-((MTXAP)->broff-(MTXAP)->roff)) /* effective rows count */
48 #define RSB_MTX_EFF_C(MTXAP) (MTXAP->bk-((MTXAP)->bcoff-(MTXAP)->coff)) /* effective columns count */
49 #define RSB_MTX_LAR(MTXAP) ((MTXAP)->roff+(MTXAP)->bm) /* last absolute row */
50 #define RSB_MTX_LAC(MTXAP) ((MTXAP)->coff+(MTXAP)->bk) /* last absolute column */
51 #define RSB_MTX_LER(MTXAP) ((MTXAP)->broff-(MTXAP)->roff) /* local empty rows */
52 #define RSB_MTX_LEC(MTXAP) ((MTXAP)->bcoff-(MTXAP)->coff) /* local empty columns */
53 #define RSB_EPS_NEWPATH "N" /* newpath */
54 #define RSB_EPS_MOVETO "M" /* moveto */
55 #define RSB_EPS_LINETO "L" /* lineto */
56 #define RSB_EPS_RLINETO "R" /* rlineto */
57 #define RSB_EPS_SCALEFONT "SCF" /* scalefont */
58 #define RSB_EPS_SETFONT "SF" /* setfont */
59 #define RSB_EPS_SETRGB "SRGB" /* setrgbcolor */
60 #define RSB_EPS_SETLINEWIDTH "SLW" /* setlinewidth */
61 #define RSB_EPS_CLOSEPATH "C" /* closepath */
62
render_ps_box(FILE * fd,int r0,int c0,int dr,int dc,rsb_coo_idx_t orows,rsb_rf_t xs,rsb_rf_t ys,rsb_rf_t r,rsb_rf_t g,rsb_rf_t b)63 static rsb_err_t render_ps_box(FILE*fd, int r0, int c0, int dr, int dc, rsb_coo_idx_t orows, rsb_rf_t xs, rsb_rf_t ys, rsb_rf_t r, rsb_rf_t g, rsb_rf_t b)
64 {
65 /**
66 \ingroup gr_internals
67 Prints out a box in the postscript language.
68
69 \param r0 the box base row
70 \param c0 the box base column
71 \param dr the box height
72 \param dc the box width
73 \param orows the box offset row
74 \param xs the scale on x (rows)
75 \param ys the scale on y (column)
76 \param r red value
77 \param g green value
78 \param b blue value
79 */
80 #if RSB_ALLOW_STDOUT
81 RSB_FPRINTF(fd,
82 "newpath\n"
83 "%g %g "RSB_EPS_MOVETO"\n"
84 "%g %d "RSB_EPS_RLINETO"\n"
85 "%d %g "RSB_EPS_RLINETO"\n"
86 "%g %d "RSB_EPS_RLINETO"\n"
87 "%d %d "RSB_EPS_RLINETO"\n"
88 RSB_EPS_CLOSEPATH"\n"
89 "%g %g %g "RSB_EPS_SETRGB"\n"
90 "1 "RSB_EPS_SETLINEWIDTH"\n"
91 "stroke\n\n"
92 ,
93 c0*xs,(orows-r0)*ys,
94 (dc)*xs, 0,
95 0, -(dr)*ys,
96 -(dc)*xs, 0,
97 /* c0*xs,(orows-r0)*ys,
98 (submatrix->nc)*xs, 0,
99 0, -(submatrix->nr)*ys,
100 -(submatrix->nc)*xs, 0,*/
101 0, 0,
102 r, g, b
103 );
104 return RSB_ERR_NO_ERROR;
105 #else /* RSB_ALLOW_STDOUT */
106 return RSB_ERR_UNSUPPORTED_FEATURE;
107 #endif /* RSB_ALLOW_STDOUT */
108 }
109
rsb_dump_postscript_z_curve(FILE * fd,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t roff,rsb_coo_idx_t coff,rsb_rf_t xs,rsb_rf_t ys,rsb_coo_idx_t orows,int level,int * p,int * pv)110 static rsb_err_t rsb_dump_postscript_z_curve(FILE*fd, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t roff, rsb_coo_idx_t coff, rsb_rf_t xs, rsb_rf_t ys, rsb_coo_idx_t orows, int level,int * p, int * pv)
111 {
112 /**
113 \ingroup gr_internals
114 */
115 #if RSB_ALLOW_STDOUT
116 rsb_submatrix_idx_t i,j;
117 struct rsb_mtx_t * submatrix=NULL;
118 const int levels = RSB_RR_LEVELS;
119 const int want_eb=0;/* effective boundaries (FIXME: option currently unfinished) */
120
121 if(!mtxAp)
122 {
123 goto err;
124 }
125
126 if(level>=levels-1)
127 level=levels;
128
129 #if 1
130 if(pv)
131 {
132 rsb_submatrix_idx_t smi=0;
133 RSB_SUBMATRIX_FOREACH_LEAF_PERMUTED(mtxAp,submatrix,smi,pv)
134 //RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
135 {
136 rsb_dump_postscript_z_curve(fd,submatrix,submatrix->roff,submatrix->coff,xs,ys,orows,level+1,p,NULL);
137
138 if(smi<mtxAp->all_leaf_matrices_n-1)
139 {
140 rsb_rf_t fcoff=(rsb_rf_t)submatrix->coff;
141 rsb_rf_t froff=(rsb_rf_t)submatrix->roff;
142 rsb_rf_t fnc=(rsb_rf_t)submatrix->nc;
143 rsb_rf_t fnr=(rsb_rf_t)submatrix->nr;
144 rsb_rf_t shade= .8 - (.8*smi)/(mtxAp->all_leaf_matrices_n);
145
146 if(want_eb)
147 {
148 fcoff=(rsb_rf_t)submatrix->bcoff;
149 froff=(rsb_rf_t)submatrix->broff;
150 fnc=(rsb_rf_t)submatrix->bm;
151 fnr=(rsb_rf_t)submatrix->bk;
152 }
153
154 RSB_FPRINTF(fd,"%g %g %g "RSB_EPS_SETRGB" 1 "RSB_EPS_SETLINEWIDTH" stroke "RSB_EPS_NEWPATH" %g %g "RSB_EPS_MOVETO"\n",
155 shade,shade,1.0, (fcoff*xs+fnc*(xs/2)), ((-froff+orows))*ys-(fnr)*(ys/2));
156 }
157
158 }
159 goto ret;
160 }
161 #endif
162
163 if(rsb__is_terminal_recursive_matrix(mtxAp))
164 {
165 rsb_coo_idx_t scoff=coff;
166 rsb_coo_idx_t sroff=roff;
167 rsb_coo_idx_t snc=mtxAp->nc;
168 rsb_coo_idx_t snr=mtxAp->nr;
169 const int want_sc = 1;/* want submatrix comments */
170
171 if(want_eb)
172 {
173 sroff=roff+RSB_MTX_LER(mtxAp);
174 scoff=coff+RSB_MTX_LEC(mtxAp);
175 snr=mtxAp->bm;
176 snc=mtxAp->bk;
177 }
178
179 if(want_sc)
180 RSB_FPRINTF(fd,"%% matrix at %d %d, level %d, xs %g, ys %g, orows %d\n",sroff,scoff,level,xs,ys,orows);
181 if(*p>0)
182 RSB_FPRINTF(fd, "%g %g "RSB_EPS_LINETO"\n" , scoff*xs+snc*(xs/2), ((rsb_rf_t)(orows-sroff))*ys-((rsb_rf_t)snr)*(ys/2));
183 else
184 RSB_FPRINTF(fd, "%g %g "RSB_EPS_MOVETO"\n" , scoff*xs+snc*(xs/2), ((rsb_rf_t)(orows-sroff))*ys-((rsb_rf_t)snr)*(ys/2));
185 ++*p;
186 }
187 else
188 {
189 RSB_SUBMATRIX_FOREACH(mtxAp,submatrix,i,j)
190 if(submatrix)
191 {
192 // rsb_coo_idx_t scoff=submatrix->coff;
193 // rsb_coo_idx_t sroff=submatrix->roff;
194 rsb_coo_idx_t snc=submatrix->nc;
195 rsb_coo_idx_t snr=submatrix->nr;
196
197 if(0)
198 if(want_eb)
199 {
200 // scoff=submatrix->bcoff;
201 // sroff=submatrix->broff;
202 // snr=submatrix->bm;
203 // snc=submatrix->bk;
204 }
205
206 rsb_dump_postscript_z_curve(fd,submatrix, roff+(i?(mtxAp->nr-snr):0), coff+(j?mtxAp->nc-snc:0),xs,ys,orows, level+1,p,NULL);
207 }
208 }
209 ret:
210 return RSB_ERR_NO_ERROR;
211 err:
212 return RSB_ERR_GENERIC_ERROR;
213 #else /* RSB_ALLOW_STDOUT */
214 return RSB_ERR_UNSUPPORTED_FEATURE;
215 #endif /* RSB_ALLOW_STDOUT */
216 }
217
rsb__dump_postscript_ussv_order_curve(const struct rsb_mtx_t * mtxAp,rsb_rf_t xs,rsb_rf_t ys,int * p)218 static rsb_err_t rsb__dump_postscript_ussv_order_curve(const struct rsb_mtx_t * mtxAp, rsb_rf_t xs, rsb_rf_t ys, int * p)
219 {
220 /**
221 \ingroup gr_internals
222 NEW, EXPERIMENTAL
223 */
224 #if RSB_ALLOW_STDOUT
225 rsb_err_t errval = RSB_ERR_NO_ERROR;
226 struct rsb_translated_matrix_t * all_leaf_matrices=NULL;
227 rsb_submatrix_idx_t all_leaf_matrices_n=0,n;
228 FILE*fd = RSB_DEFAULT_FD;
229
230 if(!mtxAp)
231 {
232 goto err;
233 }
234
235 errval = rsb__do_get_submatrices_for_ussv(mtxAp,&all_leaf_matrices,&all_leaf_matrices_n,RSB_TRANSPOSITION_N);
236 if(!all_leaf_matrices || RSB_SOME_ERROR(errval))
237 {
238 errval = RSB_ERR_ENOMEM;
239 RSB_PERR_GOTO(err,RSB_ERRM_ES);
240 }
241
242 if(RSB_SOME_ERROR(errval))
243 { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
244
245 RSB_FPRINTF(fd,"%%%%there are %d leaves, %d for ussv\n",mtxAp->all_leaf_matrices_n,all_leaf_matrices_n);
246 #if 1
247 for(n=0;n<all_leaf_matrices_n;++n)
248 {
249 rsb_coo_idx_t rows=all_leaf_matrices[n].nr;
250 rsb_coo_idx_t cols=all_leaf_matrices[n].nc;
251 rsb_coo_idx_t roff=all_leaf_matrices[n].roff;
252 rsb_coo_idx_t coff=all_leaf_matrices[n].coff;
253 rsb_coo_idx_t my=mtxAp->nr-((roff+rows/2));
254 rsb_coo_idx_t mx=(coff+cols/2);
255 rsb_rf_t mys=my;
256 rsb_rf_t mxs=mx;
257 mys*=ys/mtxAp->nc;
258 mxs*=xs/mtxAp->nr;
259 // my/=mtxAp->cols;
260 RSB_FPRINTF(fd,"%% matrix %d at %d %d, %d x %d \n",n,roff,coff,rows,cols);
261 if(*p>0)
262 RSB_FPRINTF(fd, "%g %g "RSB_EPS_LINETO"\n" , mxs, mys);
263 else
264 RSB_FPRINTF(fd, "%g %g "RSB_EPS_MOVETO"\n" , mxs, mys);
265 ++*p;
266 }
267 #endif
268 err:
269 RSB_CONDITIONAL_FREE(all_leaf_matrices);
270 RSB_DO_ERR_RETURN(errval)
271 #else /* RSB_ALLOW_STDOUT */
272 RSB_DO_ERR_RETURN(RSB_ERR_UNSUPPORTED_FEATURE)
273 #endif /* RSB_ALLOW_STDOUT */
274 }
275
rsb__dump_postscript(const int argc,char * const argv[])276 int rsb__dump_postscript(const int argc, char * const argv[])
277 {
278 /**
279 \ingroup gr_internals
280 */
281 rsb_err_t errval = RSB_ERR_NO_ERROR;
282 rsb_option options[] = {
283 {"matrix-filename", required_argument, NULL, 0x66},/* f */
284 {"dump-recursion", no_argument, NULL, 'd'},/* NEW */
285 {"width",required_argument , NULL, 0x5757},/* W */
286 {"height",required_argument , NULL, 0x4848}, /* H */
287 {"auto-size",no_argument , NULL, 'a'},
288 {"block-dump",no_argument , NULL, 'B'},
289 {"nonzeros-dump",no_argument, NULL, 'N'},
290 {"block-rowsize", required_argument, NULL, 0x72 },/* r */
291 {"block-columnsize", required_argument, NULL, 0x63},/* c */
292 {"z-dump", no_argument, NULL, 'z'},
293 {"ussv-dump", no_argument, NULL, 'S'},
294 RSB_BENCH_PROG_OPTS
295 {0,0,0,0}
296 };
297
298 #ifdef RSB_NUMERICAL_TYPE_FLOAT
299 rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE ;
300 #else /* RSB_NUMERICAL_TYPE_FLOAT */
301 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
302 rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE ;
303 #else /* RSB_NUMERICAL_TYPE_DOUBLE */
304 rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
305 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
306 #endif /* RSB_NUMERICAL_TYPE_FLOAT */
307 rsb_blk_idx_t br=1;
308 rsb_blk_idx_t bc=1;
309
310 const char * filename=NULL;
311 int c,w = RSB_DEFAULT_MATRIX_RENDERING_COLS,h = RSB_DEFAULT_MATRIX_RENDERING_ROWS;
312 int opt_index = 0;
313 int dump_recursion=0;
314 int g_auto_size=0;
315 rsb_bool_t want_blocks=0,want_nonzeros=0,z_dump=0;
316
317 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
318
319 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS))!=RSB_ERR_NO_ERROR)
320 {
321 RSB_PERR_GOTO(err,RSB_ERRM_ES);
322 }
323
324 for (;;)
325 {
326 c = rsb_getopt_long(argc,argv,RSB_SAMPLE_PROGRAM_OPTIONS_GET_FLAGS"ar:c:df:BNzSn:"/*"W:H:"*/,options,&opt_index);
327 if (c == -1)
328 break;
329 RSB_DO_FLAG_ADD(flags,rsb__sample_program_options_get_flags(c,optarg)); /* FIXME : NEW */
330 switch (c)
331 {
332 case 'r':
333 br = rsb__util_atoi(optarg);
334 if(br<1) { errval = RSB_ERR_BADARGS; RSB_PERR_GOTO(err,RSB_ERRM_ES); }
335 break;
336 case 'c':
337 bc = rsb__util_atoi(optarg);
338 if(br<1) { errval = RSB_ERR_BADARGS; RSB_PERR_GOTO(err,RSB_ERRM_ES); }
339 break;
340 case 'f':
341 filename = optarg;
342 break;
343 case 'N':
344 want_nonzeros=1;
345 break;
346 case 'B':
347 want_blocks=1;
348 break;
349 case 'a':
350 g_auto_size=1;
351 break;
352 case 'd':
353 dump_recursion=1;
354 break;
355 case 'S':
356 z_dump=2;
357 RSB_DO_FLAG_ADD(flags,RSB_FLAG_LOWER_TRIANGULAR);
358 break;
359 case 'z':
360 z_dump=1;
361 break;
362 case 0x4848:
363 h = rsb__util_atoi(optarg);
364 if(h<1) { errval = RSB_ERR_BADARGS; RSB_PERR_GOTO(err,RSB_ERRM_ES); }
365 break;
366 case 0x5757:
367 w = rsb__util_atoi(optarg);
368 if(w<1) { errval = RSB_ERR_BADARGS; RSB_PERR_GOTO(err,RSB_ERRM_ES); }
369 break;
370 case 'T':
371 typecode = toupper(*optarg);
372 break;
373 case 'n':
374 #if 1
375 rsb__set_num_threads(rsb__util_atoi(optarg));
376 #else
377 {
378 rsb_thread_t ca_[1]={1};
379 rsb_thread_t * ca=ca_;
380 rsb_thread_t cn=1,ci=0;
381 ca=NULL;cn=0;
382 if(RSB_SOME_ERROR(errval = rsb__util_get_bx_array(optarg,&cn,&ca)))
383 {
384 RSB_PERR_GOTO(err,RSB_ERRM_ES);
385 }
386 }
387 #endif
388 default:
389 ;
390 }
391 }
392
393 if(!filename)
394 {
395 const char*usagestring=" -aRzd -f pd.mtx";
396 //errval = RSB_ERR_BADARGS;
397 RSB_INFO("Did not specify a matrix file.\n");
398 RSB_INFO("Usage example: %s %s\n",argv[0],usagestring);
399 //RSB_ERROR(RSB_ERRM_ES);
400 goto err;
401 }
402
403 RSB_DO_FLAG_DEL(flags,RSB_FLAG_EXPERIMENTAL_IN_PLACE_CSR); /* FIXME : breaks -r1 -c1 -Fbr -aRzD */
404 if(g_auto_size)
405 {
406 /* rescale smartly to reflect the desired area and keep proportions (but lose both dimensions) */
407 size_t cols,rows;
408 rsb_rf_t area=1,p;
409 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
410
411 if(RSB_SOME_ERROR(rsb__do_util_get_matrix_dimensions(filename, &cols, &rows, NULL, &flags)))
412 goto err;
413
414 area*=w;
415 area*=h;
416 p=((rsb_rf_t)cols)/((rsb_rf_t)rows);
417 h=sqrt(area/p);
418 w=h*p;
419 }
420
421 if(!dump_recursion)
422 want_nonzeros = 1;
423
424 errval = rsb__dump_postscript_recursion_from_matrix(filename,br,bc,w,h,flags,want_blocks,z_dump,want_nonzeros,dump_recursion,typecode);
425 err:
426 RSB_MASK_OUT_SOME_ERRORS(errval)
427 rsb__do_perror(NULL,errval);
428 return RSB_ERR_TO_PROGRAM_ERROR(errval);
429 }
430
rsb__dump_block_rectangles(FILE * fd,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t roff,rsb_coo_idx_t coff,rsb_rf_t xs,rsb_rf_t ys,rsb_coo_idx_t orows,int level)431 static rsb_err_t rsb__dump_block_rectangles(FILE*fd, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t roff, rsb_coo_idx_t coff, rsb_rf_t xs, rsb_rf_t ys, rsb_coo_idx_t orows, int level)
432 {
433 /**
434 */
435 #if RSB_ALLOW_STDOUT
436 rsb_submatrix_idx_t i,j;
437 struct rsb_mtx_t * submatrix = NULL;
438 const int levels = RSB_RR_LEVELS;
439 const int want_eb = 0;/* want effective boundaries (working) */
440 const int want_sc = 1;/* want submatrix comments */
441 rsb_rf_t shade;
442
443 if(!mtxAp)
444 {
445 goto err;
446 }
447
448 if(level>=levels-1)
449 level=levels;
450 shade = 1.0*(level)/levels;
451
452 if(want_sc)RSB_FPRINTF(fd,"%% matrix at %d %d, level %d\n",roff,coff,level);
453 if(rsb__is_terminal_recursive_matrix(mtxAp))
454 {
455 rsb_coo_idx_t eroff=mtxAp->broff,ecoff=mtxAp->bcoff;
456 rsb_coo_idx_t er=RSB_MTX_EFF_R(mtxAp),ec=RSB_MTX_EFF_C(mtxAp);
457 if(want_eb==0)
458 eroff=mtxAp->roff,ecoff=mtxAp->coff,er=mtxAp->nr,ec=mtxAp->nc;
459 if(want_sc)RSB_FPRINTF(fd,"%% terminal matrix at %d %d\n",roff,coff);
460 render_ps_box(fd,eroff, ecoff, er, ec, orows, xs, ys, shade, shade, shade);
461 }
462
463 RSB_SUBMATRIX_FOREACH(mtxAp,submatrix,i,j)
464 if(submatrix)
465 {
466 rsb__dump_block_rectangles(fd,submatrix, roff+(i?(mtxAp->nr-submatrix->nr):0), coff+(j?mtxAp->nc-submatrix->nc:0),xs,ys,orows, level+1);
467 }
468
469 return RSB_ERR_NO_ERROR;
470 err:
471 return RSB_ERR_GENERIC_ERROR;
472 #else /* RSB_ALLOW_STDOUT */
473 return RSB_ERR_UNSUPPORTED_FEATURE;
474 #endif /* RSB_ALLOW_STDOUT */
475 }
476
rsb__dump_postscript_recursion_from_mtx_t(FILE * fd,const char * filename,const struct rsb_mtx_t * mtxAp,rsb_blk_idx_t br,rsb_blk_idx_t bc,int width,int height,rsb_marf_t rflags,rsb_bool_t want_blocks,rsb_bool_t z_dump,rsb_bool_t want_nonzeros,int * pv)477 rsb_err_t rsb__dump_postscript_recursion_from_mtx_t(FILE*fd, const char * filename, const struct rsb_mtx_t*mtxAp, rsb_blk_idx_t br, rsb_blk_idx_t bc, int width, int height, rsb_marf_t rflags, rsb_bool_t want_blocks, rsb_bool_t z_dump, rsb_bool_t want_nonzeros, int *pv )
478 {
479 /*
480 * ( rflags == RSB_FLAG_NOFLAGS ) is allowed and implies defaults.
481 * */
482 rsb_err_t errval = RSB_ERR_NO_ERROR;
483 rsb_coo_idx_t nrA = mtxAp->nr, ncA = mtxAp->nc;
484 const int want_structure_comments_dump = 1;
485 rsb_rf_t xs, ys;
486
487 if(fd && filename)
488 {
489 errval = RSB_ERR_BADARGS;
490 RSB_PERR_GOTO(err,RSB_ERRM_ES);
491 }
492
493 if(filename)
494 {
495 fd = rsb__util_fopen(filename,"w");
496 if( fd == NULL )
497 {
498 errval=RSB_ERR_GENERIC_ERROR;
499 goto err;
500 }
501 }
502
503 ys = ((rsb_rf_t)height)/nrA, xs = ((rsb_rf_t)width)/ncA;
504 errval = rsb__do_print_postscript_header(fd, width, height, xs, ys );
505
506 if(want_structure_comments_dump)
507 {
508 RSB_POSTSCRIPT_DUMP_COMMENT(fd,RSB_PRINTF_MTX_SUMMARY_ARGS(mtxAp));
509 RSB_POSTSCRIPT_DUMP_COMMENT(fd,RSB_PRINTF_MATRIX_TIME_ARGS(mtxAp));
510 RSB_FPRINTF(fd,"%%%% ");
511 rsb__fprint_matrix_implementation_code(mtxAp, "", mtxAp->flags, fd);
512 RSB_FPRINTF(fd,"\n");
513 }
514
515 if( rflags == RSB_MARF_EPS_L )
516 {
517 struct rsb_mtx_t * submatrix = NULL;
518 rsb_submatrix_idx_t smi;
519 double mnnz = 0, annz = 0;
520 rsb_coo_idx_t hoo = -RSB_MIN(RSB_MIN(mtxAp->nr,mtxAp->nc)/1000,10); /* how much out; this shall turn some coloured lines inwards the box; on smaller matrices this shall be limited */
521
522 RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
523 mnnz = RSB_MAX(mnnz,submatrix->nnz),
524 annz += submatrix->nnz;
525 annz /= mtxAp->all_leaf_matrices_n;
526
527 RSB_FPRINTF(fd,"%% colored boxes dump\n");
528 RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
529 {
530 rsb_rf_t fx,fy;
531 double rv,gv,bv, iv;
532
533 RSB_EPS_TRSL(fx,fy,submatrix->bcoff,submatrix->broff,xs,ys,mtxAp);
534 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" %g %g "RSB_EPS_MOVETO" ",fx,fy);
535 RSB_FPRINTF(fd,"%g %g "RSB_EPS_RLINETO" ", xs*RSB_MTX_EFF_C(submatrix),0.0);
536 RSB_FPRINTF(fd,"%g %g "RSB_EPS_RLINETO" ",0.0,-ys*RSB_MTX_EFF_R(submatrix));
537 RSB_FPRINTF(fd,"%g %g "RSB_EPS_RLINETO" ",-xs*RSB_MTX_EFF_C(submatrix),0.0);
538
539 if(submatrix->nnz > annz)
540 iv = 0.3 * ( ( - annz + submatrix->nnz ) / submatrix->nnz ),
541 rv = gv = bv = 0.7,
542 rv+=iv;
543 else
544 iv = 0.3 * ( ( + annz - submatrix->nnz ) / annz ),
545 rv = gv = bv = 0.7,
546 gv+=iv;
547 RSB_FPRINTF(fd,RSB_EPS_CLOSEPATH" %g %g %g "RSB_EPS_SETRGB" 1 "RSB_EPS_SETLINEWIDTH" fill ",rv,gv,bv);
548 RSB_FPRINTF(fd,"%% submatrix %d square\n",smi);
549 }
550
551 RSB_FPRINTF(fd,"%% lhs dump\n");
552 RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
553 {
554 rsb_rf_t fx,fy,tx,ty;
555 /*
556 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" ");
557 RSB_EPS_TRSL(fx,fy,submatrix->coff ,submatrix->roff,xs,ys,mtxAp);
558 RSB_EPS_TRSL(tx,ty,0 ,submatrix->roff,xs,ys,mtxAp);
559 RSB_FPRINTF(fd,"%g %g "RSB_EPS_MOVETO" ",fx,fy);
560 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
561 px=tx,py=ty;
562 RSB_EPS_TRSL(fx,fy,submatrix->coff ,submatrix->roff+submatrix->nr,xs,ys,mtxAp);
563 RSB_EPS_TRSL(tx,ty,0 ,submatrix->roff+submatrix->nr,xs,ys,mtxAp);
564 RSB_FPRINTF(fd,"%g %g "RSB_EPS_MOVETO" ",fx,fy);
565 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
566
567 RSB_FPRINTF(fd,"closepath "); RSB_FPRINTF(fd,"1 0 1 "RSB_EPS_SETRGB" "); RSB_FPRINTF(fd,"1 setlinewidth "); RSB_FPRINTF(fd,"1 stroke ");
568 RSB_FPRINTF(fd,"%% submatrix %d to-lhs\n",smi);
569
570 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" ");
571 RSB_FPRINTF(fd,"%g %g "RSB_EPS_MOVETO" ",px,py);
572 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
573 RSB_FPRINTF(fd,"closepath "); RSB_FPRINTF(fd,"1 0 1 "RSB_EPS_SETRGB" "); RSB_FPRINTF(fd,"5 setlinewidth "); RSB_FPRINTF(fd,"1 stroke ");
574 RSB_FPRINTF(fd,"%% submatrix %d lhs\n",smi);
575 */
576
577 RSB_EPS_TRSL(fx,fy,-hoo+submatrix->bcoff,-hoo+submatrix->broff ,xs,ys,mtxAp);
578 RSB_EPS_TRSL(tx,ty,-hoo+submatrix->bcoff,-hoo+RSB_MTX_LAR(submatrix),xs,ys,mtxAp);
579 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" %g %g "RSB_EPS_MOVETO" %g %g "RSB_EPS_LINETO" ",fx,fy,tx,ty);
580 RSB_FPRINTF(fd,RSB_EPS_CLOSEPATH" 1 0 1 "RSB_EPS_SETRGB" 1 "RSB_EPS_SETLINEWIDTH" 1 stroke ");
581 RSB_FPRINTF(fd,"%% submatrix %d lhs\n",smi);
582 }
583
584 RSB_FPRINTF(fd,"%% rhs dump\n");
585 RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
586 {
587 rsb_rf_t fx,fy,tx,ty;
588 //rsb_rf_t ih = (RSB_DO_FLAG_HAS(submatrix->flags,RSB_FLAG_USE_HALFWORD_INDICES)) ? 1.0 : 0.0;
589 /*
590 RSB_FPRINTF(fd,"%% submatrix %d\n",smi);
591 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" ");
592
593 RSB_EPS_TRSL(fx,fy,submatrix->coff ,submatrix->roff,xs,ys,mtxAp);
594 RSB_EPS_TRSL(tx,ty,mtxAp->nr ,submatrix->coff,xs,ys,mtxAp);
595 RSB_FPRINTF(fd,"%g %g moveto ",fx,fy);
596 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
597 px=tx,py=ty;
598 RSB_EPS_TRSL(fx,fy,submatrix->coff+submatrix->nc,submatrix->roff, xs,ys,mtxAp);
599 RSB_EPS_TRSL(tx,ty,mtxAp->nr ,submatrix->coff+submatrix->nc,xs,ys,mtxAp);
600 RSB_FPRINTF(fd,"%g %g moveto ",fx,fy);
601 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
602 RSB_FPRINTF(fd,"closepath "); RSB_FPRINTF(fd,"0.5 1 0.5 setrgbcolor "); RSB_FPRINTF(fd,"1 setlinewidth "); RSB_FPRINTF(fd,"1 stroke ");
603 RSB_FPRINTF(fd,"%% submatrix %d to-rhs\n",smi);
604
605 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" ");
606 RSB_FPRINTF(fd,"%g %g moveto ",px,py);
607 RSB_FPRINTF(fd,"%g %g lineto ",tx,ty);
608 RSB_FPRINTF(fd,"closepath "); RSB_FPRINTF(fd,"0.5 1 0.5 setrgbcolor "); RSB_FPRINTF(fd,"5 setlinewidth "); RSB_FPRINTF(fd,"1 stroke ");
609 RSB_FPRINTF(fd,"%% submatrix %d rhs\n",smi);
610 */
611 RSB_EPS_TRSL(fx,fy,-hoo+submatrix->bcoff, -hoo+submatrix->broff,xs,ys,mtxAp);
612 RSB_EPS_TRSL(tx,ty,-hoo+submatrix->coff+submatrix->bk,-hoo+submatrix->broff,xs,ys,mtxAp);
613 RSB_FPRINTF(fd,RSB_EPS_NEWPATH" %g %g "RSB_EPS_MOVETO" %g %g "RSB_EPS_LINETO" ",fx,fy,tx,ty);
614 RSB_FPRINTF(fd,RSB_EPS_CLOSEPATH" .5 1 .5 "RSB_EPS_SETRGB" 1 "RSB_EPS_SETLINEWIDTH" 1 stroke ");
615 RSB_FPRINTF(fd,"%% submatrix %d rhs\n",smi);
616 }
617
618 RSB_FPRINTF(fd,"%% node content labels\n");
619 RSB_SUBMATRIX_FOREACH_LEAF(mtxAp,submatrix,smi)
620 {
621 rsb_rf_t ox,oy;
622 char fstr[RSB_MAX_STRERRLEN];
623 double fs;
624
625 RSB_EPS_TRSL(ox,oy,submatrix->coff,submatrix->roff+submatrix->nr/2,xs,ys,mtxAp);
626 sprintf(fstr," %d/%d %s%s %0.1e",1+smi,mtxAp->all_leaf_matrices_n,(RSB_DO_FLAG_HAS(submatrix->flags,RSB_FLAG_USE_HALFWORD_INDICES))?"H":"",(submatrix->matrix_storage == RSB_MATRIX_STORAGE_BCOR)?"COO":"CSR",(double)(submatrix->nnz));
627 fs = ( xs * submatrix->nc ) / ( strlen(fstr) ) * 1.3 ;
628 RSB_FPRINTF(fd,"/Courier-Bold findfont %g "RSB_EPS_SCALEFONT" "RSB_EPS_SETFONT" %g %g "RSB_EPS_MOVETO" (%s) 0 0 0 "RSB_EPS_SETRGB" show\n",fs,ox,oy,fstr);
629 }
630 }
631
632 RSB_POSTSCRIPT_DUMP_COMMENT(fd,"sparse blocks dump");
633 errval = rsb__dump_block_rectangles(fd,mtxAp,0,0,xs,ys,mtxAp->nr,0);
634
635 if(z_dump)
636 {
637 int p = 0;
638 RSB_POSTSCRIPT_DUMP_COMMENT(fd,"z dump\nnewpath");
639
640 if(z_dump==1)
641 errval = rsb_dump_postscript_z_curve(fd,mtxAp, 0,0,xs,ys,mtxAp->nr,0,&p,pv);
642 else
643 errval = rsb__dump_postscript_ussv_order_curve(mtxAp,(rsb_rf_t)height,(rsb_rf_t)width,&p);
644 RSB_FPRINTF(fd,
645 "%d %d %d setrgbcolor\n"
646 "1 setlinewidth\n"
647 "stroke\n\n"
648 ,
649 0,0,1
650 );
651 }
652 if(want_blocks)
653 ;/* dead code removed from here */
654 if(filename)
655 {
656 fclose(fd);
657 }
658 err:
659 return errval;
660 }
661
rsb_dump_postscript_from_coo(FILE * fd,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,void * VA,rsb_coo_idx_t m,rsb_coo_idx_t k,rsb_nnz_idx_t nnz,rsb_blk_idx_t br,rsb_blk_idx_t bc,int width,int height,rsb_bool_t all_nnz,rsb_type_t typecode)662 static rsb_err_t rsb_dump_postscript_from_coo(FILE*fd, rsb_coo_idx_t *IA, rsb_coo_idx_t *JA, void *VA, rsb_coo_idx_t m, rsb_coo_idx_t k, rsb_nnz_idx_t nnz, rsb_blk_idx_t br, rsb_blk_idx_t bc, int width, int height, rsb_bool_t all_nnz, rsb_type_t typecode)
663 {
664 /**
665 \ingroup gr_internals
666 Need better error handling.
667 This function is experimentally used to render the sparse matrix.
668 */
669 #if RSB_ALLOW_STDOUT
670 rsb_err_t errval = RSB_ERR_NO_ERROR;
671 rsb_nnz_idx_t n=0;
672 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
673 rsb_rf_t ys,xs;
674 rsb_rf_t csh,csw,dx=0.0,dy=0.0,rd=1.0;
675
676 RSB_DO_FLAG_ADD(flags,RSB_FLAG_WANT_BCSS_STORAGE) ;
677 RSB_DO_FLAG_ADD(flags,RSB_FLAG_SORTED_INPUT) ;
678
679 if(1)
680 {
681 rsb_coo_idx_t /* ri=0,ci=0,*/nr=m,nc=k;
682 rsb_nnz_idx_t nzi=0;
683 rsb_nnz_idx_t onnz=nnz;
684 // RSB_STDERR("%s","FIXME: this is functioning code to render PostScript spy plots; it just needs to be called the right way ..\n");
685 rsb_aligned_t max[RSB_CONST_ENOUGH_ALIGNED_FOR_ANY_TYPE];
686 rsb_aligned_t min[RSB_CONST_ENOUGH_ALIGNED_FOR_ANY_TYPE];
687 const int want_points_plot = 0; /* was 1 */
688
689 rsb__fill_with_ones(VA,typecode,nnz,1);
690 #if 1
691 while( (nnz>100000 || nr>512 || nc>512 ) && (nr>2 && nc>2))
692 {
693 /*
694 May be better to write a function *resize_to_nnz*.
695 This code is quite poor but does the job.
696 */
697 rsb_coo_idx_t nnr=nr/2, nnc=nc/2;
698 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
699 // RSB_DO_FLAG_ADD(flags,RSB_FLAG_SORTED_INPUT) ;
700 // RSB_STDERR("will rescale %d %d (%d nz) to %d %d...\n",nr,nc,nnz,nnr,nnc);
701 errval = rsb__mtx_as_pixmap_resize(VA,IA,JA,nnz,&nnz,nr,nc,nnr,nnc,typecode,flags);
702 RSB_DO_FLAG_ADD(flags,RSB_FLAG_SORTED_INPUT) ;
703 // nnz = rsb_weed_out_duplicates(IA,JA,VA,nnz,typecode,RSB_FLAG_DUPLICATES_SUM/*|RSB_FLAG_SORTED_INPUT*/);
704 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
705 nc=nnc; nr=nnr;
706 nnc/=2; nnr/=2;
707 }
708 #endif
709 #if 1
710 // if( (nnz>100000 || nr>height || nc>width ) && (nr>2 && nc>2))
711 if(1)
712 {
713 rsb_coo_idx_t nnr=height, nnc=width;
714 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
715 RSB_DO_FLAG_ADD(flags,RSB_FLAG_SORTED_INPUT) ;
716 // RSB_STDERR("will rescale further %d %d (%d nz) to %d %d...\n",nr,nc,nnz,nnr,nnc);
717 if(nnr>nr)
718 rd=((rsb_rf_t)nnr)/((rsb_rf_t)nr);
719 errval = rsb__mtx_as_pixmap_resize(VA,IA,JA,nnz,&nnz,nr,nc,nnr,nnc,typecode,flags);
720 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
721 nc=nnc; nr=nnr;
722 }
723 #endif
724 errval = rsb__util_sort_row_major_inner(VA,IA,JA,nnz,nr,nc, typecode,RSB_FLAG_NOFLAGS);
725 if(RSB_SOME_ERROR(errval))
726 {
727 RSB_ERROR(RSB_ERRM_ES); /* RSB_PERR_GOTO(err,RSB_ERRM_ES)*/ /*not a critical error; however shall emit a warning : */
728 }
729 nnz = rsb_weed_out_duplicates(IA,JA,VA,nnz,typecode,RSB_FLAG_DUPLICATES_SUM|RSB_FLAG_SORTED_INPUT);
730
731 RSB_FPRINTF(fd,""
732 "%%!PS-Adobe-3.0 EPSF-3.0\n"
733 "%%%%Creator: "RSB_PACKAGE_STRING"\n"
734 "%%%%Title: matrix spy plot (originally %d x %d / %d, here %d x %d/%d)\n"
735 "%%%%CreationDate: \n"
736 "%%%%DocumentData: Clean7Bit\n"
737 "%%%%Origin: 0 0\n"
738 "%%%%BoundingBox: 0 0 %d %d\n"
739 "%%%%LanguageLevel: 2\n"
740 "%%%%Pages: 1\n"
741 "%%%%Page: 1 1\n"
742 /* "0.5 0.5 0.5 setrgbcolor\n" */
743 ,m,k,onnz,nr,nc,nnz,nc,nr);
744 RSB_FPRINTF(fd,"save /$LIBRSB_DICT 3 dict def $LIBRSB_DICT begin /M {moveto} bind def /Z {gsave currentpoint lineto %g setlinewidth 1 setlinecap stroke grestore} bind def /D {M Z} bind def /K {0.5 0.5 setrgbcolor} bind def\n",rd);
745 RSB_FPRINTF(fd,"/R {rlineto} bind def\n");
746 RSB_FPRINTF(fd,"/N {newpath} bind def\n");
747 RSB_FPRINTF(fd,"/L {lineto} bind def\n");
748 RSB_FPRINTF(fd,"/C {closepath} bind def\n");
749 RSB_FPRINTF(fd,"/SLW {setlinewidth} bind def\n");
750 RSB_FPRINTF(fd,"/SRGB {setrgbcolor} bind def\n");
751 RSB_FPRINTF(fd,"/SCF {scalefont} bind def\n");
752 RSB_FPRINTF(fd,"/SF {setfont} bind def\n");
753 rsb__util_find_max(&max[0],VA,typecode,nnz,1);
754 rsb__util_find_min(&min[0],VA,typecode,nnz,1);
755 // RSB_STDERR("%lf %lf\n", *(double*)(&min[0]), *(double*)(&max[0]));
756 rsb__util_do_negate(&min[0],typecode,1);
757 rsb__util_vector_add(&max[0],&min[0],typecode,1);
758 // RSB_STDERR("%lf %lf\n", *(double*)(&min[0]), *(double*)(&max[0]));
759 if(RSB_IS_ELEMENT_NONZERO(&max[0],typecode))
760 rsb__vector_scale_inv(VA,&max[0],typecode,nnz); /* scale elements in [0,1] */
761 else
762 rsb__fill_with_ones(VA,typecode,nnz,1);
763
764 if(want_points_plot)
765 {
766 RSB_FPRINTF(fd,"%% dots plot\n");
767 for(nzi=0;nzi<nnz;++nzi)
768 {
769 // RSB_FPRINTF(fd,"%d %d D\n",IA[nzi],JA[nzi]);
770 // RSB_FPRINTF(fd,"%d %d D ",nr-1-IA[nzi],JA[nzi]);
771 rsb_rf_t cv=0.0;
772 RSB_NUMERICAL_TYPE_CAST_TO_ANY_P(rsb_rf_t,cv,typecode,VA,nzi);
773 // cv=1.0f-cv;
774 cv=0.5+cv/2.0; /* stronger */
775 //cv=0.0+cv/2;
776 // cv=0.5;
777 // gray ... red
778 // RSB_FPRINTF(fd,"%0.2f %0.2f %0.2f setrgbcolor\n",cv,0.5,0.5);
779 RSB_FPRINTF(fd,"%.2f K ",cv);
780 //RSB_FPRINTF(fd,"%d %d D ",nr-1-IA[nzi],JA[nzi]);
781 RSB_FPRINTF(fd,"%d %d D ",JA[nzi],nr-1-IA[nzi]);
782 if(nzi%32==0)
783 RSB_FPRINTF(fd,"\n");
784 }
785 }
786 // RSB_FPRINTF(fd,"gsave grestore showpage\n");
787 RSB_FPRINTF(fd,"stroke\n");
788 goto err;
789 }
790
791 if(!all_nnz)
792 {
793 /* rsb__mtx_as_pixmap_resize is optional */
794 if( RSB_SOME_ERROR(errval = rsb__mtx_as_pixmap_resize(VA, IA, JA, nnz, &nnz, m, k, height, width, typecode, flags)))
795 goto err;
796 }
797 /* if(m<=height)
798 ys=1.0;
799 else
800 ys=((rsb_rf_t)height)/m;
801 if(k<=width)
802 xs=1.0;
803 else*/
804 ys=((rsb_rf_t)height)/m;
805 xs=((rsb_rf_t)width)/k;
806 csw=ys;
807 csh=xs;
808
809 // {
810 // ys=((rsb_rf_t)height)/m;
811 // xs=((rsb_rf_t)width)/k;
812 // }
813 if(width>k)
814 dx=.1*csw, csw*=.8;
815 else
816 xs=csw=1.0;
817 if(height>m)
818 dy=.1*csh, csh*=.8;
819 else
820 ys=csh=1.0;
821 /*
822 if(height>m)
823 yps=ys*.8;
824 else
825 yps=ys;
826 if(width>m)
827 xps=xs*.8;
828 else
829 xps=xs;
830
831 if(!all_nnz)
832 {
833 m=height;
834 k=width;
835 }*/
836
837 rsb__do_print_postscript_header(fd, width, height, csw, csh);
838
839 RSB_FPRINTF(fd,"%%%% nnz dump\n");
840 RSB_FPRINTF(fd,"%%%% scales : %g %g\n",xs,ys);
841
842
843 if(xs>1.0) xs=1.0;
844 if(ys>1.0)ys=1.0;
845
846 for(n=0;n<nnz;++n)
847 {
848 RSB_FPRINTF(fd,"%%%% at : %d %d\n",(int)IA[n],(int)JA[n]);
849 RSB_FPRINTF(fd,
850 "%g %g translate\n"
851 ".85 .85 .85 csquare\n"
852 "-%g -%g translate\n"
853 , dx+((rsb_rf_t) (JA[n]))*xs, -dy+((rsb_rf_t)height)-((rsb_rf_t) (IA[n]))*ys
854 , dx+((rsb_rf_t) (JA[n]))*xs, -dy+((rsb_rf_t)height)-((rsb_rf_t) (IA[n]))*ys);
855 }
856
857 //RSB_FPRINTF(fd, "%%%%EOF\n");
858
859 err:
860 RSB_DO_ERR_RETURN(errval)
861 #else /* RSB_ALLOW_STDOUT */
862 RSB_DO_ERR_RETURN(RSB_ERR_UNSUPPORTED_FEATURE);
863 #endif /* RSB_ALLOW_STDOUT */
864 }
865
rsb__dump_postscript_recursion_from_matrix(const char * filename,rsb_blk_idx_t br,rsb_blk_idx_t bc,int width,int height,rsb_flags_t flags,rsb_bool_t want_blocks,rsb_bool_t z_dump,rsb_bool_t want_nonzeros,rsb_bool_t want_recursion,rsb_type_t typecode)866 rsb_err_t rsb__dump_postscript_recursion_from_matrix(const char * filename, rsb_blk_idx_t br, rsb_blk_idx_t bc, int width, int height, rsb_flags_t flags, rsb_bool_t want_blocks, rsb_bool_t z_dump , rsb_bool_t want_nonzeros, rsb_bool_t want_recursion, rsb_type_t typecode)
867 {
868 /**
869 \ingroup gr_internals
870 */
871 #if RSB_ALLOW_STDOUT
872 rsb_err_t errval = RSB_ERR_NO_ERROR;
873 rsb_coo_idx_t *IA=NULL, *JA=NULL;
874 void *VA=NULL;
875 rsb_coo_idx_t m=0,k=0;
876 rsb_nnz_idx_t nnz=0;
877 struct rsb_mtx_t * mtxAp=NULL;
878 FILE*fd = RSB_DEFAULT_FD;
879
880 if(!filename )
881 {
882 RSB_ERROR(RSB_ERRM_ES);
883 return RSB_ERR_BADARGS;
884 }
885
886 errval = rsb__util_mm_load_matrix_f(filename,&IA,&JA,&VA,&m,&k,&nnz,typecode,flags,NULL,NULL);
887 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
888
889 mtxAp = rsb__do_mtx_alloc_from_coo_const(VA,IA,JA,nnz,typecode,m,k,br,bc,flags,&errval);
890 if(!mtxAp || RSB_SOME_ERROR(errval))
891 {
892 RSB_PERR_GOTO(err,RSB_ERRM_ES);
893 }
894
895 if( want_nonzeros )
896 {
897 // RSB_POSTSCRIPT_DUMP_COMMENT(fd,"nonzeros structure dump");
898 errval = rsb_dump_postscript_from_coo(fd, IA, JA, VA, m, k, nnz, br, bc, width, height, want_nonzeros, typecode);
899 want_nonzeros = 0;
900 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
901 }
902
903 RSB_CONDITIONAL_FREE(IA);
904 RSB_CONDITIONAL_FREE(JA);
905 RSB_CONDITIONAL_FREE(VA);
906
907 if(want_recursion)
908 {
909 errval = rsb__dump_postscript_recursion_from_mtx_t(fd, NULL, mtxAp, br, bc, width, height, RSB_FLAG_NOFLAGS/* FIXME */, want_blocks, z_dump , 0 /*want_nonzeros*/, NULL );
910 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
911 }
912
913 RSB_MTX_FREE(mtxAp);/* we don't need it anymore here */
914
915 if( want_nonzeros )
916 {
917 RSB_POSTSCRIPT_DUMP_COMMENT(fd,"nonzeros structure dump");
918 errval = rsb__dump_postscript_from_matrix(filename, br, bc, width, height, 1);
919 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
920 }
921
922 errval = RSB_ERR_NO_ERROR;
923 goto ret;
924 err:
925 errval = RSB_ERR_GENERIC_ERROR;
926 ret:
927 RSB_CONDITIONAL_FREE(IA); RSB_CONDITIONAL_FREE(JA); RSB_CONDITIONAL_FREE(VA);
928 RSB_MTX_FREE(mtxAp);
929 return errval;
930 #else /* RSB_ALLOW_STDOUT */
931 return RSB_ERR_UNSUPPORTED_FEATURE;
932 #endif /* RSB_ALLOW_STDOUT */
933 }
934
rsb_dump_postscript_from_mtx_t(FILE * fd,const struct rsb_mtx_t * mtxAp,rsb_blk_idx_t br,rsb_blk_idx_t bc,int width,int height,rsb_bool_t all_nnz)935 static rsb_err_t rsb_dump_postscript_from_mtx_t(FILE*fd, const struct rsb_mtx_t*mtxAp, rsb_blk_idx_t br, rsb_blk_idx_t bc, int width, int height, rsb_bool_t all_nnz)
936 {
937 struct rsb_coo_matrix_t coo;
938 rsb_err_t errval = RSB_ERR_NO_ERROR;
939
940 RSB_INIT_COO_FROM_MTX(&coo,mtxAp);
941 if(rsb__allocate_coo_matrix_t(&coo)!=&coo)
942 {
943 RSB_PERR_GOTO(err,RSB_ERRM_ES);
944 }
945 errval = rsb__do_get_coo(mtxAp,(rsb_byte_t**)(&coo.VA),&coo.IA,&coo.JA,RSB_FLAG_NOFLAGS);
946 if(!RSB_SOME_ERROR(errval))
947 errval = rsb_dump_postscript_from_coo(fd, coo.IA, coo.JA, coo.VA, coo.nr, coo.nc, coo.nnz, br, bc, width, height, all_nnz, mtxAp->typecode);
948 if(RSB_SOME_ERROR(errval))
949 {
950 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
951 }
952 merr:
953 rsb__destroy_coo_matrix_t(&coo);
954 err:
955 return errval;
956 }
957
rsb__dump_postscript_from_matrix(const char * filename,rsb_blk_idx_t br,rsb_blk_idx_t bc,int width,int height,rsb_bool_t all_nnz)958 rsb_err_t rsb__dump_postscript_from_matrix(const char * filename, rsb_blk_idx_t br, rsb_blk_idx_t bc, int width, int height, rsb_bool_t all_nnz)
959 {
960 /**
961 \ingroup gr_internals
962 This function is experimentally used to render the sparse matrix.
963 Needs better error handling.
964 */
965 #if RSB_ALLOW_STDOUT
966 rsb_err_t errval = RSB_ERR_NO_ERROR;
967 rsb_coo_idx_t *IA=NULL, *JA=NULL;
968 void *VA=NULL;
969 rsb_coo_idx_t m=0,k=0;
970 rsb_nnz_idx_t nnz=0;
971 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
972 rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE ;
973 #else /* RSB_NUMERICAL_TYPE_DOUBLE */
974 rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
975 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
976 rsb_flags_t flags = RSB_FLAG_NOFLAGS;
977 rsb_time_t t=0;
978
979 RSB_DO_FLAG_ADD(flags,RSB_FLAG_WANT_BCSS_STORAGE) ;
980 RSB_DO_FLAG_ADD(flags,RSB_FLAG_SORTED_INPUT) ;
981
982 if(!filename )
983 return RSB_ERR_BADARGS;
984
985 t = - rsb_time();
986 if( RSB_SOME_ERROR(errval = rsb__util_mm_load_matrix_f(filename, &IA, &JA,&VA , &m, &k, &nnz , typecode, flags, NULL, NULL)) )
987 goto err;
988 t += rsb_time();
989
990 #if 1
991 errval = rsb_dump_postscript_from_coo(/*fd*/RSB_DEFAULT_FD, IA, JA, VA, m, k, nnz, br, bc, width, height, all_nnz, typecode);
992 #else
993 #if 0
994 {
995 RSB_STDERR("%s","FIXME: this is functioning code to render PostScript raster spy plots; it just needs the right place to be employed ..\n");
996 FILE*fd = RSB_DEFAULT_FD;
997 rsb_coo_idx_t ri=0,ci=0,nr=m,nc=k;
998 const rsb_coo_idx_t nnr=16/*0*2*/;
999 const rsb_coo_idx_t nnc=nc/(nr/nnr);
1000 rsb_nnz_idx_t nzi=0;
1001 errval = rsb__mtx_as_pixmap_resize(VA,IA,JA,nnz,&nnz,nr,nc,nnr,nnc,typecode,RSB_FLAG_NOFLAGS);
1002 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
1003 nc=nnc;
1004 nr=nnr;
1005 errval = rsb__util_sort_row_major_inner(VA,IA,JA,nnz,nr,nc, typecode,RSB_FLAG_NOFLAGS);
1006 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
1007 errval = rsb__util_compress_to_row_pointers_array(NULL,nnz,nr,RSB_FLAG_NOFLAGS,RSB_FLAG_NOFLAGS,IA);
1008 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
1009 // errval = rsb__do_switch_rsb_mtx_to_csr_sorted(mtxAp, &VA, &IA, &JA, RSB_FLAG_NOFLAGS);
1010 if(RSB_SOME_ERROR(errval)) { RSB_PERR_GOTO(err,RSB_ERRM_ES) }
1011 // RSB_POSTSCRIPT_DUMP_COMMENT(fd,"raster dump\n");
1012 RSB_FPRINTF(fd,""
1013 "%%!PS-Adobe-3.0 EPSF-3.0\n"
1014 "%%%%Creator: "RSB_PACKAGE_STRING"\n"
1015 "%%%%Title: matrix spy plot\n"
1016 "%%%%CreationDate: \n"
1017 "%%%%DocumentData: Clean7Bit\n"
1018 "%%%%Origin: 0 0\n"
1019 "%%%%BoundingBox: 0 0 %d %d\n"
1020 "%%%%LanguageLevel: 2\n"
1021 "%%%%Pages: 1\n"
1022 "%%%%Page: 1 1\n"
1023 ,nc,nr);
1024 RSB_FPRINTF(fd,"gsave\n""0 %d translate\n""%d %d scale\n""%d %d 8 [%d 0 0 -%d 0 0]\n"" {<",nr,nc,nr,nc,nr,nc,nr);
1025 for(ri=0;ri<nr;++ri)
1026 {
1027 rsb_coo_idx_t fc=0,lc=0;
1028 rsb_coo_idx_t crp=IA[ri],nrp=IA[ri+1];
1029 if(nrp==crp)
1030 lc=nc-1;
1031 else
1032 lc=JA[crp]-1;
1033 for(ci=fc;ci<=lc;++ci)
1034 RSB_FPRINTF(fd,"FF");
1035 for(nzi=crp;nzi<nrp;++nzi)
1036 {
1037 RSB_FPRINTF(fd,"00");
1038 fc=JA[nzi]+1;
1039 lc=fc-1;
1040 if(JA[nzi]==nc-1)
1041 lc=nc-1;
1042 else
1043 {
1044 if(nzi+1 < nrp)
1045 lc=JA[nzi+1]-1;
1046 else
1047 lc=nc-1;
1048 }
1049 for(ci=fc;ci<=lc;++ci)
1050 RSB_FPRINTF(fd,"FF");
1051 }
1052 RSB_FPRINTF(fd,"\n");
1053 }
1054 RSB_FPRINTF(fd,">}\n""image\n""grestore\n""showpage\n");
1055 }
1056 #else
1057 goto err;
1058 #endif
1059 #endif
1060 err:
1061 RSB_CONDITIONAL_FREE(IA);
1062 RSB_CONDITIONAL_FREE(JA);
1063 RSB_CONDITIONAL_FREE(VA);
1064 RSB_DO_ERR_RETURN(errval)
1065 #else /* RSB_ALLOW_STDOUT */
1066 RSB_DO_ERR_RETURN(RSB_ERR_UNSUPPORTED_FEATURE);
1067 #endif /* RSB_ALLOW_STDOUT */
1068 }
1069
rsb__do_mtx_render(const char * filename,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t pmWidth,rsb_coo_idx_t pmHeight,rsb_marf_t rflags)1070 rsb_err_t rsb__do_mtx_render(const char * filename, const struct rsb_mtx_t*mtxAp, rsb_coo_idx_t pmWidth, rsb_coo_idx_t pmHeight, rsb_marf_t rflags)
1071 {
1072 rsb_err_t errval = RSB_ERR_NO_ERROR;
1073
1074 if(!mtxAp)
1075 {
1076 errval = RSB_ERR_BADARGS;
1077 RSB_PERR_GOTO(err,RSB_ERRM_E_MTXAP);
1078 }
1079
1080 switch(rflags)
1081 {
1082 case(RSB_MARF_RGB):
1083 RSB_DO_ERROR_CUMULATE(errval,RSB_ERR_UNIMPLEMENTED_YET);
1084 break;
1085 case(RSB_MARF_EPS_L):
1086 case(RSB_MARF_EPS_B):
1087 case(RSB_MARF_EPS_S):
1088 case(RSB_MARF_EPS):
1089 {
1090 FILE * fd = NULL;
1091 rsb_time_t dt = rsb_time();
1092 /* filename = filename ? filename : RSB_DEFAULT_DUMPFILENAME; */
1093 if( ! filename )
1094 {
1095 fd = RSB_DEFAULT_FD;
1096 }
1097 else
1098 fd = rsb__util_fopen(filename,"w");
1099
1100 if( rflags == RSB_MARF_EPS || rflags == RSB_MARF_EPS_S || rflags == RSB_MARF_EPS_L )
1101 RSB_DO_ERROR_CUMULATE(errval,rsb_dump_postscript_from_mtx_t(fd,mtxAp,1,1,pmWidth,pmHeight,1));
1102 if( rflags == RSB_MARF_EPS || rflags == RSB_MARF_EPS_B || rflags == RSB_MARF_EPS_L )
1103 RSB_DO_ERROR_CUMULATE(errval,rsb__dump_postscript_recursion_from_mtx_t(fd,NULL,mtxAp,1,1,pmWidth,pmHeight,rflags,0,1,0,NULL));
1104 if( fd )
1105 {
1106 dt = rsb_time() - dt;
1107 RSB_FPRINTF(fd,"%% rendering time ~ %lg s\n",dt);
1108 }
1109
1110 if( filename )
1111 fclose(fd);
1112 }
1113 break;
1114 default: {errval = RSB_ERR_UNIMPLEMENTED_YET; goto err;}
1115 }
1116 err:
1117 return errval;
1118 }
1119
1120 /* @endcond */
1121