# Matrix or Formula interface

    library(unifiedml)

    ## Loading required package: doParallel

    ## Loading required package: foreach

    ## Loading required package: iterators

    ## Loading required package: parallel

    ## Loading required package: R6

    # Example 1: lm with matrix interface (including factors)
    demo_lm_matrix <- function() {
      cat("\n=== Example 1: lm with matrix interface ===\n")

      lm_matrix <- unifiedml::formula_to_matrix(stats::lm)  # Uses generic predict()

      # Create data with factor and numeric columns
      X <- data.frame(
        wt = mtcars$wt,
        hp = mtcars$hp,
        cyl = factor(mtcars$cyl)
      )
      y <- mtcars$mpg
      weights <- rep(1, nrow(X))

      model <- lm_matrix$fit(X, y, weights = weights)
      preds <- lm_matrix$predict(model, X[1:5, ])

      cat("Predictions:\n")
      print(preds)
      cat("\nCoefficients:\n")
      print(coef(model))
    }

    # Example 2: glmnet with formula interface (with factors)
    demo_glmnet_formula <- function() {
      cat("\n=== Example 2: glmnet with formula interface ===\n")

      if (!requireNamespace("glmnet", quietly = TRUE)) {
        cat("glmnet package not installed, skipping example\n")
        return(invisible(NULL))
      }

      glmnet_formula <- unifiedml::matrix_to_formula(
        fit_func = glmnet::glmnet,
        predict_func = function(model, newX, ...) {
          # Wrapper to provide default s parameter
          glmnet::predict.glmnet(model, newx = newX, s = 0.01, ...)
        }
      )

      # Formula with factor - model.matrix will auto-create dummies
      model <- glmnet_formula$fit(mpg ~ wt + hp + factor(cyl), data = mtcars)
      preds <- glmnet_formula$predict(model, newdata = mtcars[1:5, ])

      cat("Predictions:\n")
      print(preds)
    }

    # Example 3: Special characters in column names
    demo_special_names <- function() {
      cat("\n=== Example 3: Column names with special characters ===\n")

      lm_matrix <- unifiedml::formula_to_matrix(lm)

      # Create problematic column names
      X <- data.frame(
        `x-1` = mtcars$wt,      # Dash
        `a:b` = mtcars$hp,       # Colon
        `log(x)` = log(mtcars$disp),  # Parentheses
        check.names = FALSE
      )
      y <- mtcars$mpg

      model <- lm_matrix$fit(X, y)
      preds <- lm_matrix$predict(model, X[1:3, ])

      cat("Predictions:\n")
      print(preds)
      cat("\nModel handled special column names correctly!\n")
    }

    # Run examples (uncomment to test)
    demo_lm_matrix()

    ##
    ## === Example 1: lm with matrix interface ===
    ## Predictions:
    ##        1        2        3        4        5
    ## 21.60851 20.79725 26.31500 19.71558 17.67011
    ##
    ## Coefficients:
    ## (Intercept)          wt          hp        cyl6        cyl8
    ## 35.84599532 -3.18140405 -0.02311981 -3.35902490 -3.18588444

    demo_glmnet_formula()

    ##
    ## === Example 2: glmnet with formula interface ===
    ## Predictions:
    ##                     s=0.01
    ## Mazda RX4         21.65238
    ## Mazda RX4 Wag     20.83774
    ## Datsun 710        26.26479
    ## Hornet 4 Drive    19.75155
    ## Hornet Sportabout 17.70497

    demo_special_names()

    ##
    ## === Example 3: Column names with special characters ===
    ## Predictions:
    ##        1        2        3
    ## 22.92749 22.38846 25.67092
    ##
    ## Model handled special column names correctly!