/*--------------------------------------------------------------------- * uvLLab_gFun -- grid-table functions *--------------------------------------------------------------------- */ double uvLLab_gFun (double_p dP, fut_calcData_p dataP) { double u = dP[0], v = dP[1], l = dP[2]; double x, y, z, p, delta, a, astar, bstar; /* Decode piecewise linear functions of u and v: */ delta = u - UGRID0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bu1 : ((auxData_p)dataP)->uvLLabC.bu0; delta = UNMAP (delta, a); u = U0 + delta; delta = v - VGRID0; a = (delta > 0.0) ? ((auxData_p)dataP)->uvLLabC.bv1 : ((auxData_p)dataP)->uvLLabC.bv0; delta = UNMAP (delta, a); v = V0 + delta; u = 0.070 + 0.40996784565916 * u; /* CIE 1976 u' */ v = 0.165 + 0.41986827661910 * v; /* CIE 1976 v' */ /* Compute CIE 1931 tristimulus values: */ y = Hinverse (l, &(((auxData_p)dataP)->lc)); /* CIE 1931 Y */ y = (254.0 * y + 1.0) / 255.0; /* recompress for Prophecy */ x = 2.25 * (u / v) * y; /* CIE 1931 X */ z = ((3.0 - 0.75 * u) / v - 5.0) * y; /* CIE 1931 Z */ /* Scale to white point: */ x /= XWHITE; y /= YWHITE; z /= ZWHITE; /* Convert to CIELAB: */ astar = (Hfunc (x, &(((auxData_p)dataP)->lc)) - Hfunc (y, &(((auxData_p)dataP)->lc))) / 0.00232; /* CIE 1976 a* */ bstar = (Hfunc (y, &(((auxData_p)dataP)->lc)) - Hfunc (z, &(((auxData_p)dataP)->lc))) / 0.00580; /* CIE 1976 b* */ /* Encode CIELAB for L* in [0, 100] and a* & b* in [-200, 200]: */ switch (dataP->chan) { case 0: /* (L*)/100 */ p = Hfunc (y, &(((auxData_p)dataP)->lc)); break; case 1: /* ~ 1/2 + (a*)/400 */ p = MID12BIT + 0.0025 * astar; break; case 2: /* ~ 1/2 + (b*)/400 */ p = MID12BIT + 0.0025 * bstar; break; default: p = 6.023e+23; /* Avogadro's number */ break; } return RESTRICT (p, 0.0, 1.0); }
/*--------------------------------------------------------------------- * cmyklin_oFunc -- output mapping *--------------------------------------------------------------------- */ double cmyklin_oFunc ( double s, fut_calcData_p dataP) { s = (1.0 - YMIN) * s + YMIN; s = Hfunc (s, &(((auxData_p)dataP)->lc)); s = (1.0 + L0) * s - L0; s = RESTRICT (s, 0.0, 1.0); return s; }
double uvLLab_iL (double l, fut_calcData_p dataP) /* piecewise linear in v' */ { double y; #if defined KCP_MAP_BASE_MAX_REF l *= KCP_16_TO_8_ENCODING; #endif /* Convert to luminance: */ y = Hinverse (l, &(((auxData_p)dataP)->lc)); /* ==> y is compressed relative luminance */ y = (255.0 * y - 1.0) / 254.0; /* decompress for L*a*b* */ /* Convert back to (L*)/100: */ l = Hfunc (y, &(((auxData_p)dataP)->lc)); /* (L*)/100, in [-0.0356, 1] */ return RESTRICT (l, 0.0, 1.0); }
/*--------------------------------------------------------------------- * xyzmap_iFunc -- input mappings *--------------------------------------------------------------------- */ double xyzmap_iFunc (double xyz, fut_calcData_p dataP) { switch (dataP->chan) { case 0: xyz /= (KCP_D50_X * XYZSCALE); /* X */ break; case 1: xyz /= (KCP_D50_Y * XYZSCALE); /* Y */ break; case 2: xyz /= (KCP_D50_Z * XYZSCALE); /* Z */ break; } xyz = Hfunc (xyz, &(((auxData_p)dataP)->lc)); xyz /= 1.4; return RESTRICT (xyz, 0.0, 1.0); }
/*---------------------------------------------------------------------------- * outfun -- rescale and clip a* and b*; decompress L* *---------------------------------------------------------------------------- */ double uvLLab_oFun (double p, fut_calcData_p dataP) { switch (dataP->chan) { case 0: p = Hinverse (p, &(((auxData_p)dataP)->lc)); /* Y */ p = (255.0 * p - 1.0) / 254.0; /* decompress from Prophecy Dmax */ p = Hfunc (p, &(((auxData_p)dataP)->lc)); /* (L*)/100, in [-0.0356, 1] */ break; case 1: case 2: p = 400.0 * (p - MID12BIT); /* CIE 1976 a*, b*, in [-200, 200] */ p = RESTRICT (p, -128.0, 127.0); /* clip to [-128, 127] */ p = p + 128.0; /* -> [0, 255] */ p /= 255.0; /* from [0, 255] to [0, 1] */ break; default: p = 6.023e+23; break; } #if defined KCP_MAP_BASE_MAX_REF p *= KCP_8_TO_16_ENCODING; #endif return RESTRICT (p, 0.0, 1.0); /* L* in [0, 100]; a* & b* in [-128, 127] */ }
void Hfunc2(int* family,int* n,double* v,double* u,double* theta,double* nu,double* out) { double *negv, *negu; negv = (double *) malloc(*n * sizeof(double)); negu = (double *) malloc(*n * sizeof(double)); double ntheta, nnu; int nfamily; ntheta = -*theta; nnu = -*nu; for(int i=0;i<*n;i++) { if(u[i]<UMIN) u[i]=UMIN; else if(u[i]>UMAX) u[i]=UMAX; if(v[i]<UMIN) v[i]=UMIN; else if(v[i]>UMAX) v[i]=UMAX; } if((*family)==43) { nfamily=3; if(*theta > 0){ ntheta=2*(*theta)/(1-*theta); Hfunc (&nfamily, n, v, u, &ntheta, &nnu, out); }else{ ntheta=-2*(*theta)/(1+*theta); for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, negv, u, &ntheta, &nnu, out); for (int i = 0; i < *n; i++) {out[i]=1-out[i];}; } } else if((*family)==44) { nfamily=4; if(*theta > 0){ ntheta=1/(1-*theta); Hfunc (&nfamily, n, v, u, &ntheta, &nnu, out); }else{ ntheta=1/(1+*theta); for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, negv, u, &ntheta, &nnu, out); for (int i = 0; i < *n; i++) {out[i]=1-out[i];}; } }else{ if(((*family==23) | (*family==24) | (*family==26) | (*family==27) | (*family==28) | (*family==29) | (*family==30) | (*family==61) )) { nfamily=(*family)-20; for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, negv, u, &ntheta, &nnu, out); for (int i = 0; i < *n; i++) {out[i]=1-out[i];}; } else if(((*family==33) | (*family==34) | (*family==36) | (*family==37) | (*family==38) | (*family==39) | (*family==40) | (*family==71) )) { nfamily=(*family)-30; for (int i = 0; i < *n; ++i) {negu[i]=1 - u[i];} Hfunc(&nfamily, n, v, negu, &ntheta, &nnu, out); } else if((*family==104) | (*family==204) | (*family==114) | (*family==214)) { // switch u and v and change type if((*family)/100 == 1) nfamily = (*family) + 100; if((*family)/100 == 2) nfamily = (*family) - 100; for (int i = 0; i < *n; ++i) {negu[i] = 1 - u[i];} Hfunc1(&nfamily, n, v, u, theta, nu, out); } else if((*family==124) | (*family==224) | (*family==134) | (*family==234)) { // switch u and v and change type if((*family)/100 == 1) nfamily = (*family) + 100; if((*family)/100 == 2) nfamily = (*family) - 100; for (int i = 0; i < *n; ++i) {negv[i] = 1 - v[i];} for (int i = 0; i < *n; ++i) {negu[i] = 1 - u[i];} Hfunc1(&nfamily, n, negv, negu, theta, nu, out); for (int i = 0; i < *n; i++) {out[i] = 1 - out[i];}; } else { // switch u and v Hfunc(family, n, v, u, theta, nu, out); } } // ensure that results are in [0,1] for(int i=0; i < *n; ++i) {out[i] = MIN(MAX(out[i], UMIN), UMAX);} free(negv); free(negu); }
// Since the h function is not symmetric in case of double Gumbel and double Clayton we have two implement both separately, // i.e. Hfunc1 and Hfunc2 void Hfunc1(int* family,int* n,double* u,double* v,double* theta,double* nu,double* out) { double *negv, *negu; negv = (double *) malloc(*n* sizeof(double)); negu = (double *) malloc(*n*sizeof(double)); double ntheta, nnu; int nfamily, j, T=1; ntheta = -*theta; nnu = -*nu; for(int i=0;i<*n;i++) { if(u[i]<UMIN) u[i]=UMIN; else if(u[i]>UMAX) u[i]=UMAX; if(v[i]<UMIN) v[i]=UMIN; else if(v[i]>UMAX) v[i]=UMAX; } if((*family)==43) { nfamily=3; if(*theta > 0){ ntheta=2*(*theta)/(1-*theta); Hfunc(&nfamily, n, u, v, &ntheta, &nnu, out); }else{ ntheta=-2*(*theta)/(1+*theta); for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, u, negv, &ntheta, &nnu, out); } }else if((*family)==44) { nfamily=4; if(*theta > 0){ ntheta=1/(1-*theta); Hfunc (&nfamily, n, u, v, &ntheta, &nnu, out); }else{ ntheta=1/(1+*theta); for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, u, negv, &ntheta, &nnu, out); } }else{ if(((*family==23) | (*family==24) | (*family==26) | (*family==27) | (*family==28) | (*family==29) | (*family==30) | (*family==61) )) { nfamily=(*family)-20; for (int i = 0; i < *n; ++i) {negv[i]=1 - v[i];} Hfunc(&nfamily, n, u, negv, &ntheta, &nnu, out); } else if(((*family==33) | (*family==34) | (*family==36) | (*family==37) | (*family==38) | (*family==39) | (*family==40) | (*family==71) )) { nfamily=(*family)-30; for (int i = 0; i < *n; ++i) {negu[i]=1 - u[i];} Hfunc(&nfamily, n, negu, v, &ntheta, &nnu, out); for (int i = 0; i < *n; i++) {out[i]=1-out[i];}; } // u and v enter in wrong order from BiCopHfunc and have to be treated accordingly else if(*family==104) { double par3=1; dC_du(v,u,n,theta,nu,&par3,out); } else if(*family==114) { double par3=1; for(j=0;j<*n;j++) { negv[j]= 1-v[j]; negu[j]= 1-u[j]; dC_du(&negv[j],&negu[j],&T,theta,nu,&par3,&out[j]); out[j]= 1-out[j]; } } else if(*family==124) { double par3=*nu; double par2=1; for(j=0;j<*n;j++) { negv[j]= 1-v[j]; dC_du(&negv[j],&u[j],&T,&ntheta,&par2,&par3,&out[j]); } } else if(*family==134) { double par3=*nu; double par2=1; for(j=0;j<*n;j++) { negu[j]= 1-u[j]; dC_du(&v[j],&negu[j],&T,&ntheta,&par2,&par3,&out[j]); out[j]=1-out[j]; } } else if(*family==204) { double par3=*nu; double par2=1; dC_du(v,u,n,theta,&par2,&par3,out); } else if(*family==214) { double par3=*nu; double par2=1; for(j=0;j<*n;j++) { negv[j]= 1-v[j]; negu[j]= 1-u[j]; dC_du(&negv[j],&negu[j],&T,theta,&par2,&par3,&out[j]); out[j]= 1-out[j]; } } else if(*family==224) { double par3=1; for(j=0;j<*n;j++) { negv[j]= 1-v[j]; dC_du(&negv[j],&u[j],&T,&ntheta,nu,&par3,&out[j]); } } else if(*family==234) { double par3=1; for(j=0;j<*n;j++) { negu[j]= 1-u[j]; dC_du(&v[j],&negu[j],&T,&ntheta,nu,&par3,&out[j]); out[j]=1-out[j]; } } else { Hfunc (family, n, u, v, theta, nu, out); } } // ensure that results are in [0,1] for(int j=0; j <* n; ++j){out[j] = MIN(MAX(out[j], 0), 1);} free(negv); free(negu); }
/* * Computes normal albedo mult factor w/o opp surge from * Hapke input parameters: W,H,BO,HG,THETA. * Full-up Hapke's Law with macroscopic roughness. The photometric * function multiplied back in will be modified to take out oppos- * ition effect. This requires saving the actual value of B0 while * temporarily setting it to zero in the common block to compute * the overall normalization. * * @param phase Value of phase angle, in degrees. * @param incidence Value of incidence angle, in degrees. * @param emission Value of emission angle, in degrees. * @returns <b>double</b> * * * @history 1989-08-02 Unknown author in Isis2 under name pht_hapke * @history 1991-08-07 Tammy Becker relinked hapke to new photompr * @history 1997-02-16 James M Anderson - changed nonstandard degree trig * to use radians * @history 1999-01-11 KTT - Remove mu,munot,and alpha from the argument * list and pass in only ema,inc, and phase. Remove * lat and lon from argument list because they aren't * used. * @history 1999-03-01 K Teal Thompson Implement 1999-01-08 Randy Kirk * Original Specs & Code. Declare vars, add implicit none. * @history 1999-11-18 Randy Kirk - fixed minor typos, implemented return with * smooth Hapke (Theta=0) result before doing rough Hapke * calculations, allow single-particle-phase params = 0 * @history 2008-01-14 Janet Barrett - Imported into Isis3. Changed name from pht_hapke to PhotoModelAlgorithm() * @history 2008-11-05 Jeannie Walldren - Added documentation * from Isis2 files. Replaced Isis::PI with PI since this is in Isis namespace. * */ double HapkeHen::PhotoModelAlgorithm (double phase, double incidence, double emission) { double pht_hapkehen; double pharad; //phase angle in radians double incrad; // incidence angle in radians double emarad; // emission angle in radians double munot; double mu; double cost; double sint; double tan2t; double gamma; double hgs; double sing; double cosg; double tang; double bg; double pg; double pg1; double pg2; double sini; double coti; double cot2i; double ecoti; double ecot2i; double u0p0; double sine; double cote; double cot2e; double cosei; double sinei; double caz; double az; double az2; double faz; double tanaz2; double sin2a2; double api; double ecote; double ecot2e; double up0; double q; double ecei; double s2ei; double u0p; double up; double ecee; double s2ee; double rr1; double rr2; pharad = phase * PI / 180.0; incrad = incidence * PI / 180.0; emarad = emission * PI / 180.0; munot = cos(incrad); mu = cos(emarad); if (p_photoTheta != p_photoThetaold) { cost = cos(p_photoTheta * PI / 180.0); sint = sin(p_photoTheta * PI / 180.0); p_photoCott = cost / max(1.0e-10, sint); p_photoCot2t = p_photoCott * p_photoCott; p_photoTant = sint / cost; tan2t = p_photoTant * p_photoTant; p_photoSr = sqrt(1.0 + PI * tan2t); p_photoOsr = 1.0 / p_photoSr; SetOldTheta(p_photoTheta); } if (incidence >= 90.0) { pht_hapkehen = 0.0; return pht_hapkehen; } gamma = sqrt(1.0 - p_photoWh); hgs = p_photoHg1 * p_photoHg1; sing = sin(pharad); cosg = cos(pharad); tang = sing / max(1.0e-10, cosg); if (p_photoHh == 0.0) { bg = 0.0; } else { if (phase <= 90.0) { bg = p_photoB0 / max(-5.0, 1.0 + tang / p_photoHh); } else { bg = 0.0; } } pg1 = (1.0 - p_photoHg2) * (1.0 - hgs) / pow((1.0 + hgs + 2.0 * p_photoHg1 * cosg), 1.5); pg2 = p_photoHg2 * (1.0 - hgs) / pow((1.0 + hgs - 2.0 * p_photoHg1 * cosg), 1.5); pg = pg1 + pg2; if (p_photoTheta <= 0.0) { pht_hapkehen = p_photoWh / 4.0 * munot / (munot + mu) * ((1.0 + bg) * pg - 1.0 + Hfunc(munot,gamma) * Hfunc(mu,gamma)); return pht_hapkehen; } sini = sin(incrad); coti = munot / max(1.0e-10, sini); cot2i = coti * coti; ecoti = exp(min(-p_photoCot2t * cot2i / PI , 23.0)); ecot2i = exp(min(-2.0 * p_photoCott * coti / PI, 23.0)); u0p0 = p_photoOsr * (munot + sini * p_photoTant * ecoti / (2.0 - ecot2i)); sine = sin(emarad); cote = mu / max(1.0e-10, sine); cot2e = cote * cote; cosei = mu * munot; sinei = sine * sini; if (sinei == 0.0) { caz = 1.0; az = 0.0; } else { caz = (cosg - cosei) / sinei; if (caz <= -1.0) { az = 180.0; } else if (caz > 1.0) { az = 0.0; } else { az = acos(caz) * 180.0 / PI; } } az2 = az / 2.0; if (az2 >= 90.0) { faz = 0.0; } else { tanaz2 = tan(az2 * PI / 180.0); faz = exp(min(-2.0 * tanaz2, 23.0)); } sin2a2 = pow(sin(az2 * PI / 180.0), 2.0); api = az / 180.0; ecote = exp(min(-p_photoCot2t * cot2e / PI, 23.0)); ecot2e = exp(min(-2.0 * p_photoCott * cote / PI, 23.0)); up0 = p_photoOsr * (mu + sine * p_photoTant * ecote / (2.0 - ecot2e)); if (incidence <= emission) { q = p_photoOsr * munot / u0p0; } else { q = p_photoOsr * mu / up0; } if (incidence <= emission) { ecei = (2.0 - ecot2e - api * ecot2i); s2ei = sin2a2 * ecoti; u0p = p_photoOsr * (munot + sini * p_photoTant * (caz * ecote + s2ei) / ecei); up = p_photoOsr * (mu + sine * p_photoTant * (ecote - s2ei) / ecei); } else { ecee = (2.0 - ecot2i - api * ecot2e); s2ee = sin2a2 * ecote; u0p = p_photoOsr * (munot + sini * p_photoTant * (ecoti - s2ee) / ecee); up = p_photoOsr * (mu + sine * p_photoTant * (caz * ecoti + s2ee) / ecee); } rr1 = p_photoWh / 4.0 * u0p / (u0p + up) * ((1.0 + bg) * pg - 1.0 + Hfunc(u0p, gamma) * Hfunc(up, gamma)); rr2 = up * munot / (up0 * u0p0 * p_photoSr * (1.0 - faz + faz * q)); pht_hapkehen = rr1 * rr2; return pht_hapkehen; }
void condsim(int* n, int* d, int* d1, double* u1, int* family, double* par, double* nu, double* out) { int i,j, k; double **uf,**ub,**th,**nuu; double aux; int **fam; uf = create_matrix(*d,*d); ub = create_matrix(*d,*d); th = create_matrix(*d+1,*d+1); nuu = create_matrix(*d+1,*d+1); fam = create_intmatrix(*d+1,*d+1); // param in matrices: k = 0; for(i=0;i<((*d)-1);i++) { for(j=0;j<((*d)-i-1);j++) { fam[i][j] = family[k]; nuu[i][j] = nu[k]; th[i][j] = par[k]; k++; //printf("%d \t",fam[i][j]); } //printf("\n"); } // Simulation GetRNGstate(); /* Declare variable to hold seconds on clock. */ //time_t seconds; /* Get value from system clock and place in seconds variable. */ //time(&seconds); /* Convert seconds to a unsigned integer. */ //srand((unsigned int) seconds); // for i = 0 uf[0][0] = u1[0]; ub[0][0] = u1[0]; // for i = 1,... d1-1 // compute uf and ub for (int i = 1; i < (*d1); ++i) { uf[i][i] = u1[i]; ub[i][i] = u1[i]; for (int j = (i-1); j >= 0; --j) { Hfunc(&fam[i-j-1][j],n,&ub[i][j+1], &uf[i-1][j],&th[i-j-1][j],&nuu[i-j-1][j],&ub[i][j]); //backward //printf("ub: %d,%d : %d, %5.2f : %10.8f \n",i,j,fam[i-j-1][j], th[i-j-1][j], ub[i][j]); } //printf("\n"); for (int j = 0; j <= i-1; ++j) { Hfunc(&fam[i-j-1][j],n, &uf[i-1][j], &ub[i][j+1],&th[i-j-1][j],&nuu[i-j-1][j],&uf[i][j]); //forward //printf("uf: %d,%d : %d, %5.2f : %10.8f \n",i,j,fam[i-j-1][j], th[i-j-1][j], uf[i][j]); } //printf("\n"); } // for i= d1,.. d-1 for (int i = (*d1); i < (*d); ++i) { // (a) Simulate uniform //out[i-(*d1)] = rand()/(RAND_MAX+1.0); out[i-(*d1)]=runif(0,1); // (b) inverse transformation: for (int j = 0; j < i; ++j) { //printf("inv: %d,%d : %d, %5.2f : %10.8f \t",i-j-1,j,fam[i-j-1][j], th[i-j-1][j], uf[i-1][j]); Hinv(&fam[i-j-1][j], n, &out[i-*d1] , &uf[i-1][j], &th[i-j-1][j], &nuu[i-j-1][j],&aux ); out[i-(*d1)] = aux; //printf("%10.8f \n ", aux); } //printf("\n"); if (i <((*d)-1)) { // forward and backward steps: uf[i][i] = out[i-(*d1)]; ub[i][i] = out[i-(*d1)]; for (int j = i-1; j >= 0; --j) { Hfunc(&fam[i-j-1][j],n,&ub[i][j+1], &uf[i-1][j],&th[i-j-1][j],&nuu[i-j-1][j],&ub[i][j]); //backward //printf("ub: %d,%d : %d, %5.2f : %10.8f \n",i-j-1,j,fam[i-j-1][j], th[i-j-1][j], ub[i][j]); } //printf("\n"); for (int j = 0; j <= i-1; ++j) { Hfunc(&fam[i-j-1][j],n, &uf[i-1][j], &ub[i][j+1],&th[i-j-1][j],&nuu[i-j-1][j],&uf[i][j]); //forward //printf("uf: %d,%d : %d, %5.2f : %10.8f \n",i-j-1,j,fam[i-j-1][j], th[i-j-1][j], uf[i][j]); } //printf("\n"); } } // free memory free_matrix(th,*d); free_matrix(ub,*d); free_matrix(uf,*d); free_matrix(nuu,*d); free_intmatrix(fam,*d); PutRNGstate(); }