> # test.numstab.R: Expose any numerical instability of earth across platforms.
> #
> # This file was created by running earth and plotmo slowtests
> # with earth on Win7 built with "--mfpmath=387" (instead of "-mtune=native"
> # or "-mfpmath=sse -msse2").
> # Differences between the output in the test suites from standard earth
> # were collected and put into this file.
> # So this code duplicates code in earth and plotmo slowtests.
> # Most but not all differences were captured and put into this file.
> # This file was originally created in in Oct 2020 for earth 5.3.0.
> 
> source("test.prolog.R")
> 
> library(earth)
Loading required package: Formula
Loading required package: plotmo
Loading required package: plotrix
> library(mda)
Loading required package: class
Loaded mda 0.5-4

> data(ozone1)
> data(trees)
> data(etitanic)
> 
> cat("\n#=== from test.full.R ===========================================\n")

#=== from test.full.R ===========================================
> set.seed(2020)
> 
> PLOT <- TRUE                # TRUE to do plots too, FALSE for speed
> options.old <- options()
> options(warn=1) # print warnings as they occur
> 
> printh <- function(x, expect.warning=FALSE, max.print=0) # like print but with a header
+ {
+     cat("===", deparse(substitute(x)), " ", sep="")
+     if(expect.warning)
+         cat(" expect warning -->")
+     else if (NROW(x) > 1)
+         cat("\n")
+     if (max.print > 0)
+         print(head(x, n=max.print))
+     else
+         print(x)
+ }
> 
> ozone.test <- function(itest, sModel, x, y, degree=2, nk=51,
+                     plotit=PLOT, trace=0, smooth.col="red")
+ {
+     fite <- earth(x, y, degree=degree, nk=nk, trace=trace)
+     fitm <- mars(x, y, degree=degree, nk=nk)
+ 
+     cat("itest",
+         sprint("%-3d", itest),
+         sprint("%-32s", sModel),
+         "degree", sprint("%-2d", degree), "nk", sprint("%-3g", nk),
+         "nTerms",  sprint("%-2d", sum(fite$selected.terms != 0)),
+         "of", sprint("%-3d", nrow(fite$dirs)),
+         "GRSq", sprint("%4.2g", fite$grsq),
+         "GRSq ratio", fite$grsq/mars.to.earth(fitm)$grsq,
+         "\n")
+     caption <- paste("itest ", itest, ": ", sModel, " degree=", degree, " nk=", nk, sep="")
+     printh(summary(fite))
+     printh(summary(fite, style="bf"))
+     if(plotit) {
+         fitme <- mars.to.earth(fitm)
+         plotmo(fite, caption=paste("NUMSTAB EARTH", caption), trace=-1)
+         plotmo(fitme, caption=paste("MARS", caption), trace=-1)
+         plot(fite, npoints=500, smooth.col=smooth.col, caption=paste("EARTH", caption), info=TRUE)
+         plot(fitme, caption=paste("MARS", caption), info=TRUE)
+         fitme <- update(fitme)  # generate model selection data
+         plot.earth.models(list(fite, fitme), caption=paste(itest, ": Compare earth to mars ", sModel, sep=""))
+     }
+     fite
+ }
> set.seed(2020)
> data(ozone1)
> attach(ozone1)
> itest <- 1
> 
> set.seed(2020)
> cat("--Expect warning from mda::mars: NAs introduced by coercion\n") # why do we get a warning?
--Expect warning from mda::mars: NAs introduced by coercion
> x.global <- cbind(wind, exp(humidity))
> y <- doy
> # smooth.col is 0 else get loess errors
> # trace==2 so we see "Fixed rank deficient bx by removing 2 terms, 7 terms remain"
> ozone.test(itest, "doy ~ wind+exp(humidity)", x.global, y, degree=1, nk=21, smooth.col=0, trace=2)
x[330,2] with colnames wind x2
y[330,1] with colname y, and values 33, 34, 35, 36, 37, 38, 39, 4...
Forward pass: minspan 5 endspan 8   x[330,2] 5.16 kB   bx[330,21] 54.1 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0887 0.1107       0.1107    1         wind           3  2   3         1 
4      0.0906 0.1235      0.01274    1         wind           9  4             1 
6      0.0821 0.1262     0.002668    1         wind           4  5             1 
8      0.0730 0.1285     0.002307    1         wind           6  6             1 
10     0.0633 0.1304     0.001925    2           x2  1.7848e+08< 7             1 
12     0.0534 0.1323     0.001868    2           x2  1.7848e+08< 8             1 
14     0.0432 0.1340     0.001792    2           x2  1.7848e+08< 9             1 
16     0.0309 0.1340            0    -                                       reject (no DeltaRsq)

RSq changed by less than 0.001 at 15 terms, 9 terms used (DeltaRSq 0)
After forward pass GRSq 0.031 RSq 0.134
Forward pass complete: 15 terms, 9 terms used
Fixed rank deficient bx by removing 2 terms, 7 terms remain
Prune backward penalty 2 nprune null: selected 3 of 7 terms, and 1 of 2 preds
After pruning pass GRSq 0.101 RSq 0.123
Warning in storage.mode(tagx) <- "integer" :
  NAs introduced by coercion to integer range
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

itest 1   doy ~ wind+exp(humidity)         degree 1  nk 21  nTerms 3  of 7   GRSq  0.1 GRSq ratio 1.318534 
===summary(fite) 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

            coefficients
(Intercept)    202.17924
h(3-wind)       50.04004
h(wind-9)      -61.15513

Selected 3 of 7 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: wind, x2-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 9821.564    RSS 3143644    GRSq 0.1012101    RSq 0.1229323
===summary(fite, style = "bf") 
Call: earth(x=x, y=y, trace=trace, degree=degree, nk=nk)

y =
  202.1792
  + 50.04004 * bf1
  - 61.15513 * bf2

   bf1  h(3-wind)
   bf2  h(wind-9)

Selected 3 of 7 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: wind, x2-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 9821.564    RSS 3143644    GRSq 0.1012101    RSq 0.1229323
Converted mars(x=x, y=y, degree=degree, nk=nk)

to earth(x=x, y=y, degree=degree, nk=nk)

