library( munsellinterpol ) library( microbenchmark ) library( spacesXYZ ) printf <- function( msg, ... ) { mess = sprintf( msg[1], ... ) # should this really be msg[1] ? cat( mess, '\n' ) #, file=stderr() ) } gettime <- function() { return( microbenchmark::get_nanotime() * 1.e-9 ) } ABfromHC <- function( H, C ) { theta = H * pi/50 list( A = C*cos(theta), B = C*sin(theta) ) } makeABab <- function( Munsell2xy, value ) { dfsub = Munsell2xy[ Munsell2xy$V == value , ] # & Munsell2xy$real tmp = ABfromHC( dfsub$H, dfsub$C ) dfsub$A = tmp$A dfsub$B = tmp$B XYZ.C = spacesXYZ::XYZfromxyY( c( 0.3101,0.3163, 100 ) ) xyY = cbind( dfsub$x, dfsub$y, YfromV(value) ) XYZ = spacesXYZ::XYZfromxyY( xyY ) Lab = spacesXYZ::LabfromXYZ( XYZ, XYZ.C ) dfsub$a = Lab[ ,2] dfsub$b = Lab[ ,3] return( dfsub ) } testPoly <- function() { df5 = makeABab( munsellinterpol::Munsell2xy, 5 ) mod.poly = lm( A ~ polym(a,b,degree=3,raw=TRUE) + 0, data=df5 ) # but polym prediction does not work for singletons form = "A ~ a + I(a^2) + I(a^3) + b + I(a*b) + I(a^2*b) + I(b^2) + I(a*b^2) + I(b^3) + 0" mod.terms = lm( formula(form), data=df5 ) # coefficients should be identical ok = identical( as.numeric(coef(mod.terms)) , as.numeric(coef(mod.poly)) ) if( ! ok ) { printf( "direct and polynomial coefficients are not identical." ) return(FALSE) } coef = coef(mod.terms) #; print( coef ) count = nrow(df5) pred1 = numeric( count ) time_start = gettime() # predict A for each row, one at a time for( i in 1:count ) pred1[i] = predict( mod.terms, newdata=list( a=df5$a[i], b=df5$b[i] ) ) time_elapsed = gettime() - time_start printf( "Predicted %d points using predict() (one at a time) in %g seconds. %g/point.", count, time_elapsed, time_elapsed/count ) # do it again by direct calc, which is much faster pred2 = numeric( count ) time_start = gettime() for( i in 1:count ) { a = df5$a[i] b = df5$b[i] a2 = a*a b2 = b*b term = c( a, a2, a2*a, b, a*b, a2*b, b2, a*b2, b2*b ) pred2[i] = sum( coef * term ) } time_elapsed = gettime() - time_start printf( "Predicted %d points using sum(coef*term) (one at a time) in %g seconds. %g/point.", count, time_elapsed, time_elapsed/count ) # now compare pred1[] to pred2[] ran = range( pred1 - pred2 ) printf( "Difference range = [%g,%g].", ran[1], ran[2] ) tol = 5.e-14 return( all( abs(ran) < tol ) ) } { if( testPoly() ) printf( "testPoly() succeeded !" ) else stop( "testPoly() failed !", call.=FALSE ) } printf( "Passed all polynomial tests !" )