2 * Grace - GRaphing, Advanced Computation and Exploration of data
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-2003 Grace Development Team
9 * Maintained by Evgeny Stambulchik
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * routines to allocate, manipulate, and return
32 * information about sets.
40 #include "core_utils.h"
45 * same as copyset(), but doesn't alter the to set appearance
47 int copysetdata(Quark
*psrc
, Quark
*pdest
)
49 Dataset
*dsp
= set_get_dataset(psrc
);
51 return set_set_dataset(pdest
, dsp
);
55 * get the min/max fields of a set
57 int getsetminmax(Quark
**sets
, int nsets
,
58 double *xmin
, double *xmax
, double *ymin
, double *ymax
)
62 if (nsets
< 1 || !sets
) {
63 return RETURN_FAILURE
;
66 for (i
= 0; i
< nsets
; i
++) {
67 Quark
*pset
= sets
[i
];
68 if (set_is_drawable(pset
)) {
69 double x1
, x2
, y1
, y2
;
70 set_get_minmax(pset
, &x1
, &x2
, &y1
, &y2
);
78 *xmin
= (x1
< *xmin
) ? x1
: *xmin
;
79 *xmax
= (x2
> *xmax
) ? x2
: *xmax
;
80 *ymin
= (y1
< *ymin
) ? y1
: *ymin
;
81 *ymax
= (y2
> *ymax
) ? y2
: *ymax
;
87 return RETURN_SUCCESS
;
89 return RETURN_FAILURE
;
94 * get the min/max fields of a set with fixed x/y range
96 int getsetminmax_c(Quark
**sets
, int nsets
,
97 double *xmin
, double *xmax
, double *ymin
, double *ymax
, int ivec
)
99 double vmin_t
, vmax_t
, *vmin
, *vmax
, bvmin
, bvmax
, *vec
, *bvec
;
101 int first
= TRUE
, hits
;
103 if (nsets
< 1 || !sets
) {
104 return RETURN_FAILURE
;
119 for (i
= 0; i
< nsets
; i
++) {
120 Quark
*pset
= sets
[i
];
121 if (set_is_drawable(pset
)) {
131 n
= set_get_length(pset
);
132 hits
= minmaxrange(bvec
, vec
, n
, bvmin
, bvmax
, &vmin_t
, &vmax_t
);
133 if (hits
== RETURN_SUCCESS
) {
139 *vmin
= MIN2(vmin_t
, *vmin
);
140 *vmax
= MAX2(vmax_t
, *vmax
);
146 if (first
== FALSE
) {
147 return RETURN_SUCCESS
;
149 return RETURN_FAILURE
;
154 int set_point(Quark
*pset
, int seti
, const WPoint
*wp
)
157 return RETURN_FAILURE
;
159 if (seti
>= set_get_length(pset
) || seti
< 0) {
160 return RETURN_FAILURE
;
162 (set_get_col(pset
, DATA_X
))[seti
] = wp
->x
;
163 (set_get_col(pset
, DATA_Y
))[seti
] = wp
->y
;
164 quark_dirtystate_set(pset
, TRUE
);
165 return RETURN_SUCCESS
;
168 int get_point(Quark
*pset
, int seti
, WPoint
*wp
)
171 return RETURN_FAILURE
;
173 if (seti
>= set_get_length(pset
) || seti
< 0) {
174 return RETURN_FAILURE
;
176 wp
->x
= (set_get_col(pset
, DATA_X
))[seti
];
177 wp
->y
= (set_get_col(pset
, DATA_Y
))[seti
];
178 return RETURN_SUCCESS
;
181 int set_point_shift(Quark
*pset
, int seti
, const VVector
*vshift
)
186 if (get_point(pset
, seti
, &wp
) == RETURN_SUCCESS
&&
187 Wpoint2Vpoint(pset
, &wp
, &vp
) == RETURN_SUCCESS
) {
190 Vpoint2Wpoint(pset
, &vp
, &wp
);
191 return set_point(pset
, seti
, &wp
);
193 return RETURN_FAILURE
;
198 * delete the point pt in setno
200 void del_point(Quark
*pset
, int pt
)
202 ssd_delete_rows(get_parent_ssd(pset
), pt
, pt
);
205 int set_set_colors(Quark
*pset
, unsigned int color
)
207 set
*p
= set_get_data(pset
);
208 GraceApp
*gapp
= gapp_from_quark(pset
);
210 return RETURN_FAILURE
;
213 if (color
< number_of_colors(grace_get_canvas(gapp
->grace
))) {
214 p
->line
.line
.pen
.color
= color
;
215 p
->sym
.line
.pen
.color
= color
;
216 p
->sym
.fillpen
.color
= color
;
217 p
->errbar
.pen
.color
= color
;
219 quark_dirtystate_set(pset
, TRUE
);
220 return RETURN_SUCCESS
;
222 return RETURN_FAILURE
;
226 Quark
*gapp_set_new(Quark
*parent
)
231 pr
= get_parent_project(parent
);
233 pset
= set_new(parent
);
235 rt
= rt_from_quark(pset
);
242 rt
->setcolor
%= project_get_ncolors(pr
);
243 if (rt
->setcolor
== 0) {
246 set_set_colors(pset
, rt
->setcolor
);
254 void do_sort(Quark
*pset
, int sorton
, int stype
)
256 if (set_is_dataless(pset
)) {
257 errmsg("Set not active");
260 sortset(pset
, sorton
, stype
);
266 * join several sets together; all but the first set in the list will be killed
268 int join_sets(Quark
**sets
, int nsets
)
270 int i
, j
, n
, ncols
, old_length
, new_length
;
271 Quark
*pset
, *pset_final
;
277 return RETURN_FAILURE
;
280 pset_final
= sets
[0];
281 ncols
= set_get_ncols(pset_final
);
282 for (i
= 0; i
< nsets
; i
++) {
285 errmsg("Invalid pset in the list");
286 return RETURN_FAILURE
;
288 if (set_get_ncols(pset
) != ncols
) {
289 errmsg("Can't join datasets with different number of cols");
290 return RETURN_FAILURE
;
294 new_length
= set_get_length(pset_final
);
295 for (i
= 1; i
< nsets
; i
++) {
297 old_length
= new_length
;
298 new_length
+= set_get_length(pset
);
299 if (set_set_length(pset_final
, new_length
) != RETURN_SUCCESS
) {
300 return RETURN_FAILURE
;
302 for (j
= 0; j
< ncols
; j
++) {
303 x1
= set_get_col(pset_final
, j
);
304 x2
= set_get_col(pset
, j
);
305 for (n
= old_length
; n
< new_length
; n
++) {
306 x1
[n
] = x2
[n
- old_length
];
309 s1
= set_get_strings(pset_final
);
310 s2
= set_get_strings(pset
);
311 if (s1
!= NULL
&& s2
!= NULL
) {
312 for (n
= old_length
; n
< new_length
; n
++) {
313 s1
[n
] = copy_string(s1
[n
], s2
[n
- old_length
]);
319 return RETURN_SUCCESS
;
328 * for ascending and descending sorts
331 static int compare_points1(const void *p1
, const void *p2
)
335 i1
= (const int *)p1
;
336 i2
= (const int *)p2
;
348 static int compare_points2(const void *p1
, const void *p2
)
352 i1
= (const int *)p1
;
353 i2
= (const int *)p2
;
365 void sortset(Quark
*pset
, int sorton
, int stype
)
367 int i
, j
, nc
, len
, *ind
;
371 /* get the vector to sort on */
372 vptr
= set_get_col(pset
, sorton
);
374 errmsg("NULL vector in sort, operation cancelled, check set type");
378 len
= set_get_length(pset
);
383 /* allocate memory for permuted indices */
384 ind
= xmalloc(len
*SIZEOF_INT
);
388 /* allocate memory for temporary array */
389 xtmp
= xmalloc(len
*SIZEOF_DOUBLE
);
395 s
= set_get_strings(pset
);
397 stmp
= xmalloc(len
*sizeof(char *));
406 /* initialize indices */
407 for (i
= 0; i
< len
; i
++) {
412 qsort(ind
, len
, SIZEOF_INT
, stype
? compare_points2
: compare_points1
);
414 /* straighten things out - done one vector at a time for storage */
416 nc
= set_get_ncols(pset
);
417 /* loop over the number of columns */
418 for (j
= 0; j
< nc
; j
++) {
419 /* get this vector and put into the temporary vector in the right order */
420 x
= set_get_col(pset
, j
);
421 for (i
= 0; i
< len
; i
++) {
425 /* load it back to the set */
426 for (i
= 0; i
< len
; i
++) {
431 /* same with strings, if any */
433 for (i
= 0; i
< len
; i
++) {
437 for (i
= 0; i
< len
; i
++) {
442 /* free allocated temporary arrays */
447 quark_dirtystate_set(pset
, TRUE
);
450 int get_datapoint(Quark
*pset
, int ind
, int *ncols
, Datapoint
*dpoint
)
456 n
= set_get_length(pset
);
457 if (ind
< 0 || ind
>= n
) {
458 return RETURN_FAILURE
;
460 *ncols
= set_get_ncols(pset
);
461 for (col
= 0; col
< *ncols
; col
++) {
462 ex
= set_get_col(pset
, col
);
463 dpoint
->ex
[col
] = ex
[ind
];
465 s
= set_get_strings(pset
);
471 return RETURN_SUCCESS
;
476 * split a set into lpart length sets
478 int do_splitsets(Quark
*pset
, int lpart
)
480 int i
, j
, k
, ncols
, len
, plen
, npsets
;
484 Dataset
*dsp
, *dsptmp
;
486 if ((len
= set_get_length(pset
)) < 2) {
487 errmsg("Set length < 2");
488 return RETURN_FAILURE
;
491 errmsg("Split length >= set length");
492 return RETURN_FAILURE
;
495 errmsg("Split length <= 0");
496 return RETURN_FAILURE
;
499 npsets
= (len
- 1)/lpart
+ 1;
501 /* get number of columns in this set */
502 ncols
= set_get_ncols(pset
);
504 gr
= get_parent_graph(pset
);
505 dsp
= set_get_dataset(pset
);
507 /* now load each set */
508 for (i
= 0; i
< npsets
; i
++) {
509 plen
= MIN2(lpart
, len
- i
*lpart
);
510 ptmp
= gapp_set_new(gr
);
512 errmsg("Can't create new set");
513 return RETURN_FAILURE
;
516 dsptmp
= set_get_dataset(ptmp
);
518 /* set the plot parameters */
519 copy_set_params(pset
, ptmp
);
521 if (set_set_length(ptmp
, plen
) != RETURN_SUCCESS
) {
522 return RETURN_FAILURE
;
525 dataset_enable_scol(dsptmp
, TRUE
);
528 /* load the data into each column */
529 for (k
= 0; k
< ncols
; k
++) {
530 x
= set_get_col(ptmp
, k
);
531 for (j
= 0; j
< plen
; j
++) {
532 x
[j
] = dsp
->ex
[k
][i
*lpart
+ j
];
536 for (j
= 0; j
< plen
; j
++) {
538 copy_string(NULL
, dsp
->s
[i
*lpart
+ j
]);
542 sprintf(s
, "partition %d of set %s", i
+ 1, quark_idstr_get(pset
));
543 set_set_comment(ptmp
, s
);
546 /* kill the original set */
548 return RETURN_SUCCESS
;