Selected 3 of 7 terms, and 1 of 2 predictors
Termination condition: RSq changed by less than 0.001 at 7 terms
Importance: wind, x2-unused
Number of terms at each degree of interaction: 1 2 (additive model)
GCV 9821.564    RSS 3143644    GRSq 0.1012101    RSq 0.1229323
> 
> # test Auto.linpreds with data sent in by a user
> ndata <- matrix(data=c(
+ -0.0781, -0.6109, -0.216, -1.5172, 0.8184, -1.1242,
+ -0.0781, -0.5885, -0.216, -1.3501, 0.8184, -0.8703,
+ -0.0781, -0.5885, -0.216, -1.3501, 0.8184, -0.9549,
+ -0.0781, -0.5885, -0.216, -1.3501, 1.4136, -0.8703,
+ -2.5759, -0.5885, 1.1665, -1.3501, 2.0089, -0.9549,
+ -2.5759, -0.5885, 1.1665, -1.3501, 2.0089, -0.8703,
+ -0.0781, -0.4937, -0.216, -0.9949, -0.372, -1.0396,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.447,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.701,
+ -0.0781, -0.4463, -0.216, -0.8278, -0.372, -0.6163,
+ -0.0781, -0.4463, -0.216, -0.8278, 0.8184, -0.447,
+ -0.0781, -0.4463, -0.216, -0.8278, 0.8184, -0.6163,
+ -0.0781, -0.4463, 1.1665, -0.8278, 0.8184, -0.447,
+ -0.0781, -0.4379, 1.1665, 0.2585, -0.372, -0.1085,
+ -0.0781, -0.2147, 1.1665, 0.0496, -0.372, -0.1085,
+ -0.0781, -0.2147, -0.216, 0.2585, -0.372, -0.0238,
+ -0.0781, -0.1589, -0.216, 0.2585, -0.372, -0.1931,
+ -0.0781, -0.1589, -0.216, 0.2585, -0.372, -0.1085,
+ -0.0781, -0.1589, 1.1665, 0.2585, -0.372, -0.1931,
+ -0.0781, -0.1589, -0.216, 0.2585, 0.8184, -0.1085,
+ -0.0781, -0.1589, -0.216, 0.2585, 0.8184, 0.0608,
+ -0.0781, -0.1589, -0.216, 1.0942, 0.8184, -0.0238,
+ -0.0781, 0.0643, 1.1665, 1.0942, -0.372, 0.2301,
+ -0.0781, 0.0643, -0.216, 1.0942, -1.5624, 0.3148,
+ -0.0781, 0.0643, -0.216, 1.0942, -0.9672, 0.1455,
+ -0.0781, 0.0643, 1.1665, 1.4284, 0.2232, 0.4841,
+ -0.0781, 0.1563, -0.216, 1.0942, -0.372, 0.5687,
+ 2.4197, 0.3432, -0.216, 1.0942, -1.5624, 1.0766,
+ -0.0781, 0.3432, -0.216, 1.0942, -1.5624, 1.1613,
+ -0.0781, 0.3432, 1.1665, 1.0942, 0.2232, 0.738,
+ 2.4197, 2.7145, -2.9811, 1.0942, -1.5624, 2.5156,
+ 2.4197, 4.3884, -2.9811, 1.0942, -1.5624, 3.5314),
+ ncol=6)
> colnames(ndata) <- c("x1", "x2", "x3", "x4", "x5", "y")
> ndata <- as.data.frame(ndata)
> 
> set.seed(2020)
> cat("Auto.linpreds=TRUE pmethod=\"none\":\n")
Auto.linpreds=TRUE pmethod="none":
> # trace==2 so we see "Fixed rank deficient bx by removing terms"
> # TODO why are we getting the rank deficient message?
> auto.linpreds.true.pmethod.none <- earth(y~., data=ndata, degree=2, nk=21, trace=2, pmethod="none")
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        4   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 10 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 10 terms used
Prune none penalty 3 nprune null: selected 10 of 10 terms, and 3 of 5 preds
After pruning pass GRSq -1.76 RSq 0.792
> print(summary(auto.linpreds.true.pmethod.none, decomp="none"))
Call: earth(formula=y~., data=ndata, pmethod="none", trace=2, degree=2, nk=21)

                    coefficients
(Intercept)            2.4332961
h(x1- -0.9549)        -0.9865989
h(-0.9549-x1)          6.9070794
h(x3- -0.0781)        -8.9336500
h(-0.0781-x3)          0.0165408
h(x1- -0.9549) * x4   -1.2581107
h(x1- -0.9549) * x3    6.4769097
h(-0.9549-x1) * x3    25.0101165
h(x1- -0.216)          1.8627919
x1 * h(x3- -0.0781)   -5.5959046

Selected 10 of 10 terms, and 3 of 5 predictors (pmethod="none")
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 5 4
GCV 8.371258    RSS 18.90073    GRSq -1.762519    RSq 0.792308
> cat("\nAuto.linpreds=FALSE pmethod=\"none\":\n")

Auto.linpreds=FALSE pmethod="none":
> auto.linpreds.false.pmethod.none <- earth(y~., data=ndata, degree=2, nk=21, trace=2, Auto.linpreds=FALSE, pmethod="none")
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        5   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 12 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 12 terms used
Fixed rank deficient bx by removing 2 terms, 10 terms remain
Prune none penalty 3 nprune null: selected 10 of 10 terms, and 3 of 5 preds
After pruning pass GRSq -1.76 RSq 0.792
> print(summary(auto.linpreds.false.pmethod.none, decomp="none"))
Call: earth(formula=y~., data=ndata, pmethod="none", trace=2, degree=2, nk=21,
            Auto.linpreds=FALSE)

                                coefficients
(Intercept)                         2.433296
h(x1- -0.9549)                     -1.684918
h(-0.9549-x1)                     -17.991545
h(x3- -0.0781)                     -3.590121
h(-0.0781-x3)                       9.087502
h(x1- -0.9549) * h(x4- -0.372)     -1.258111
h(x1- -0.9549) * h(x3- -0.8278)     0.881005
h(-0.9549-x1) * h(x3- -0.8278)     30.606021
h(x1- -0.216)                       1.862792
h(x1- -2.5759) * h(-0.0781-x3)     -5.595905

Selected 10 of 10 terms, and 3 of 5 predictors (pmethod="none")
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 5 4
GCV 8.371258    RSS 18.90073    GRSq -1.762519    RSq 0.792308
> stopifnot(isTRUE(all.equal(predict(auto.linpreds.true.pmethod.none), predict(auto.linpreds.false.pmethod.none))))
> 
> set.seed(2020)
> cat("\nAuto.linpreds=TRUE:\n")

Auto.linpreds=TRUE:
> auto.linpreds.true <- earth(y~., data=ndata, degree=2, nk=21, trace=2)
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        4   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 10 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 10 terms used
Prune backward penalty 3 nprune null: selected 4 of 10 terms, and 3 of 5 preds
After pruning pass GRSq 0.209 RSq 0.546
> print(summary(auto.linpreds.true, decomp="none"))
Call: earth(formula=y~., data=ndata, trace=2, degree=2, nk=21)

                    coefficients
(Intercept)             1.371239
h(x3- -0.0781)         -1.882810
h(x1- -0.9549) * x4    -1.413220
h(-0.9549-x1) * x3      4.319452

Selected 4 of 10 terms, and 3 of 5 predictors
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 1 2
GCV 2.396481    RSS 41.35802    GRSq 0.20916    RSq 0.5455344
> cat("\nAuto.linpreds=FALSE:\n")

Auto.linpreds=FALSE:
> auto.linpreds.false <- earth(y~., data=ndata, degree=2, nk=21, trace=2, Auto.linpreds=FALSE)
x[32,5] with colnames x1 x2 x3 x4 x5
y[32,1] with colname y, and values -0.372, 0.5687, 2.42, 0.3432,...
Forward pass: minspan 4 endspan 9   x[32,5] 1.25 kB   bx[32,21] 5.25 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.0583 0.3376       0.3376    1           x1     -0.9549  2   3         1 
4     -0.2012 0.4488       0.1112    3           x3     -0.0781  4   5         1 
6     -0.1801 0.5797        0.131    4           x4      -0.372< 6         2   2 
8     -0.2458 0.6681      0.08841    3           x3     -0.8278< 7         2   2 
10    -0.4175 0.7312      0.06304    3           x3     -0.8278< 8         3   2 
12    -0.8452 0.7677      0.03649    1           x1      -0.216  9             1 
14    -1.7625 0.7923      0.02464    1           x1     -2.5759< 10        5   2 
16   -13.8221 0.8111      0.01875    2           x2      -0.216  11  12        1 reject (negative GRSq)

Reached minimum GRSq -10 at 15 terms, 12 terms used (GRSq -14)
After forward pass GRSq -13.822 RSq 0.811
Forward pass complete: 15 terms, 12 terms used
Fixed rank deficient bx by removing 2 terms, 10 terms remain
Prune backward penalty 3 nprune null: selected 5 of 10 terms, and 3 of 5 preds
After pruning pass GRSq 0.223 RSq 0.643
> print(summary(auto.linpreds.false, decomp="none"))
Call: earth(formula=y~., data=ndata, trace=2, degree=2, nk=21,
            Auto.linpreds=FALSE)

                               coefficients
(Intercept)                        1.635321
h(-0.9549-x1)                    -12.155291
h(x3- -0.0781)                    -1.555091
h(x1- -0.9549) * h(x4- -0.372)    -1.220702
h(-0.9549-x1) * h(x3- -0.8278)    22.975120

Selected 5 of 10 terms, and 3 of 5 predictors
Termination condition: GRSq -10 at 10 terms
Importance: x1, x4, x3, x2-unused, x5-unused
Number of terms at each degree of interaction: 1 2 2
GCV 2.354961    RSS 32.4543    GRSq 0.2228618    RSq 0.6433736
> # following fails because of different pruning because of different term count
> # stopifnot(isTRUE(all.equal(predict(auto.linpreds.true), predict(auto.linpreds.false))))
> 
> cat("\n#=== from test.weights.R ===========================================\n")

