Files
argyllcms/rspl/trnd.c
T
2026-08-20 20:28:40 +01:00

276 lines
6.0 KiB
C

/************************************************/
/* Test RSPL reverse lookup in 3/4D */
/************************************************/
/* Author: Graeme Gill
* Date: 31/10/96
* Derived from tnd.c
* Copyright 1999 - 2000 Graeme W. Gill
*
* This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
* see the License.txt file for licencing details.
*/
#undef DEBUG
#undef DETAILED
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
#include "rspl.h"
#include "numlib.h"
#ifdef NEVER
FILE *verbose_out = stdout;
int verbose_level = 6; /* Current verbosity level */
/* 0 = none */
/* !0 = diagnostics */
#endif /* NEVER */
#define GRES 10 /* Grid resolution */
#define DI 4 /* Dimensions in */
#define FDI 3 /* Function (out) Dimensions */
#define DOLIMIT
#define LIMITV 1.50
/* Fwd function approximated by rspl */
void func(
void *cbctx,
double *out,
double *in) {
double tt[4];
#ifdef NEVER
printf(" Got input %f %f\n",in[0],in[1]);
if (in[1] < 0.5 && in[0] < 0.5) { /* 0,0 */
out[0] = 0.1;
out[1] = 0.5;
}
if (in[1] < 0.5 && in[0] > 0.5) { /* 0,1 */
out[0] = 0.5;
out[1] = 0.0;
}
if (in[1] > 0.5 && in[0] < 0.5) { /* 0,1 */
out[0] = 0.9;
out[1] = 0.8;
}
if (in[1] > 0.5 && in[0] > 0.5) { /* 0,1 */
out[0] = 0.9;
out[1] = 0.2;
}
#endif /* NEVER */
#if DI >= 3
tt[0] = 0.7 * in[0] + 0.2 * in[1] + 0.1 * in[2];
tt[0] = tt[0] * tt[0];
tt[1] = 0.2 * in[0] + 0.8 * in[1] - 0.1 * in[2];
tt[1] = tt[1] * tt[1];
tt[2] = 0.3 * in[0] - 0.2 * in[1] + 0.9 * in[2];
tt[2] = tt[2] * tt[2];
#endif
#if DI == 4
tt[0] *= in[3];
tt[1] *= in[3];
tt[2] *= in[3];
#endif
tt[3] = 0.3 * in[0] + 0.4 * in[1] + 0.3 * in[2];
#if FDI > 0
out[0] = tt[0];
#endif
#if FDI > 1
out[1] = tt[1];
#endif
#if FDI > 2
out[2] = tt[2];
#endif
#if FDI > 3
out[3] = tt[3];
#endif
}
/* Simplex ink limit function */
double limitf(
void *lcntx,
double *in
) {
int i;
double ov;
for (ov = 0.0, i = 0; i < DI; i++) {
ov += in[i];
}
return ov;
}
int
main(
int argc,
char *argv[]
) {
int e;
rspl *rss; /* Multi-resolution regularized spline structure */
int gres[MXDI];
for (e = 0; e < DI; e++)
gres[e] = GRES;
printf("Started test\n");
/* Create the object */
rss = new_rspl(RSPL_NOFLAGS, DI, FDI);
printf("Rspl allocated\n");
rss->set_rspl(rss, 0, (void *)NULL, func, NULL, NULL, gres, NULL, NULL);
// rss->set_rspl(rss, RSPL_SET_APXLS, (void *)NULL, func, NULL, NULL, gres, NULL, NULL);
printf("Rspl set\n");
{
#define NIP 10 /* Number of solutions allowed */
int i, r, cl;
double v[MXDO]; /* Target output value */
co tp[NIP], chp; /* Test point, check point */
double cvec[4]; /* Text clip vector */
int auxm[4]; /* Auxiliary target value valid flag */
double lmin[4], lmax[4]; /* Locus min/max values */
/* Output value being looked for */
/*
tp[0].v[0] = v[0] = 1.5;
tp[0].v[1] = v[1] = 0.9;
tp[0].v[2] = v[2] = 1.2;
tp[0].v[3] = v[3] = 0.0;
*/
tp[0].v[0] = v[0] = 0.3;
tp[0].v[1] = v[1] = 0.4;
tp[0].v[2] = v[2] = 0.26;
tp[0].v[3] = v[3] = 0.0;
/* Set auxiliary target */
auxm[0] = 0;
auxm[1] = 0;
auxm[2] = 0;
auxm[3] = 1;
tp[0].p[0] = 0;
tp[0].p[1] = 0;
tp[0].p[2] = 0.0;
tp[0].p[3] = 0.87;
for (i = 1; i < NIP; i++) { /* Make sure we can see changes */
tp[i].p[0] = -1.0;
tp[i].p[1] = -1.0;
tp[i].p[2] = -1.0;
tp[i].p[3] = -1.0;
}
/* Clip center */
cvec[0] = 0.1 - tp[0].v[0];
cvec[1] = 0.1 - tp[0].v[1];
cvec[2] = 0.1 - tp[0].v[2];
cvec[3] = 0.1 - tp[0].v[3];
#ifdef DOLIMIT
/* Setup limit */
rss->rev_set_limit(rss,
limitf, /* limit function */
NULL, /* Function context */
LIMITV /* limit maximum value */
);
#endif /* DOLIMIT */
#if DI > FDI
/* Check out the locus size */
if ((r = rss->rev_locus(rss,
auxm, /* auxm Auxiliary mask flags */
tp, /* Input and auxiliary values */
lmin, /* Locus min/max return values */
lmax
)) > 0) {
printf("Total of %d Results\n",r);
for (i = 0; i < FDI; i++) {
if (auxm[i] == 0)
continue;
printf("Auxiliary %d min = %f, max = %f\n",i, lmin[i], lmax[i]);
}
} else {
printf("Failed to find gamut range\n");
}
printf("\n\n");
#endif
/* Do reverse interpolation ~~~1 */
if ((r = rss->rev_interp(rss,
0 /* RSPL_EXACTAUX */, /* Hint flags */
NIP, /* Number of solutions allowed */
auxm, /* auxm Auxiliary mask flags */
cvec, /* cvec Clip vector direction & length */
tp) /* Input and output values */
) > 0) {
printf("Total of %d Results\n", r &= RSPL_NOSOLNS);
printf("Target output %f, %f, %f, %f\n", v[0], v[1], v[2], v[3]);
cl = r & RSPL_DIDCLIP; /* clipped flag */
r &= RSPL_NOSOLNS; /* Get number of solutions */
/* Check test result */
for (i = 0; i < r; i++) {
chp.p[0] = tp[i].p[0];
chp.p[1] = tp[i].p[1];
chp.p[2] = tp[i].p[2];
chp.p[3] = tp[i].p[3];
chp.v[0] = -1.0;
chp.v[1] = -1.0;
chp.v[2] = -1.0;
chp.v[3] = -1.0;
printf("Result %d = inp: %f, %f, %f, %f\n",i, tp[i].p[0],tp[i].p[1],tp[i].p[2],tp[i].p[3]);
printf(" out: %f, %f, %f, %f\n",tp[i].v[0],tp[i].v[1],tp[i].v[2],tp[i].v[3]);
if (rss->interp(rss, &chp))
printf("Fwd check %d failed!\n",i);
else {
int p;
double er = 0.0;
for (p = 0; p < FDI; p++)
er += (v[p] - chp.v[p]) * (v[p] - chp.v[p]);
er = sqrt(er);
printf("Fwd check error %d = %f\n",i,er);
if (cl != 0) {
/* Check if clipped result us reasonable */
/* ~~~ */
}
}
{
printf("Output limit = %f\n",limitf(NULL, tp[i].p));
}
}
} else
printf("Rev lookup result returned none\n");
}
rss->del(rss);
return 0;
}
#ifdef NEVER
/* Standard interface for powell function */
/* return err on sucess, -1.0 on failure */
/* Result will be in cp */
double powell(
int di, /* Dimensionality */
double cp[], /* Initial starting point */
double s[], /* Size of initial search area */
double ftol, /* Tollerance of error change to stop on */
int maxit, /* Maximum iterations allowed */
double (*func)(void *fdata, double tp[]), /* Error function to evaluate */
void *fdata /* Opaque data needed by function */
) {
#endif