#=== from test.weights.R ===========================================
> set.seed(2020)
> 
> noise <- .01 * c(1,2,3,2,1,3,5,2,0)
> data <- data.frame(x1=c(1,2,3,4,5,6,7,8,9), x2=c(1,2,3,3,3,6,7,8,9), y=(1:9)+noise)
> data[5,] <- c(5, 5, 6)
> colnames(data) <- c("x1", "x2", "y")
> 
> a21.noweights <- earth(y~., data=data, # no weights for comparison
+                        minspan=1, endspan=1, penalty=-1, thresh=1e-8, trace=-1)
> print(summary(a21.noweights))
Call: earth(formula=y~., data=data, trace=-1, minspan=1, endspan=1, penalty=-1,
            thresh=1e-08)

            coefficients
(Intercept)        5.070
h(5-x1)           -0.990
h(x1-5)           -0.465
h(x1-7)           -0.050
h(x1-8)            0.010
h(x2-3)            0.475
h(6-x2)           -0.020
h(x2-6)            1.010

Selected 8 of 8 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 1.0000 at 8 terms
Importance: x1, x2
Number of terms at each degree of interaction: 1 7 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> weights <- c(1, 1, 1, 1, .5, 1, 1, 1, 1)
> a10  <- earth(y~., data=data, weights=weights,
+               minspan=1, endspan=1, penalty=-1, thresh=1e-8, trace=-1)
> print(summary(a10))
Call: earth(formula=y~., data=data, weights=weights, trace=-1, minspan=1,
            endspan=1, penalty=-1, thresh=1e-08)

            coefficients
(Intercept)         5.07
h(x1-4)             0.95
h(5-x1)            -0.99
h(x1-5)            -0.94
h(x1-7)            -0.05
h(x1-8)             0.01
h(6-x2)            -0.02
h(x2-6)             1.01

Selected 8 of 8 terms, and 2 of 2 predictors
Termination condition: Reached maximum RSq 1.0000 at 8 terms
Importance: x1, x2
Weights: 1, 1, 1, 1, 0.5, 1, 1, 1, 1
Number of terms at each degree of interaction: 1 7 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> 
> cat("\n#=== from test.glm.R ===========================================\n")

#=== from test.glm.R ===========================================
> 
> cat("a12: compare family=gaussian to standard earth model with two responses\n\n")
a12: compare family=gaussian to standard earth model with two responses

> a12 <- earth(cbind(etitanic$sex, (as.integer(etitanic$age)^2)) ~ ., data=etitanic, degree=2, glm=list(family="gaussian"), trace=4)
Call: earth(formula=cbind(etitanic$sex,(as.integer(etitanic$age)^2))~.,
            data=etitanic, trace=4, glm=list(family="gaussian"), degree=2)

x[1046,5]:
     pclass2nd pclass3rd survived sibsp parch
1            0         0        1     0     0
2            0         0        1     1     2
3            0         0        0     1     2
...          0         0        0     1     2
1046         0         1        0     0     0

y[1046,2]:
     y1  y2
1     1 841
2     2   0
3     1   4
...   2 900
1046  2 841

Forward pass: minspan 6 endspan 9   x[1046,5] 40.9 kB   bx[1046,21] 172 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.1060 0.1103       0.1103    2    pclass3rd           0< 2             1 
4      0.1653 0.1733      0.06303    1    pclass2nd           0< 3             1 
6      0.2059 0.2210      0.04767    5        parch           2  4   5         1 
8      0.2210 0.2396      0.01859    3     survived           0< 6             1 
10     0.2223 0.2481     0.008525    5        parch           2  7   8     2   2 
12     0.2234 0.2565      0.00837    4        sibsp           1  9   10        1 
14     0.2219 0.2587     0.002244    5        parch           1  11        2   2 
16     0.2231 0.2635     0.004765    5        parch           1  12            1 
18     0.2226 0.2702     0.006718    5        parch           1  13  14    4   2 
20     0.2232 0.2743      0.00415    1    pclass2nd           0< 15        6   2 final (reached nk 21)

Reached nk 21
After forward pass GRSq 0.223 RSq 0.274
Forward pass complete: 21 terms, 15 terms used

Using EvalSubsetsUsingXtx (rather than leaps) because this is a multiple response model
     nTerms iTerm    DeltaRss     RSq
         15     2  2.8941e+07  0.2461 min
         15     3  3.4484e+07  0.2406
         15     4  3.0548e+07  0.2445
         15     5  1.9834e+06  0.2724 min
         15     6  2.0705e+07  0.2541
         15     7  2.4297e+07  0.2506
         15     8  6.3042e+06  0.2682
         15     9  6.3458e+06  0.2681
         15    10      8231.6  0.2743 min
         15    11  1.5243e+07  0.2594
         15    12  1.4677e+07  0.2600
         15    13  1.0817e+07  0.2638
         15    14  4.9902e+06  0.2695
         15    15  4.2448e+06  0.2702

         14     2  2.9403e+07  0.2456 min
         14     3   3.491e+07  0.2402
         14     4  3.0578e+07  0.2444
         14     5  1.9758e+06  0.2724 min
         14     6   2.074e+07  0.2541
         14     7  2.4514e+07  0.2504
         14     8  6.4997e+06  0.2680
         14     9   6.995e+06  0.2675
         14    11  1.5597e+07  0.2591
         14    12   1.467e+07  0.2600
         14    13  1.0901e+07  0.2637
         14    14  5.1186e+06  0.2693
         14    15  4.2486e+06  0.2702

         13     2  4.1871e+07  0.2315 min
         13     3  4.0788e+07  0.2325 min
         13     4  3.2141e+07  0.2410 min
         13     6  2.0184e+07  0.2527 min
         13     7  2.3466e+07  0.2495
         13     8  5.1563e+06  0.2674 min
         13     9  7.0251e+06  0.2655
         13    11  1.5565e+07  0.2572
         13    12  2.1626e+07  0.2513
         13    13  8.9657e+06  0.2636
         13    14   3.173e+06  0.2693 min
         13    15  3.5082e+06  0.2690

         12     2  4.1546e+07  0.2287 min
         12     3  7.7449e+07  0.1936
         12     4  3.1892e+07  0.2381 min
         12     6  2.3605e+07  0.2462 min
         12     7  2.3299e+07  0.2465 min
         12     8  4.9192e+06  0.2645 min
         12     9  7.5636e+06  0.2619
         12    11  1.5356e+07  0.2543
         12    12   2.139e+07  0.2484
         12    13  6.1065e+06  0.2633
         12    15  2.5439e+06  0.2668 min

         11     2  4.0833e+07  0.2269 min
         11     3  7.5335e+07  0.1932
         11     4  3.2208e+07  0.2353 min
         11     6  2.3752e+07  0.2436 min
         11     7  2.0994e+07  0.2463 min
         11     8  4.7818e+06  0.2621 min
         11     9  8.2607e+06  0.2587
         11    11  1.3425e+07  0.2537
         11    12  1.8871e+07  0.2484
         11    13  3.5784e+06  0.2633 min

         10     2   3.947e+07  0.2247 min
         10     3  7.2626e+07  0.1923
         10     4   2.897e+07  0.2350 min
         10     6  2.2396e+07  0.2414 min
         10     7  1.8734e+07  0.2450 min
         10     8  4.7438e+06  0.2587 min
         10     9  8.8185e+06  0.2547
         10    11  1.0366e+07  0.2532
         10    12   1.638e+07  0.2473

          9     2  1.8992e+08  0.0730 min
          9     3  7.3379e+07  0.1870 min
          9     4  2.8502e+07  0.2308 min
          9     6  2.5381e+07  0.2339 min
          9     7  1.4043e+07  0.2450 min
          9     9  1.3625e+07  0.2454 min
          9    11  5.6644e+06  0.2531 min
          9    12  1.5764e+07  0.2433

          8     2  1.8436e+08  0.0729 min
          8     3  7.3891e+07  0.1809 min
          8     4  2.2897e+07  0.2308 min
          8     6  2.6814e+07  0.2269
          8     7  8.7055e+06  0.2446 min
          8     9  9.3843e+06  0.2440
          8    12  1.0108e+07  0.2433

          7     2  1.9348e+08  0.0555 min
          7     3  7.5359e+07  0.1710 min
          7     4  1.7932e+07  0.2271 min
          7     6   2.644e+07  0.2188
          7     9  9.7584e+06  0.2351 min
          7    12  8.2948e+06  0.2365 min

          6     2  1.9155e+08  0.0493 min
          6     3   7.663e+07  0.1616 min
          6     4    1.17e+07  0.2251 min
          6     6  3.1425e+07  0.2058
          6     9  2.1466e+07  0.2155

          5     2  1.8693e+08  0.0424 min
          5     3  7.7548e+07  0.1493 min
          5     6   3.258e+07  0.1932 min
          5     9  2.2907e+07  0.2027 min

          4     2  2.0575e+08  0.0016 min
          4     3   7.681e+07  0.1276 min
          4     6  3.0059e+07  0.1733 min

          3     2  1.7662e+08  0.0007 min
          3     3   6.448e+07  0.1103 min

          2     2  1.1281e+08  0.0000 min

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.1060  0.1103     0.1060      1  1 2
          3      0.1653  0.1733     0.0593      2  1 2 3
          4      0.1911  0.2027     0.0258      3  1 2 3 6
          5      0.2100  0.2251     0.0189      4  1 2 3 6 9
          6      0.2179  0.2365     0.0079      5  1 2 3 4 6 9
          7      0.2225  0.2446     0.0045      5  1 2 3 4 6 9 12
          8      0.2275  0.2531     0.0050      5  1 2 3 4 6 7 9 12
          9      0.2295  0.2587     0.0020      5  1 2 3 4 6 7 9 11 12
chosen   10      0.2305  0.2633     0.0011      5  1 2 3 4 6 7 8 9 11 12
         11      0.2304  0.2668    -0.0001      5  1 2 3 4 6 7 8 9 11 12 13
         12      0.2293  0.2693    -0.0012      5  1 2 3 4 6 7 8 9 11 12 13 15
         13      0.2288  0.2724    -0.0005      5  1 2 3 4 6 7 8 9 11 12 13 14 15
         14      0.2270  0.2743    -0.0018      5  1 2 3 4 5 6 7 8 9 11 12 13 14 15
         15      0.2232  0.2743    -0.0038      5  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Prune backward penalty 3 nprune null: selected 10 of 15 terms, and 5 of 5 preds
After pruning pass GRSq 0.231 RSq 0.263

glm y[1046,1]:
     y1
1     1
2     2
3     1
...   2
1046  2

glm weights: NULL

GLM y1 devratio 0.32 dof 1036/1045 iters 2
glm y[1046,1]:
      y2
1    841
2      0
3      4
...  900
1046 841

glm weights: NULL

GLM y2 devratio 0.26 dof 1036/1045 iters 2
> cat("\nsummary(a12, details=TRUE)\n\n", sep="")

summary(a12, details=TRUE)

> print(summary(a12, details=TRUE))
Call: earth(formula=cbind(etitanic$sex,(as.integer(etitanic$age)^2))~.,
            data=etitanic, trace=4, glm=list(family="gaussian"), degree=2)

Earth coefficients
                                y1         y2
(Intercept)             1.87825514  1994.3477
pclass2nd              -0.03052777  -739.9866
pclass3rd              -0.24945083 -1666.0231
survived               -0.52605843  -320.9401
h(sibsp-1)              0.01497329  -177.7240
h(parch-1)             -0.09968178  -594.6399
h(parch-2)              0.04012795  1973.9441
pclass3rd * h(parch-2) -0.02275679 -2152.3800
pclass3rd * h(2-parch)  0.13019337   299.5782
pclass3rd * h(parch-1)  0.03601703  1047.1577

GLM coefficients
                                y1         y2
(Intercept)             1.87825514  1994.3477
pclass2nd              -0.03052777  -739.9866
pclass3rd              -0.24945083 -1666.0231
survived               -0.52605843  -320.9401
h(sibsp-1)              0.01497329  -177.7240
h(parch-1)             -0.09968178  -594.6399
h(parch-2)              0.04012795  1973.9441
pclass3rd * h(parch-2) -0.02275679 -2152.3800
pclass3rd * h(2-parch)  0.13019337   299.5782
pclass3rd * h(parch-1)  0.03601703  1047.1577

GLM y1 deviance residuals:
       Min          1Q      Median          3Q         Max  
-0.9041644  -0.3216689   0.1108089   0.1522726   0.9609189  

GLM y1 coefficients (family gaussian, link identity)
                          Estimate  Std. Error   t value Pr(>|t|)
(Intercept)             1.87825514  0.02962998  63.39037  < 2e-16
pclass3rd              -0.24945083  0.10625049  -2.34776 0.019074
pclass2nd              -0.03052777  0.03479059  -0.87747 0.380434
h(parch-2)              0.04012795  0.14694175   0.27309 0.784840
survived               -0.52605843  0.02717222 -19.36016  < 2e-16
pclass3rd * h(parch-2) -0.02275679  0.19924557  -0.11421 0.909090
pclass3rd * h(2-parch)  0.13019337  0.05510971   2.36244 0.018339
h(sibsp-1)              0.01497329  0.02397899   0.62443 0.532480
pclass3rd * h(parch-1)  0.03601703  0.13031139   0.27639 0.782302
h(parch-1)             -0.09968178  0.05886754  -1.69332 0.090695

GLM y1 dispersion parameter for gaussian family taken to be 0.1605338

GLM y2 deviance residuals:
       Min          1Q      Median          3Q         Max  
-1705.3478   -514.7814   -198.4811    297.5189   4726.5924  

GLM y2 coefficients (family gaussian, link identity)
                          Estimate  Std. Error  t value   Pr(>|t|)
(Intercept)             1994.34775    63.07215 31.62010 < 2.22e-16
pclass3rd              -1666.02307   226.17115 -7.36621 3.5776e-13
pclass2nd               -739.98661    74.05734 -9.99208 < 2.22e-16
h(parch-2)              1973.94408   312.78900  6.31078 4.1081e-10
survived                -320.94014    57.84041 -5.54872 3.6538e-08
pclass3rd * h(parch-2) -2152.38000   424.12604 -5.07486 4.5943e-07
pclass3rd * h(2-parch)   299.57821   117.30982  2.55374 0.01079967
h(sibsp-1)              -177.72401    51.04312 -3.48184 0.00051875
pclass3rd * h(parch-1)  1047.15774   277.38862  3.77506 0.00016906
h(parch-1)              -594.63992   125.30896 -4.74539 2.3728e-06

GLM y2 dispersion parameter for gaussian family taken to be 727409.6

GLM (family gaussian, link identity):
       nulldev   df         dev   df   devratio     AIC iters converged
y1 2.44077e+02 1045 1.66313e+02 1036      0.319    1067     2         1
y2 1.02296e+09 1045 7.53596e+08 1036      0.263   17100     2         1

Earth selected 10 of 15 terms, and 5 of 5 predictors
Termination condition: Reached nk 21
Importance: pclass3rd, pclass2nd, survived, sibsp, parch
Number of terms at each degree of interaction: 1 6 3

Earth
          GCV       RSS      GRSq       RSq
y1       0.17       166 0.2882848 0.3186029
y2  753952.19 753596300 0.2305416 0.2633195
All 753952.36 753596466 0.2305416 0.2633195
> 
> cat("\n#=== from test.plotmo.R ===========================================\n")

#=== from test.plotmo.R ===========================================
> 
> # check various types of predictors with grid.func and ndiscrete
> 
> varied.type.data <- data.frame(
+     y    = 1:13,
+     num  = c(1, 3, 2, 3, 4, 5, 6, 4, 5, 6.5, 3, 6, 5), # 7 unique values (but one is non integral)
+     int  = c(1L, 1L, 3L, 3L, 4L, 4L, 3L, 5L, 3L, 6L, 7L, 8L, 10L), # 8 unique values
+     bool = c(F, F, F, F, F, T, T, T, T, T, T, T, T),
+     date = as.Date(
+            c("2018-08-01", "2018-08-02", "2018-08-03",
+              "2018-08-04", "2018-08-05", "2018-08-06",
+              "2018-08-07", "2018-08-08", "2018-08-08",
+              "2018-08-08", "2018-08-10", "2018-08-11", "2018-08-11")),
+     ord  = ordered(c("ord3", "ord3", "ord3",
+                      "ord1", "ord2", "ord3",
+                      "ord1", "ord2", "ord3",
+                      "ord1", "ord1", "ord1", "ord1"),
+                    levels=c("ord1", "ord3", "ord2")),
+     fac  = as.factor(c("fac1", "fac1", "fac1",
+                        "fac2", "fac2", "fac2",
+                        "fac3", "fac3", "fac3",
+                        "fac1", "fac2", "fac3", "fac3")),
+     str  = c("str1", "str1", "str1", # will be treated like a factor
+              "str2", "str2", "str2",
+              "str3", "str3", "str3",
+              "str3", "str3", "str3", "str3"))
> 
> varied.type.earth <- earth(y ~ ., data = varied.type.data, thresh=0, penalty=-1, trace=1)
x[13,10] with colnames num int boolTRUE date ord.L ord.Q facfac2 facfac3 strstr2...
y[13,1] with colname y, and values 1, 2, 3, 4, 5, 6, 7, 8, 9, 10...
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18
Reached maximum RSq 1.0000 at 19 terms, 13 terms used (RSq 1.0000)
After forward pass GRSq 1.000 RSq 1.000
Prune backward penalty -1 nprune null: selected 13 of 13 terms, and 9 of 10 preds
After pruning pass GRSq 1 RSq 1
> print(summary(varied.type.earth))
Call: earth(formula=y~., data=varied.type.data, trace=1, thresh=0, penalty=-1)

              coefficients
(Intercept)      9.5964912
boolTRUE        -2.0473684
ord.L            0.4986964
ord.Q            0.0859470
facfac2         -4.4157895
facfac3         -3.1526316
strstr2          3.2526316
h(4-num)         1.4105263
h(num-4)        -0.3157895
h(4-int)         2.1157895
h(int-4)         0.3421053
h(17749-date)   -3.8210526
h(date-17749)    1.4368421

Selected 13 of 13 terms, and 9 of 10 predictors
Termination condition: Reached maximum RSq 1.0000 at 13 terms
Importance: date, facfac2, facfac3, int, strstr2, boolTRUE, num, ord.L, ...
Number of terms at each degree of interaction: 1 12 (additive model)
GCV 0    RSS 0    GRSq 1    RSq 1
> 
> cat("\n#=== from test.plotmo.args.R ===========================================\n")

#=== from test.plotmo.args.R ===========================================
> set.seed(2020)
> 
> oz2 <- ozone1[1:40,]
> set.seed(2015)
> a <- earth(O3~temp+wind, dat=oz2, deg=2, nk=21, ncr=3, nfo=3, varmod.me="lm")
> print(summary(a))
Call: earth(formula=O3~temp+wind, data=oz2, degree=2, nfold=3, ncross=3,
            varmod.method="lm", nk=21)

            coefficients
(Intercept)    3.8636364
h(temp-42)     0.1581028

Selected 2 of 13 terms, and 1 of 2 predictors
Termination condition: Reached nk 21
Importance: temp, wind-unused
Number of terms at each degree of interaction: 1 1 (additive model)
GCV 4.813872  RSS 160.332  GRSq 0.1971602  RSq 0.2967894  CVRSq -0.01337941

Note: the cross-validation sd's below are standard deviations across folds

Cross validation:   nterms 2.11 sd 0.33    nvars 1.11 sd 0.33

     CVRSq    sd     MaxErr   sd
    -0.013 0.283        8.7 4.66

varmod: method "lm"    min.sd 0.252    iter.rsq 0.064

stddev of predictions:
            coefficients iter.stderr iter.stderr%
(Intercept)    1.0887149    0.855322           79
O3             0.2608246    0.161143           62

                              mean   smallest    largest     ratio
95% prediction interval   9.890959   8.217919   12.58237   1.53109

                                         68%    80%     90%     95% 
response values in prediction interval   78     90     100     100  
> plotmo(a, caption.col=3, caption.font=2, grid.col="pink",
+        level=.8, SHOWCALL=TRUE)
 plotmo grid:    temp wind
                 53.5    4
> 
> cat("\n#=== from test.plotmo3.R ===========================================\n")

#=== from test.plotmo3.R ===========================================
> set.seed(2020)
> 
> # basic tests of plotmo on abbreviated titanic data
> 
> get.tita <- function()
+ {
+     tita <- etitanic
+     pclass <- as.character(tita$pclass)
+     # change the order of the factors so not alphabetical
+     pclass[pclass == "1st"] <- "first"
+     pclass[pclass == "2nd"] <- "class2"
+     pclass[pclass == "3rd"] <- "classthird"
+     tita$pclass <- factor(pclass, levels=c("class2", "classthird", "first"))
+     # log age is so we have a continuous predictor even when model is age~.
+     set.seed(2015)
+     tita$logage <- log(tita$age) + rnorm(nrow(tita))
+     tita$parch <- NULL
+     # by=12 gives us a small fast model with an additive and a interaction term
+     tita[seq(1, nrow(etitanic), by=12), ]
+ }
> tita <- get.tita()
> # tita[,4] is age
> set.seed(2020)
> mod.earth.tita.age <- earth(tita[,-4], tita[,4], degree=2, nfold=3, ncross=3, trace=.5, varmod.method="lm")
Model with pmethod="backward": GRSq 0.335 RSq 0.512 nterms 6
CV fold  1.1  CVRSq -0.047   n.oof 58 34%   n.infold.nz 58 100%   n.oof.nz 30 100%
CV fold  1.2  CVRSq -0.022   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV fold  1.3  CVRSq -0.045   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV fold  2.1  CVRSq  0.133   n.oof 58 34%   n.infold.nz 58 100%   n.oof.nz 30 100%
CV fold  2.2  CVRSq  0.338   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV fold  2.3  CVRSq  0.149   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV fold  3.1  CVRSq  0.419   n.oof 58 34%   n.infold.nz 58 100%   n.oof.nz 30 100%
CV fold  3.2  CVRSq  0.107   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV fold  3.3  CVRSq  0.307   n.oof 59 33%   n.infold.nz 59 100%   n.oof.nz 29 100%
CV all        CVRSq  0.149                  n.infold.nz 88 100%


varmod method="lm" rmethod="hc12" lambda=1 exponent=1 conv=1 clamp=0.1 minspan=-3:
     iter weight.ratio coefchange% (Intercept) tita[, 4]
        1          1.4         0.0          13    -0.032
        2          1.2         7.1          12    -0.018
        3          1.3         3.0          13    -0.024
        4          1.3         1.2          13    -0.022
        5          1.3         0.5          13    -0.023

> cat("\nsummary(mod.earth.tita.age)\n")

summary(mod.earth.tita.age)
> print(summary(mod.earth.tita.age))
Call: earth(x=tita[,-4], y=tita[,4], trace=0.5, degree=2, nfold=3, ncross=3,
            varmod.method="lm")

                            coefficients
(Intercept)                    25.664968
pclassfirst                     9.028974
h(sibsp-1)                    -12.096706
h(1.68119-logage)              -7.502937
sexmale * h(logage-2.48137)     5.062358
sibsp * h(logage-1.68119)       3.280947

Selected 6 of 14 terms, and 4 of 6 predictors
Termination condition: Reached nk 21
Importance: logage, sexmale, pclassclassthird-unused, sibsp, pclassfirst, ...
Number of terms at each degree of interaction: 1 3 2
GCV 174.7603  RSS 11022.31  GRSq 0.335155  RSq 0.5124778  CVRSq 0.1487371

Note: the cross-validation sd's below are standard deviations across folds

Cross validation:   nterms 3.89 sd 1.05    nvars 3.22 sd 0.97

     CVRSq    sd     MaxErr   sd
     0.149 0.174      -39.1 32.3

varmod: method "lm"    min.sd 1.49    iter.rsq 0.001

stddev of predictions:
            coefficients iter.stderr iter.stderr%
(Intercept)   15.7287403     2.77398           18
tita[, 4]     -0.0283536   0.0837154          295

                              mean   smallest    largest     ratio
95% prediction interval   58.24711   55.23254   62.56685   1.13279

                                         68%    80%    90%    95% 
response values in prediction interval   84     90     97     99  
> plotmo(mod.earth.tita.age, SHOWCALL=TRUE)
 plotmo grid:    pclass survived  sex sibsp  logage
             classthird        0 male     0 3.06991
> 
> set.seed(2020)
> mod.earth.sex <- earth(sex~., data=tita, degree=2, nfold=3, ncross=3, varmod.method="earth", glm=list(family=binomial), trace=.5)
Model with pmethod="backward": GRSq 0.333 RSq 0.478 nterms 5
CV fold  1.1  CVRSq -0.249   n.oof 61 31%   n.infold.nz 39 64%   n.oof.nz 20 74%
CV fold  1.2  CVRSq  0.038   n.oof 57 35%   n.infold.nz 39 68%   n.oof.nz 20 65%
CV fold  1.3  CVRSq  0.293   n.oof 58 34%   n.infold.nz 40 69%   n.oof.nz 19 63%
CV fold  2.1  CVRSq -1.534   n.oof 59 33%   n.infold.nz 39 66%   n.oof.nz 20 69%
CV fold  2.2  CVRSq  0.289   n.oof 54 39%   n.infold.nz 39 72%   n.oof.nz 20 59%
CV fold  2.3  CVRSq  0.212   n.oof 63 28%   n.infold.nz 40 63%   n.oof.nz 19 76%
CV fold  3.1  CVRSq  0.144   n.oof 59 33%   n.infold.nz 39 66%   n.oof.nz 20 69%
CV fold  3.2  Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
CVRSq -0.452   n.oof 59 33%   n.infold.nz 39 66%   n.oof.nz 20 69%
CV fold  3.3  CVRSq  0.522   n.oof 58 34%   n.infold.nz 40 69%   n.oof.nz 19 63%
CV all        CVRSq -0.082                  n.infold.nz 59 67%


varmod method="earth" rmethod="hc12" lambda=1 exponent=1 conv=1 clamp=0.1 minspan=-3:
     iter weight.ratio coefchange% (Intercept) h(male-0.425371)
        1           14           0        0.73               -1
 h(0.425371-male)
             -1.1

> cat("\nsummary(mod.earth.sex)\n")

summary(mod.earth.sex)
> print(summary(mod.earth.sex))
Call: earth(formula=sex~., data=tita, trace=0.5, glm=list(family=binomial),
            degree=2, nfold=3, ncross=3, varmod.method="earth")

GLM coefficients
                                   male
(Intercept)                   2.2100473
survived                     -5.5463575
pclassclassthird * h(31-age) -0.1144390
survived * h(age-31)          0.2623977
survived * h(31-age)          0.1814641

GLM (family binomial, link logit):
 nulldev df       dev df   devratio     AIC iters converged
 111.559 87   67.1605 83      0.398   77.16     5         1

Earth selected 5 of 12 terms, and 3 of 6 predictors
Termination condition: Reached nk 21
Importance: survived, age, pclassclassthird, pclassfirst-unused, ...
Number of terms at each degree of interaction: 1 1 3
Earth GCV 0.1507171  RSS 10.15456  GRSq 0.3332684  RSq 0.4777313  CVRSq -0.08180991

Note: the cross-validation sd's below are standard deviations across folds

Cross validation:   nterms 3.78 sd 1.39    nvars 2.89 sd 1.17

  CVRSq    sd ClassRate   sd MaxErr    sd   AUC   sd MeanDev   sd CalibInt
 -0.082 0.619     0.745 0.08     -1 0.951 0.719 0.14    2.61 2.77     0.27
    sd CalibSlope    sd
 0.612       0.63 0.588

varmod: method "earth"    min.sd 0.0412    iter.rsq 0.246

stddev of predictions:
                 coefficients iter.stderr iter.stderr%
(Intercept)         0.9211535    0.104791           11
h(0.425371-male)   -1.4199715     0.37374           26
h(male-0.425371)   -1.2999441    0.247601           19

                              mean    smallest    largest     ratio
95% prediction interval   1.615511   0.9644817   3.610856   3.74383

                                         68%    80%    90%    95% 
response values in prediction interval   90     92     94     94< 
> plotmo(mod.earth.sex, SHOWCALL=TRUE)
 plotmo grid:    pclass survived age sibsp  logage
             classthird        0  30     0 3.06991
> 
> cat("\n#=== from test.unusual.vars.R ===========================================\n")

#=== from test.unusual.vars.R ===========================================
> set.seed(2020)
> 
> vdata <- data.frame(
+     resp = 1:13,
+     bool = c(F, F, F, F, F, T, T, T, T, T, T, T, T),
+     ord  = ordered(c("ORD1", "ORD1", "ORD1",
+                      "ORD1", "ORD1", "ORD1",
+                      "ORD3", "ORD3", "ORD3",
+                      "ORD2", "ORD2", "ORD2", "ORD2"),
+                    levels=c("ORD1", "ORD3", "ORD2")),
+     fac  = as.factor(c("FAC1", "FAC1", "FAC1",
+                        "FAC2", "FAC2", "FAC2",
+                        "FAC3", "FAC3", "FAC3",
+                        "FAC1", "FAC2", "FAC3", "FAC3")),
+     str  = c("STR1", "STR1", "STR1", # WILL BE TREATED LIKE A FACTOR
+              "STR2", "STR2", "STR2",
+              "STR3", "STR3", "STR3",
+              "STR3", "STR3", "STR3", "STR3"),
+     num  = c(1, 3, 2, 3, 4, 5, 6, 4, 5, 6.5, 3, 6, 5), # 7 unique values (but one is non integral)
+     sqrt_num  = sqrt(c(1, 3, 2, 3, 4, 5, 6, 4, 5, 6.5, 3, 6, 5)),
+     int  = c(1L, 1L, 3L, 3L, 4L, 4L, 3L, 5L, 3L, 6L, 7L, 8L, 10L), # 8 unique values
+     date = as.Date(
+            c("2018-08-01", "2018-08-02", "2018-08-03",
+              "2018-08-04", "2018-08-05", "2018-08-06",
+              "2018-08-07", "2018-08-08", "2018-08-08",
+              "2018-08-08", "2018-08-10", "2018-08-11", "2018-08-11")),
+     date_num = as.numeric(as.Date(
+            c("2018-08-01", "2018-08-02", "2018-08-03",
+              "2018-08-04", "2018-08-05", "2018-08-06",
+              "2018-08-07", "2018-08-08", "2018-08-08",
+              "2018-08-08", "2018-08-10", "2018-08-11", "2018-08-11"))))
> 
> vdata$off <- (1:nrow(vdata)) / nrow(vdata)
> 
> resp2 <- 13:1
> 
> vweights <- rep(1, length.out=nrow(vdata))
> vweights[1] <- 2
> 
> set.seed(2020)
> lognum.bool.ord.off <- earth(resp ~ log(num) + bool + ord + offset(off), degree=2, weights=vweights,
+            data=vdata, pmethod="none", varmod.method="lm",
+            nfold=2, ncross=3,
+            trace=1)
x[13,4] with colnames log(num) boolTRUE ord.L ord.Q
y[13,1] with colname resp, and values 0.9231, 1.846, 2.769, 3.692, ...
weights[13]: 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Forward pass term 1, 2, 4, 6, 8
GRSq -Inf at 7 terms, 5 terms used
After forward pass GRSq -in RSq 0.966
Prune none penalty 3 nprune null: selected 5 of 5 terms, and 3 of 4 preds
After pruning pass GRSq -0.732 RSq 0.952

CV fold  1.1  CVRSq -0.476   n.oof  6 54%   n.infold.nz  6 100%   n.oof.nz  7 100%
CV fold  1.2  CVRSq  0.823   n.oof  7 46%   n.infold.nz  7 100%   n.oof.nz  6 100%
CV fold  2.1  CVRSq -0.622   n.oof  6 54%   n.infold.nz  6 100%   n.oof.nz  7 100%
CV fold  2.2  CVRSq  0.816   n.oof  7 46%   n.infold.nz  7 100%   n.oof.nz  6 100%
CV fold  3.1  CVRSq  0.559   n.oof  6 54%   n.infold.nz  6 100%   n.oof.nz  7 100%
CV fold  3.2  CVRSq  0.698   n.oof  7 46%   n.infold.nz  7 100%   n.oof.nz  6 100%
CV all        CVRSq  0.300                  n.infold.nz 13 100%


varmod method="lm" rmethod="hc12" lambda=1 exponent=1 conv=1 clamp=0.1 minspan=-3:
     iter weight.ratio coefchange% (Intercept)  resp
        1          1.6        0.00        1.76 0.045
        2          2.2       39.64        1.55 0.076
        3          2.9       19.19        1.40 0.098
        4          3.5       12.21        1.29 0.115
        5          4.1        8.66        1.21 0.127
        6          4.6        6.50        1.15 0.137
        7          5.0        5.05        1.10 0.145
        8          5.5        4.02        1.06 0.152
        9          5.8        3.25        1.03 0.157
       10          6.1        2.66        1.00 0.162
       11          6.4        2.19        0.98 0.165
       12          6.7        1.82        0.97 0.168
       13          6.9        1.52        0.95 0.171
       14          7.1        1.28        0.94 0.173
       15          7.3        1.08        0.93 0.175
       16          7.4        0.91        0.92 0.176

> print(summary(lognum.bool.ord.off))
Call: earth(formula=resp~log(num)+bool+ord+offset(off), data=vdata,
            weights=vweights, pmethod="none", trace=1, degree=2, nfold=2,
            ncross=3, varmod.method="lm")

                                 coefficients
(Intercept)                          6.273213
boolTRUE                             1.111403
h(-7.85046e-17-ord.L)               -7.600147
h(ord.L- -7.85046e-17)               4.568998
log(num) * h(-7.85046e-17-ord.L)     3.100021

Selected 5 of 5 terms, and 3 of 4 predictors (pmethod="none")
Termination condition: GRSq -Inf at 5 terms
Importance: ord.L, log(num), boolTRUE, ord.Q-unused
Offset: off with values 0.07692308, 0.1538462, 0.2307692, 0.3076923, 0.3...
Weights: 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Number of terms at each degree of interaction: 1 3 1
GCV 28.70012  RSS 8.830806  GRSq -0.7319038  RSq 0.9518916  CVRSq 0.2995745

Note: the cross-validation sd's below are standard deviations across folds

Cross validation:   nterms 2.33 sd 0.52    nvars 1.00 sd 0.00

     CVRSq    sd     MaxErr   sd
       0.3 0.666         -6 3.53

varmod: method "lm"    min.sd 0.27    iter.rsq 0.204

stddev of predictions:
            coefficients iter.stderr iter.stderr%
(Intercept)     1.151190    0.759983           66
resp            0.220811    0.131375           59

                              mean   smallest    largest      ratio
95% prediction interval   10.57312   5.357389   14.56643   2.718942

                                          68%     80%     90%     95% 
response values in prediction interval   100     100     100     100  
> 
> cat("\n#=== from test.caret.R ===========================================\n")

#=== from test.caret.R ===========================================
> set.seed(2020)
> 
> library(caret)
Loading required package: ggplot2
Loading required package: lattice
> set.seed(2015)
> a.bag3 <- bagEarth(survived~., data=etitanic, degree=2, B=3, trace=1)
x[1046,7] with colnames pclass1st pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname subY, and values 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,...
weights: no weights (because all weights equal)
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.435 RSq 0.472
Prune backward penalty 3 nprune null: selected 10 of 15 terms, and 6 of 7 preds
After pruning pass GRSq 0.444 RSq 0.468
x[1046,7] with colnames pclass1st pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname subY, and values 0, 0, 1, 1, 1, 0, 0, 0, 1, 1,...
weights: no weights (because all weights equal)
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.385 RSq 0.434
Prune backward penalty 3 nprune null: selected 12 of 18 terms, and 6 of 7 preds
After pruning pass GRSq 0.402 RSq 0.433
x[1046,7] with colnames pclass1st pclass2nd pclass3rd sexmale age sibsp parch
y[1046,1] with colname subY, and values 1, 1, 0, 1, 1, 1, 0, 1, 0, 0,...
weights: no weights (because all weights equal)
Forward pass term 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reached nk 21
After forward pass GRSq 0.451 RSq 0.487
Prune backward penalty 3 nprune null: selected 13 of 15 terms, and 6 of 7 preds
After pruning pass GRSq 0.456 RSq 0.487
> print(a.bag3)

Call:
bagEarth.formula(formula = survived ~ ., data = etitanic, B = 3,     degree = 2, trace = 1)

Data:
   # variables:	 7 
   # samples:	 1046 
case weights used

B: 3 
> plotmo(a.bag3, clip=F, caption="bagEarth, etitanic", trace=1, SHOWCALL=TRUE)
stats::predict(bagEarth.object, data.frame[3,7], type="response")
stats::fitted(object=bagEarth.object)
fitted() was unsuccessful, will use predict() instead
assuming "survived" in the model.frame is the response, because terms(object) did not return the terms
assuming "survived" in the model.frame is the response, because terms(object) did not return the terms
got model response from model.frame(survived ~ .,
                                    data=call$data, na.action="na.fail")

 plotmo grid:    pclass1st pclass2nd pclass3rd sexmale age sibsp parch
                         0         0         0       1  28     0     0

> plotres(a.bag3, clip=F, trace=1, SHOWCALL=TRUE)
stats::residuals(object=bagEarth.object, type="response")
residuals() was unsuccessful, will use predict() instead
stats::predict(bagEarth.object, data.frame[3,7], type="response", clip=FALSE)
stats::fitted(object=bagEarth.object)
fitted() was unsuccessful, will use predict() instead
assuming "survived" in the model.frame is the response, because terms(object) did not return the terms
assuming "survived" in the model.frame is the response, because terms(object) did not return the terms
got model response from model.frame(survived ~ .,
                                    data=call$data, na.action="na.fail")
assuming "survived" in the model.frame is the response, because terms(object) did not return the terms

training rsq 0.44
> 
> # Following commented out because too slow
> #
> # cat("\n#=== from test.parsnip.R ===========================================\n")
> # set.seed(2020)
> #
> # cat("loading parsnip libraries\n") # these libraries take several seconds to load
> # library(tidymodels)
> # library(timetk)
> # library(lubridate)
> # cat("loaded parsnip libraries\n")
> # cat("parsnip version:", as.character(packageVersion("parsnip")[[1]]), "\n")
> #
> # vdata <- data.frame(
> #     resp    = 1:23,
> #     bool = c(F, F, F, F, F, T, T, T, T, T, T, T, T, F, F, T, T, T, T, T, T, T, T),
> #     ord  = ordered(c("ORD1", "ORD1", "ORD1",
> #                      "ORD1", "ORD1", "ORD1",
> #                      "ORD1", "ORD3", "ORD1",
> #                      "ORD2", "ORD2", "ORD2", "ORD2",
> #                      "ORD2", "ORD2", "ORD2",
> #                      "ORD3", "ORD3", "ORD3",
> #                      "ORD2", "ORD2", "ORD2", "ORD2"),
> #                    levels=c("ORD1", "ORD3", "ORD2")),
> #     fac  = as.factor(c("FAC1", "FAC1", "FAC1",
> #                        "FAC2", "FAC2", "FAC2",
> #                        "FAC3", "FAC1", "FAC1",
> #                        "FAC1", "FAC2", "FAC2", "FAC2",
> #                        "FAC2", "FAC2", "FAC2",
> #                        "FAC3", "FAC3", "FAC3",
> #                        "FAC1", "FAC3", "FAC3", "FAC3")),
> #     str  = c("STR1", "STR1", "STR1", # WILL BE TREATED LIKE A FACTOR
> #              "STR1", "STR1", "STR1",
> #              "STR2", "STR2", "STR2",
> #              "STR3", "STR3", "STR2", "STR3",
> #              "STR2", "STR3", "STR2",
> #              "STR3", "STR3", "STR3",
> #              "STR3", "STR3", "STR3", "STR3"),
> #     num  = c(1, 9, 2, 3, 14, 5, 6, 4, 5, 6.5, 3, 6, 5,
> #              3, 4, 5, 6, 4, 5, 16.5, 3, 16, 15),
> #     sqrt_num  = sqrt(
> #            c(1, 9, 2, 3, 14, 5, 6, 4, 5, 6.5, 3, 6, 5,
> #              3, 4, 5, 6, 4, 5, 16.5, 3, 16, 15)),
> #     int  = c(1L, 1L, 3L, 3L, 4L, 4L, 3L, 5L, 3L, 6L, 7L, 8L, 10L,
> #              13L, 14L, 3L, 13L, 5L, 13L, 16L, 17L, 18L, 11L),
> #     date = as.Date(
> #            c("2018-08-01", "2018-08-02", "2018-08-03",
> #              "2018-08-04", "2018-08-05", "2018-08-06",
> #              "2018-08-07", "2018-08-08", "2018-08-08",
> #              "2018-08-10", "2018-08-10", "2018-08-11", "2018-08-11",
> #              "2018-08-11", "2018-08-12", "2018-08-13",
> #              "2018-08-10", "2018-08-15", "2018-08-17",
> #              "2018-08-04", "2018-08-19", "2018-08-03", "2018-08-18")),
> #     date_num = as.numeric(as.Date(
> #            c("2018-08-01", "2018-08-02", "2018-08-03",
> #              "2018-08-04", "2018-08-05", "2018-08-06",
> #              "2018-08-07", "2018-08-08", "2018-08-08",
> #              "2018-08-10", "2018-08-10", "2018-08-11", "2018-08-11",
> #              "2018-08-11", "2018-08-12", "2018-08-13",
> #              "2018-08-10", "2018-08-15", "2018-08-17",
> #              "2018-08-04", "2018-08-19", "2018-08-03", "2018-08-18"))))
> #
> # set.seed(2020)
> # splits <- initial_time_split(vdata, prop=.9)
> #
> # cat("===m750a first example===\n")
> # set.seed(2020)
> # m750a <- m4_monthly %>%
> #     filter(id == "M750") %>%
> #     select(-id)
> # print(m750a) # a tibble
> # set.seed(2020)
> # splits_a <- initial_time_split(m750a, prop = 0.9)
> # earth_m750a <- earth(log(value) ~ as.numeric(date) + month(date, label = TRUE), data = training(splits_a), degree=2)
> # print(summary(earth_m750a))
> 
> cat("\n#=== from test.non.earth.R ===========================================\n")

#=== from test.non.earth.R ===========================================
> set.seed(2020)
> 
> # Following gives different results on different systems (Oct 2020, earth 5.3.0).
> # For example:
> #   Win7 (Intel i7-4910MQ): Earth selected 7 of 19 terms, and 3 of 3 predictors, GRSq 0.20041 RSq 0.47214
> #   Ubuntu (Intel P8600):   Earth selected 2 of 19 terms, and 1 of 3 predictors, GRSq 0.18687 RSq 0.23689
> 
> library(rpart) # for kyphosis data
> data(kyphosis)
> a <- earth(Kyphosis ~ ., data=kyphosis, degree=2, glm=list(family=binomial), trace=4)
Call: earth(formula=Kyphosis~., data=kyphosis, trace=4,
            glm=list(family=binomial), degree=2)

x[81,3]:
    Age Number Start
1    71      3     5
2   158      3    14
3   128      4     5
...   2      5     1
81   36      4    13

y[81,1]:
    present
1         0
2         0
3         1
...       0
81        0

Forward pass: minspan 4 endspan 8   x[81,3] 1.9 kB   bx[81,21] 13.3 kB

         GRSq    RSq     DeltaRSq Pred     PredName         Cut  Terms   Par Deg
1      0.0000 0.0000                    (Intercept)
2      0.1485 0.2516       0.2516    3        Start           6  2   3         1 
4      0.1233 0.3288      0.07718    1          Age          97  4   5         1 
6      0.0792 0.3921      0.06334    1          Age         114  6   7     2   2 
8     -0.0291 0.4212      0.02903    2       Number           3  8   9     5   2 
10    -0.1701 0.4470      0.02581    2       Number           3  10  11    2   2 
12    -0.3036 0.4908      0.04382    2       Number           6  12  13        1 
14    -0.4432 0.5434      0.05258    1          Age          78  14  15   13   2 
16    -0.4927 0.5787      0.03535    2       Number           3  16            1 
18    -0.8279 0.5984      0.01966    1          Age          42  17  18   16   2 
20    -1.0151 0.6143      0.01592    3        Start           5  19            1 final (reached nk 21)

Reached nk 21
After forward pass GRSq -1.015 RSq 0.614
Forward pass complete: 21 terms, 19 terms used

Subset size        GRSq     RSq  DeltaGRSq nPreds  Terms (col nbr in bx)
          1      0.0000  0.0000     0.0000      0  1
          2      0.1869  0.2369     0.1869      1  1 2
          3      0.1901  0.2882     0.0032      2  1 2 5
          4      0.1995  0.3426     0.0094      2  1 2 5 7
          5      0.1810  0.3729    -0.0186      3  1 2 5 7 8
          6      0.1708  0.4097    -0.0102      3  1 2 5 7 10 13
chosen    7      0.2004  0.4721     0.0296      3  1 2 5 7 10 13 17
          8      0.1859  0.5031    -0.0145      3  1 2 5 7 10 13 17 19
          9      0.1364  0.5142    -0.0494      3  1 2 5 7 10 12 13 15 17
         10      0.1063  0.5383    -0.0302      3  1 2 5 7 10 13 15 17 18 19
         11      0.0736  0.5621    -0.0326      3  1 2 5 7 10 12 13 15 17 18 19
         12      0.0143  0.5755    -0.0593      3  1 2 5 7 10 11 12 13 15 17 18 19
         13     -0.0384  0.5944    -0.0527      3  1 2 5 7 8 10 11 12 13 15 17 18 19
         14     -0.1170  0.6062    -0.0786      3  1 2 5 6 7 8 10 11 12 13 15 17 18 19
         15     -0.2333  0.6098    -0.1163      3  1 2 5 6 7 8 9 10 11 12 13 15 17 18 19
         16     -0.3686  0.6137    -0.1353      3  1 2 5 6 7 8 9 10 11 12 13 15 16 17 18 19
         17     -0.5432  0.6142    -0.1746      3  1 2 3 5 6 7 8 9 10 11 12 13 15 16 17 18 19
         18     -0.7555  0.6143    -0.2123      3  1 2 3 4 5 6 7 8 9 10 11 12 13 15 16 17 18 19
         19     -1.0151  0.6143    -0.2596      3  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Prune backward penalty 3 nprune null: selected 7 of 19 terms, and 3 of 3 preds
After pruning pass GRSq 0.2 RSq 0.472

glm y[81,1]:
    present
1         0
2         0
3         1
...       0
81        0

glm weights: NULL

GLM present devratio 0.56 dof 74/80 iters 8
> print(summary(a))
Call: earth(formula=Kyphosis~., data=kyphosis, trace=4,
            glm=list(family=binomial), degree=2)

GLM coefficients
                            present
(Intercept)              12.4739052
h(97-Age)                -0.1563678
h(6-Number)              -3.8334755
h(Start-6)               -0.3798750
h(Age-42) * h(Number-3)  -0.0197570
h(114-Age) * h(Start-6)   0.0089521
h(Number-3) * h(Start-6) -0.3545004

GLM (family binomial, link logit):
 nulldev df       dev df   devratio     AIC iters converged
 83.2345 80   36.4652 74      0.562   50.47     8         1

Earth selected 7 of 19 terms, and 3 of 3 predictors
Termination condition: Reached nk 21
Importance: Start, Age, Number
Number of terms at each degree of interaction: 1 3 3
Earth GCV 0.1359306    RSS 7.090206    GRSq 0.2004084    RSq 0.4721446
> par(mfrow=c(3,3))
> plotmo(a, type2="image", do.par=FALSE,
+         col.response=ifelse(kyphosis$Kyphosis=="present", "red", "lightblue"),
+         clip=F)
 plotmo grid:    Age Number Start
                  87      4    13
> plotmo(a, clip=F, degree1=0, do.par=FALSE)
> 
> source("test.epilog.R")
