packages feed

dataframe-learn 2.5.0.0 → 2.5.0.1

raw patch · 16 files changed

+230/−225 lines, 16 filesdep ~dataframe-coredep ~dataframe-expr-serializerdep ~dataframe-operationsPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: dataframe-core, dataframe-expr-serializer, dataframe-operations

API changes (from Hackage documentation)

Files

README.md view
@@ -41,7 +41,7 @@     , "y" =: [2 * x + 1 | x <- [1, 2, 3, 4, 5, 6]] :: [Double]     ] -model = fit defaultLinearConfig (D.col @Double "y") sales+model = fit defaultLinearConfig (D.double "y") sales putStrLn (D.prettyPrint (predict model)) ``` @@ -115,7 +115,7 @@     , "species"      =: [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2] :: [Double]     ] -tree = fit defaultTreeConfig (D.col @Double "species") flowers+tree = fit defaultTreeConfig (D.double "species") flowers putStrLn (D.prettyPrint (predict tree)) ``` @@ -180,7 +180,7 @@  sr = fit         defaultSRConfig { srSeed = 3, srGenerations = 50, srPopSize = 300, srUnaryOps = [] }-        (D.col @Double "y") curve+        (D.double "y") curve putStrLn (D.prettyPrint (srBest sr) ++ "   (mse " ++ show (srBestMSE sr) ++ ")") ``` @@ -198,7 +198,6 @@ > <!-- scripths:mime text/plain --> > <interactive>:87:47: error: [GHC-88464] >     Variable not in scope: model->     Suggested fix: Perhaps use ‘T.mode’ (imported from DataFrame.Typed) >  > <interactive>:87:54: error: [GHC-88464] >     Variable not in scope: sales :: D.DataFrame@@ -215,7 +214,7 @@ ```haskell scaler      = standardScaler ["x"] sales scaledSales = applyTransform (scalerTransform scaler) sales-scaledModel = fit defaultLinearConfig (D.col @Double "y") scaledSales+scaledModel = fit defaultLinearConfig (D.double "y") scaledSales  deployed = compileThrough (scalerTransform scaler) (predict scaledModel) putStr (unlines@@ -242,14 +241,14 @@ original frame with no preprocessing step at inference time.  ```haskell-evaluate rmse deployed (D.col @Double "y") sales+evaluate rmse deployed (D.double "y") sales ```  > <!-- scripths:mime text/plain --> > <interactive>:112:15: error: [GHC-88464] >     Variable not in scope: deployed :: D.Expr Double > -> <interactive>:112:44: error: [GHC-88464]+> <interactive>:112:39: error: [GHC-88464] >     Variable not in scope: sales :: D.DataFrame  ## Splitting the data, and evaluation@@ -279,10 +278,10 @@ import System.Random (mkStdGen)  (train, test) = D.randomSplit (mkStdGen 7) 0.75 clean-heldModel     = fit defaultLinearConfig (D.col @Double "y") train+heldModel     = fit defaultLinearConfig (D.double "y") train putStr (unlines-    [ "held-out R^2:  " ++ show (evaluate r2   (predict heldModel) (D.col @Double "y") test)-    , "held-out RMSE: " ++ show (evaluate rmse (predict heldModel) (D.col @Double "y") test) ])+    [ "held-out R^2:  " ++ show (evaluate r2   (predict heldModel) (D.double "y") test)+    , "held-out RMSE: " ++ show (evaluate rmse (predict heldModel) (D.double "y") test) ]) ```  > <!-- scripths:mime text/plain -->@@ -294,8 +293,8 @@ fold. You pass a `train -> Expr` closure, so it works with any model:  ```haskell-cv = crossValidate 5 0 rmse (D.col @Double "y")-         (\tr -> predict (fit defaultLinearConfig (D.col @Double "y") tr))+cv = crossValidate 5 0 rmse (D.double "y")+         (\tr -> predict (fit defaultLinearConfig (D.double "y") tr))          clean putStrLn ("5-fold RMSE: " ++ show (sum cv / fromIntegral (length cv))) ```@@ -313,17 +312,17 @@ macro/weighted averages):  ```haskell-clf = fit defaultLogisticConfig (D.col @Double "species") flowers-putStr (show (classificationReportExpr (predict clf) (D.col @Double "species") flowers))+clf = fit defaultLogisticConfig (D.double "species") flowers+putStr (show (classificationReportExpr (predict clf) (D.double "species") flowers)) ```  > <!-- scripths:mime text/plain -->-> <interactive>:170:59: error: [GHC-88464]+> <interactive>:170:54: error: [GHC-88464] >     Variable not in scope: flowers :: D.DataFrame >  > <interactive>:173:49: error: [GHC-88464] Variable not in scope: clf > -> <interactive>:173:80: error: [GHC-88464]+> <interactive>:173:75: error: [GHC-88464] >     Variable not in scope: flowers :: D.DataFrame  ## Pipelines compose as a monoid@@ -335,7 +334,7 @@ ```haskell features = ["petal_length", "petal_width"] scalerF  = standardScaler features flowers-pca      = fit (PCAConfig (NComp 2) True) (map (D.col @Double) features) flowers+pca      = fit (PCAConfig (NComp 2) True) (map (D.double) features) flowers pipeline = scalerTransform scalerF <> pcaTransform pca  D.columnNames (applyTransform pipeline flowers)@@ -345,7 +344,7 @@ > <interactive>:182:36: error: [GHC-88464] >     Variable not in scope: flowers :: D.DataFrame > -> <interactive>:183:74: error: [GHC-88464]+> <interactive>:183:69: error: [GHC-88464] >     Variable not in scope: flowers :: D.DataFrame >  > <interactive>:188:31: error: [GHC-88464]@@ -373,17 +372,17 @@     as = [-1, -1, 1, 1, -2, 2, -2, 2] :: [Double]     bs = [-1, 1, -1, 1, -2, -2, 2, 2] :: [Double] -rawModel = fit defaultLinearConfig (D.col @Double "y") interactions-feature  = fit defaultSynthesisConfig (D.col @Double "y") interactions+rawModel = fit defaultLinearConfig (D.double "y") interactions+feature  = fit defaultSynthesisConfig (D.double "y") interactions withFeat = D.derive "synth" (predict feature) interactions fitModel =-    fit defaultLinearConfig (D.col @Double "y")+    fit defaultLinearConfig (D.double "y")         (D.select ["synth", "y"] withFeat)  putStr (unlines     [ "discovered feature: " ++ D.prettyPrint (predict feature)-    , "raw linear R^2:     " ++ show (evaluate r2 (predict rawModel) (D.col @Double "y") interactions)-    , "with synth feature: " ++ show (evaluate r2 (predict fitModel) (D.col @Double "y") withFeat)+    , "raw linear R^2:     " ++ show (evaluate r2 (predict rawModel) (D.double "y") interactions)+    , "with synth feature: " ++ show (evaluate r2 (predict fitModel) (D.double "y") withFeat)     ]) ``` 
dataframe-learn.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.4 name:               dataframe-learn-version:            2.5.0.0+version:            2.5.0.1 synopsis:           Interpretable, expression-returning machine learning for the dataframe ecosystem. description:     A small scikit-learn-style ML library where every model returns both an@@ -62,8 +62,8 @@                         containers >= 0.6.7 && < 0.10,                         parallel >= 3.3 && < 4,                         random >= 1.2 && < 2,-                        dataframe-core >= 2.6 && < 2.7,-                        dataframe-operations >= 2.6 && < 2.7,+                        dataframe-core >= 2.7 && < 2.8,+                        dataframe-operations >= 2.7 && < 2.8,                         text >= 2.1 && < 3,                         vector >= 0.13 && < 0.15,                         vector-algorithms >= 0.9 && < 0.11@@ -106,11 +106,11 @@                         containers >= 0.6.7 && < 0.10,                         parallel >= 3.3 && < 4,                         random >= 1.2 && < 2,-                        dataframe-core >= 2.6 && < 2.7,-                        dataframe-core >= 2.6 && < 2.7,-                        dataframe-operations >= 2.6 && < 2.7,-                        dataframe-operations >= 2.6 && < 2.7,-                        dataframe-expr-serializer >= 1.3 && < 1.4,+                        dataframe-core >= 2.7 && < 2.8,+                        dataframe-core >= 2.7 && < 2.8,+                        dataframe-operations >= 2.7 && < 2.8,+                        dataframe-operations >= 2.7 && < 2.8,+                        dataframe-expr-serializer >= 1.4 && < 1.5,                         dataframe-learn:internal,                         text >= 2.1 && < 3,                         vector >= 0.13 && < 0.15,@@ -144,13 +144,13 @@                         aeson >= 0.11.0.0 && < 3,                         bytestring >= 0.11 && < 0.14,                         containers >= 0.6.7 && < 0.10,-                        dataframe-core >= 2.6 && < 2.7,-                        dataframe-core >= 2.6 && < 2.7,+                        dataframe-core >= 2.7 && < 2.8,+                        dataframe-core >= 2.7 && < 2.8,                         dataframe-csv >= 2.3 && < 2.4,                         dataframe-learn,                         dataframe-learn:internal,-                        dataframe-operations >= 2.6 && < 2.7,-                        dataframe-operations >= 2.6 && < 2.7,+                        dataframe-operations >= 2.7 && < 2.8,+                        dataframe-operations >= 2.7 && < 2.8,                         HUnit >= 1.6 && < 1.8,                         QuickCheck >= 2 && < 3,                         random >= 1 && < 2,
src-internal/DataFrame/DecisionTree/Cart.hs view
@@ -301,7 +301,7 @@     (Columnable b, VU.Unbox b) =>     T.Text -> Maybe Bitmap -> VU.Vector b -> [CartFeature] numericFeature c Nothing v = case testEquality (typeRep @b) (typeRep @Double) of-    Just Refl -> [CartFeature v Nothing (\t _ -> F.col @Double c .<=. F.lit t)]+    Just Refl -> [CartFeature v Nothing (\t _ -> F.double c .<=. F.lit t)]     Nothing -> case sIntegral @b of         STrue ->             [ CartFeature@@ -327,9 +327,9 @@     T.Text -> Maybe (b -> Double, Double -> Expr (Maybe Bool)) nullableLeq c     | Just Refl <- testEquality (typeRep @b) (typeRep @Double) =-        Just (id, \t -> F.col @(Maybe Double) c .<= F.lit t)+        Just (id, \t -> F.maybeDouble c .<= F.lit t)     | Just Refl <- testEquality (typeRep @b) (typeRep @Int) =-        Just (fromIntegral, \t -> F.col @(Maybe Int) c .<= F.lit t)+        Just (fromIntegral, \t -> F.maybeInt c .<= F.lit t)     | otherwise = Nothing  oneHotFeatures ::@@ -348,7 +348,7 @@     CartFeature         (VU.generate (V.length v) (\i -> if v V.! i == cat then 1 else 0))         Nothing-        (\_ _ -> F.col @T.Text c ./=. F.lit cat)+        (\_ _ -> F.text c ./=. F.lit cat) oneHot c (Just nulls) v cat =     CartFeature         (VU.generate (V.length v) value)@@ -359,7 +359,7 @@         | nulls VU.! i = 1 / 0         | v V.! i == cat = 1         | otherwise = 0-    col' = F.col @(Maybe T.Text) c+    col' = F.maybeText c     -- Threshold 1 passes every non-null row, so that split is null vs non-null.     cond t side         | t < 1 = F.fromMaybe (side == NullsLeft) (col' ./= F.lit cat)
src-internal/DataFrame/DecisionTree/CondVec.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE GADTs #-}-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} @@ -24,10 +23,12 @@ import DataFrame.Internal.Column (TypedColumn (..), toVector) import DataFrame.Internal.DataFrame (DataFrame) import DataFrame.Internal.Expression (-    BinaryOp (binaryName),+    BinOpId (..),+    BinaryOp (binaryId),     Expr (..),+    builtinOf,     eqExpr,-    normalize,+    structuralKey,  ) import DataFrame.Internal.Interpreter (interpret) @@ -57,13 +58,14 @@ -- | Truth vectors keyed by structural form, read-only once built. type CondCache = M.Map T.Text (VU.Vector Bool) --- | Structural key matching the candidate-dedup key.-condCacheKey :: Expr Bool -> T.Text-condCacheKey = T.pack . show . normalize+-- | Structural key; Nothing for conditions with anonymous operators.+condCacheKey :: Expr Bool -> Maybe T.Text+condCacheKey = fmap T.pack . structuralKey  -- | Seed a cache from already-materialized candidate 'CondVec's (no interpret). condCacheFromVecs :: [CondVec] -> CondCache-condCacheFromVecs cvs = M.fromList [(condCacheKey (cvExpr cv), cvVec cv) | cv <- cvs]+condCacheFromVecs cvs =+    M.fromList [(k, cvVec cv) | cv <- cvs, Just k <- [condCacheKey (cvExpr cv)]]  -- | Add a tree's branch-condition vectors to a cache. addTreeCondsToCache :: DataFrame -> Tree a -> CondCache -> CondCache@@ -73,16 +75,16 @@     go (Branch cond l r) c = go r (go l (insertCond df cond c))  insertCond :: DataFrame -> Expr Bool -> CondCache -> CondCache-insertCond df cond c-    | M.member k c = c-    | otherwise =-        maybe c (\cv -> M.insert k (cvVec cv) c) (materializeCondVec df cond)-  where-    k = condCacheKey cond+insertCond df cond c = case condCacheKey cond of+    Nothing -> c+    Just k+        | M.member k c -> c+        | otherwise ->+            maybe c (\cv -> M.insert k (cvVec cv) c) (materializeCondVec df cond)  -- | A condition's truth vector: a cache hit, else interpret. lookupCondVec :: CondCache -> DataFrame -> Expr Bool -> Maybe (VU.Vector Bool)-lookupCondVec cache df cond = case M.lookup (condCacheKey cond) cache of+lookupCondVec cache df cond = case (`M.lookup` cache) =<< condCacheKey cond of     hit@(Just _) -> hit     Nothing -> cvVec <$> materializeCondVec df cond @@ -99,7 +101,7 @@ -- | A same-column same-direction Double threshold comparison. data ThreshCmp = ThreshCmp     { tcCol :: !T.Text-    , tcName :: !T.Text+    , tcOp :: !BinOpId     , tcThr :: !Double     , tcRebuild :: Double -> Expr Bool     }@@ -108,29 +110,31 @@ asDoubleThreshold (Binary op (Col c :: Expr cc) (Lit (t :: tt))) =     case ( testEquality (typeRep @cc) (typeRep @Double)          , testEquality (typeRep @tt) (typeRep @Double)+         , builtinOf (binaryId op)          ) of-        (Just Refl, Just Refl) -> Just (ThreshCmp c (binaryName op) t (Binary op (Col c) . Lit))+        (Just Refl, Just Refl, Just tag) ->+            Just (ThreshCmp c tag t (Binary op (Col c) . Lit))         _ -> Nothing asDoubleThreshold _ = Nothing -directionalNames :: [T.Text]-directionalNames = ["lt", "leq", "gt", "geq"]+directionalOps :: [BinOpId]+directionalOps = [BLt, BLeq, BGt, BGeq]  -- | Tighter (AND) or looser (OR) of two same-direction thresholds.-chooseThreshold :: Bool -> T.Text -> Double -> Double -> Double-chooseThreshold isAnd name t1 t2+chooseThreshold :: Bool -> BinOpId -> Double -> Double -> Double+chooseThreshold isAnd op t1 t2     | leftDir = if isAnd then min t1 t2 else max t1 t2     | otherwise = if isAnd then max t1 t2 else min t1 t2   where-    leftDir = name == "lt" || name == "leq"+    leftDir = op == BLt || op == BLeq  -- | Collapse two same-direction Double comparisons into one, if possible. consolidateThreshold :: Bool -> Expr Bool -> Expr Bool -> Maybe (Expr Bool) consolidateThreshold isAnd ea eb = do     a <- asDoubleThreshold ea     b <- asDoubleThreshold eb-    if tcCol a == tcCol b && tcName a == tcName b && tcName a `elem` directionalNames-        then Just (tcRebuild a (chooseThreshold isAnd (tcName a) (tcThr a) (tcThr b)))+    if tcCol a == tcCol b && tcOp a == tcOp b && tcOp a `elem` directionalOps+        then Just (tcRebuild a (chooseThreshold isAnd (tcOp a) (tcThr a) (tcThr b)))         else Nothing  -- | AND-combine two cached conditions, consolidating thresholds if possible.
src-internal/DataFrame/DecisionTree/Fit.hs view
@@ -44,7 +44,8 @@ import DataFrame.Internal.Expression (Expr (..)) import DataFrame.Internal.Interpreter (interpret) import DataFrame.Operations.Core (nRows)-import DataFrame.Operations.Subset (exclude, filterWhere)+import DataFrame.Operations.Subset (exclude)+import qualified DataFrame.Operations.Subset as Subset  import Control.Exception (throw) import Data.Function (on)@@ -101,7 +102,7 @@ pruneTree = pruneExpr  partitionDataFrame :: Expr Bool -> DataFrame -> (DataFrame, DataFrame)-partitionDataFrame cond df = (filterWhere cond df, filterWhere (F.not cond) df)+partitionDataFrame cond df = (Subset.filter cond df, Subset.filter (F.not cond) df)  -- | Laplace-smoothed Gini impurity of the target distribution. calculateGini ::
src-internal/DataFrame/DecisionTree/Pool.hs view
@@ -36,7 +36,7 @@     eSize,     eqExpr,     getColumns,-    normalize,+    structuralKey,  )  import Control.Parallel.Strategies (parListChunk, rdeepseq, using)@@ -157,12 +157,15 @@ admitKeys = go []   where     go acc seen [] = (reverse acc, seen)-    go acc !seen (c : cs)-        | structuralKey c `Set.member` seen = go acc seen cs-        | otherwise = go (c : acc) (Set.insert (structuralKey c) seen) cs+    go acc !seen (c : cs) = case cvKey c of+        Nothing -> go (c : acc) seen cs+        Just k+            | k `Set.member` seen -> go acc seen cs+            | otherwise -> go (c : acc) (Set.insert k seen) cs -structuralKey :: CondVec -> String-structuralKey = show . normalize . cvExpr+-- | Nothing for anonymous operators, which are never merged.+cvKey :: CondVec -> Maybe String+cvKey = structuralKey . cvExpr  -- | Admit candidates by distinct truth vector, keeping the smallest expression. admitVecs ::@@ -187,17 +190,20 @@ dedupCVByExpr = go Set.empty   where     go _ [] = []-    go seen (cv : cvs)-        | structuralKey cv `Set.member` seen = go seen cvs-        | otherwise = cv : go (Set.insert (structuralKey cv) seen) cvs+    go seen (cv : cvs) = case cvKey cv of+        Nothing -> cv : go seen cvs+        Just k+            | k `Set.member` seen -> go seen cvs+            | otherwise -> cv : go (Set.insert k seen) cvs  -- | Deduplicate expressions by normalized form, keeping the first. nubByExpr :: [Expr Bool] -> [Expr Bool] nubByExpr = go Set.empty   where+    go :: Set.Set String -> [Expr Bool] -> [Expr Bool]     go _ [] = []-    go seen (e : es)-        | k `Set.member` seen = go seen es-        | otherwise = e : go (Set.insert k seen) es-      where-        k = show (normalize e)+    go seen (e : es) = case structuralKey e of+        Nothing -> e : go seen es+        Just k+            | k `Set.member` seen -> go seen es+            | otherwise -> e : go (Set.insert k seen) es
src-internal/DataFrame/Featurize/Internal.hs view
@@ -80,7 +80,7 @@             then throw (nullableInputError name (columnTypeString c))             else                 if D.hasElemType @Double c-                    then fromRight undefined (columnAsUnboxedVector (F.col @Double name) df)+                    then fromRight undefined (columnAsUnboxedVector (F.double name) df)                     else                         throw                             ( asDoubleInputError
src/DataFrame/DBSCAN.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-}  -- | Density-based clustering (DBSCAN) with brute-force region queries.@@ -103,7 +102,7 @@ dbscanSurrogateExpr ::     TreeConfig -> [Expr Double] -> DBSCANModel -> DataFrame -> Expr Int dbscanSurrogateExpr cfg features model df =-    fitDecisionTree cfg (F.col @Int clusterCol) augmented+    fitDecisionTree cfg (F.int clusterCol) augmented   where     clusterCol = "__cluster__"     cols = map (\e -> (columnExprName e, materializeColumn df e)) features
src/DataFrame/Transform.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}  -- | Fitted column transforms as a composable monoid. module DataFrame.Transform (@@ -66,7 +65,7 @@     ScalerModel (V.fromList names) (VU.fromList means) (VU.fromList stds)   where     cols = map column names-    column n = case columnAsDoubleVector (F.col @Double n) df of+    column n = case columnAsDoubleVector (F.double n) df of         Right v -> v         Left e -> throw e     means = [VU.sum c / fromIntegral (max 1 (VU.length c)) | c <- cols]@@ -84,7 +83,7 @@ scalerTransform :: ScalerModel -> Transform scalerTransform m =     Transform-        [ (n, SomeExpr ((F.col @Double n .-. F.lit mu) ./. F.lit sigma))+        [ (n, SomeExpr ((F.double n .-. F.lit mu) ./. F.lit sigma))         | (n, mu, sigma) <-             zip3                 (V.toList (smColumns m))
tests-internal/DecisionTree.hs view
@@ -91,7 +91,7 @@  -- x <= 2.5: True for idx 0,1 (→ left); False for idx 2,3 (→ right) splitCond :: Expr Bool-splitCond = F.col @Double "x" .<= F.lit (2.5 :: Double)+splitCond = F.double "x" .<= F.lit (2.5 :: Double)  -- Pre-computed care points for the full fixture carePoints3 :: [CarePoint]@@ -216,14 +216,14 @@ countErrorsAllCorrect :: Test countErrorsAllCorrect = TestCase $ do     let cps = [CarePoint 0 GoLeft, CarePoint 1 GoRight]-        cond = F.col @Double "x" .<= F.lit (1.5 :: Double)+        cond = F.double "x" .<= F.lit (1.5 :: Double)         errs = countCarePointErrors cond fixtureDF cps     assertEqual "condition routes all care points correctly" 0 errs  countErrorsAllWrong :: Test countErrorsAllWrong = TestCase $ do     let cps = [CarePoint 0 GoLeft, CarePoint 1 GoRight]-        cond = F.col @Double "x" .> F.lit (1.5 :: Double)+        cond = F.double "x" .> F.lit (1.5 :: Double)         errs = countCarePointErrors cond fixtureDF cps     assertEqual "reversed condition misroutes all care points" 2 errs @@ -260,8 +260,8 @@ -- Candidate conditions that bracket the decision boundary sepConds :: [Expr Bool] sepConds =-    [ F.col @Double "x" .<= F.lit (10.5 :: Double)-    , F.col @Double "x" .> F.lit (10.5 :: Double)+    [ F.double "x" .<= F.lit (10.5 :: Double)+    , F.double "x" .> F.lit (10.5 :: Double)     ]  testCfg :: TreeConfig@@ -276,7 +276,7 @@ wrongStump :: Tree T.Text wrongStump =     Branch-        (F.col @Double "x" .> F.lit (10.5 :: Double))+        (F.double "x" .> F.lit (10.5 :: Double))         (Leaf "pos")         (Leaf "neg") @@ -324,7 +324,7 @@  taoDeadBranchNoCrash :: Test taoDeadBranchNoCrash = TestCase $ do-    let badCond = F.col @Double "x" .<= F.lit (0.5 :: Double)+    let badCond = F.double "x" .<= F.lit (0.5 :: Double)         indices = V.enumFromN 0 20         initTree = Branch badCond (Leaf "pos") (Leaf "neg") :: Tree T.Text         result =@@ -348,20 +348,20 @@ taoRecoversSingleObliqueDerived = TestCase $ do     let labelExpr =             F.ifThenElse-                ((F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double))+                ((F.double "x" + F.double "y") .<= F.lit (4.5 :: Double))                 (F.lit ("pos" :: T.Text))                 (F.lit ("neg" :: T.Text))         df = D.derive @T.Text "label" labelExpr gridBaseDF         indices = V.enumFromN 0 16         initTree =             Branch-                (F.col @Double "x" .<= F.lit (2.5 :: Double))+                (F.double "x" .<= F.lit (2.5 :: Double))                 (Leaf "pos")                 (Leaf "neg") ::                 Tree T.Text         conds =-            [ (F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double)-            , (F.col @Double "x" + F.col @Double "y") .> F.lit (4.5 :: Double)+            [ (F.double "x" + F.double "y") .<= F.lit (4.5 :: Double)+            , (F.double "x" + F.double "y") .> F.lit (4.5 :: Double)             ]         cfg = defaultTreeConfig{taoIterations = 5, expressionPairs = 4, minLeafSize = 1}         result = taoOptimize @T.Text cfg "label" conds df indices initTree@@ -375,10 +375,10 @@ taoRecoversNestedObliqueDerived = TestCase $ do     let labelExpr =             F.ifThenElse-                ((F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double))+                ((F.double "x" + F.double "y") .<= F.lit (4.5 :: Double))                 (F.lit ("low" :: T.Text))                 ( F.ifThenElse-                    ((F.col @Double "x" - F.col @Double "y") .<= F.lit (0.5 :: Double))+                    ((F.double "x" - F.double "y") .<= F.lit (0.5 :: Double))                     (F.lit "mid")                     (F.lit "high")                 )@@ -386,19 +386,19 @@         indices = V.enumFromN 0 16         initTree =             Branch-                (F.col @Double "x" .<= F.lit (1.5 :: Double))+                (F.double "x" .<= F.lit (1.5 :: Double))                 (Leaf "low")                 ( Branch-                    (F.col @Double "y" .<= F.lit (3.5 :: Double))+                    (F.double "y" .<= F.lit (3.5 :: Double))                     (Leaf "mid")                     (Leaf "high")                 ) ::                 Tree T.Text         conds =-            [ (F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double)-            , (F.col @Double "x" + F.col @Double "y") .> F.lit (4.5 :: Double)-            , (F.col @Double "x" - F.col @Double "y") .<= F.lit (0.5 :: Double)-            , (F.col @Double "x" - F.col @Double "y") .> F.lit (0.5 :: Double)+            [ (F.double "x" + F.double "y") .<= F.lit (4.5 :: Double)+            , (F.double "x" + F.double "y") .> F.lit (4.5 :: Double)+            , (F.double "x" - F.double "y") .<= F.lit (0.5 :: Double)+            , (F.double "x" - F.double "y") .> F.lit (0.5 :: Double)             ]         cfg = defaultTreeConfig{taoIterations = 5, expressionPairs = 4, minLeafSize = 1}         result = taoOptimize @T.Text cfg "label" conds df indices initTree@@ -413,17 +413,17 @@ obliqueAxisAlignedFixture =     let labelExpr =             F.ifThenElse-                ((F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double))+                ((F.double "x" + F.double "y") .<= F.lit (4.5 :: Double))                 (F.lit ("pos" :: T.Text))                 (F.lit ("neg" :: T.Text))         df = D.derive @T.Text "label" labelExpr gridBaseDF         indices = V.enumFromN 0 16         axisConds =-            [F.col @Double "x" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]-                ++ [F.col @Double "y" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]+            [F.double "x" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]+                ++ [F.double "y" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]         initTree =             Branch-                (F.col @Double "x" .<= F.lit (2.5 :: Double))+                (F.double "x" .<= F.lit (2.5 :: Double))                 (Leaf "pos")                 (Leaf "neg") ::                 Tree T.Text@@ -537,7 +537,7 @@                         (V.fromList [Nothing, Just (5.0 :: Double)] :: V.Vector (Maybe Double))                     )                 ]-        cond = F.fromMaybe False (F.col @(Maybe Double) "x" .<= F.lit (6.0 :: Double))+        cond = F.fromMaybe False (F.maybeDouble "x" .<= F.lit (6.0 :: Double))         (lft, rgt) = partitionIndices cond df (V.fromList [0, 1])     assertBool "null row (idx 0) routes to right (false) partition" (0 `V.elem` rgt)     assertBool "Just 5.0 <= 6.0 routes to left (true) partition" (1 `V.elem` lft)@@ -597,7 +597,7 @@         [c] ->             assertBool                 "cond is isNothing x"-                (eqExpr c (F.isNothing (F.col @(Maybe Double) "x")))+                (eqExpr c (F.isNothing (F.maybeDouble "x")))         _ -> assertFailure "expected exactly one condition"     assertBool         "no missingness conds for a non-nullable DataFrame"@@ -609,7 +609,7 @@         assertBool             "generateNumericConds contains isNothing x"             ( any-                (`eqExpr` F.isNothing (F.col @(Maybe Double) "x"))+                (`eqExpr` F.isNothing (F.maybeDouble "x"))                 (generateNumericConds defaultTreeConfig (D.exclude ["label"] nullsMixedDF))             ) @@ -620,7 +620,7 @@                 defaultTreeConfig                 (D.exclude ["label"] nullsMixedDF)                 nullsMixedDF-        isMissingCV cv = eqExpr (cvExpr cv) (F.isNothing (F.col @(Maybe Double) "x"))+        isMissingCV cv = eqExpr (cvExpr cv) (F.isNothing (F.maybeDouble "x"))         expected = VU.fromList [False, True, False, False, True, False]     case filter isMissingCV cvs of         (cv : _) -> assertEqual "isNothing vector marks null slots" expected (cvVec cv)@@ -640,7 +640,7 @@                     )                 ]         conds = generateNumericConds defaultTreeConfig{percentiles = [50]} df-        leqAt t = F.fromMaybe False (F.col @(Maybe Double) "x" .<= F.lit (t :: Double))+        leqAt t = F.fromMaybe False (F.maybeDouble "x" .<= F.lit (t :: Double))     assertBool         "median threshold from observed values (30)"         (any (`eqExpr` leqAt 30) conds)@@ -667,7 +667,7 @@     let df =             D.fromColumns                 [("s", packedFromTexts (Just [1, 3]) ["yes", "", "no", ""])]-        isMissingS = F.isNothing (F.col @(Maybe T.Text) "s")+        isMissingS = F.isNothing (F.maybeText "s")         conds = missingnessConditions df     assertEqual "one missingness cond for nullable PackedText" 1 (length conds)     case conds of@@ -834,10 +834,10 @@ taoRecoversNestedObliqueWithoutHint = TestCase $ do     let labelExpr =             F.ifThenElse-                ((F.col @Double "x" + F.col @Double "y") .<= F.lit (4.5 :: Double))+                ((F.double "x" + F.double "y") .<= F.lit (4.5 :: Double))                 (F.lit ("low" :: T.Text))                 ( F.ifThenElse-                    ((F.col @Double "x" - F.col @Double "y") .<= F.lit (0.5 :: Double))+                    ((F.double "x" - F.double "y") .<= F.lit (0.5 :: Double))                     (F.lit "mid")                     (F.lit "high")                 )@@ -845,17 +845,17 @@         indices = V.enumFromN 0 16         initTree =             Branch-                (F.col @Double "x" .<= F.lit (1.5 :: Double))+                (F.double "x" .<= F.lit (1.5 :: Double))                 (Leaf "low")                 ( Branch-                    (F.col @Double "y" .<= F.lit (3.5 :: Double))+                    (F.double "y" .<= F.lit (3.5 :: Double))                     (Leaf "mid")                     (Leaf "high")                 ) ::                 Tree T.Text         axisOnlyConds =-            [F.col @Double "x" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]-                ++ [F.col @Double "y" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]+            [F.double "x" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]+                ++ [F.double "y" .<= F.lit (t :: Double) | t <- [1.5, 2.5, 3.5]]         cfg =             defaultTreeConfig                 { taoIterations = 20@@ -1161,90 +1161,90 @@  threshAndLeq :: Test threshAndLeq = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .<=. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .<=. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .<=. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .<=. F.lit (1.0 :: Double))         r = combineAndVec a b     assertEqExpr         "AND of x≤3 and x≤1 collapses to x≤1"-        (F.col @Double "x" .<=. F.lit (1.0 :: Double))+        (F.double "x" .<=. F.lit (1.0 :: Double))         (cvExpr r)  threshOrLeq :: Test threshOrLeq = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .<=. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .<=. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .<=. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .<=. F.lit (1.0 :: Double))         r = combineOrVec a b     assertEqExpr         "OR of x≤3 and x≤1 collapses to x≤3"-        (F.col @Double "x" .<=. F.lit (3.0 :: Double))+        (F.double "x" .<=. F.lit (3.0 :: Double))         (cvExpr r)  threshAndLt :: Test threshAndLt = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .<. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .<. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .<. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .<. F.lit (1.0 :: Double))         r = combineAndVec a b     assertEqExpr         "AND of x<3 and x<1 collapses to x<1"-        (F.col @Double "x" .<. F.lit (1.0 :: Double))+        (F.double "x" .<. F.lit (1.0 :: Double))         (cvExpr r)  threshOrLt :: Test threshOrLt = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .<. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .<. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .<. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .<. F.lit (1.0 :: Double))         r = combineOrVec a b     assertEqExpr         "OR of x<3 and x<1 collapses to x<3"-        (F.col @Double "x" .<. F.lit (3.0 :: Double))+        (F.double "x" .<. F.lit (3.0 :: Double))         (cvExpr r)  threshAndGeq :: Test threshAndGeq = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>=. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>=. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>=. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .>=. F.lit (3.0 :: Double))         r = combineAndVec a b     assertEqExpr         "AND of x≥1 and x≥3 collapses to x≥3"-        (F.col @Double "x" .>=. F.lit (3.0 :: Double))+        (F.double "x" .>=. F.lit (3.0 :: Double))         (cvExpr r)  threshOrGeq :: Test threshOrGeq = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>=. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>=. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>=. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .>=. F.lit (3.0 :: Double))         r = combineOrVec a b     assertEqExpr         "OR of x≥1 and x≥3 collapses to x≥1"-        (F.col @Double "x" .>=. F.lit (1.0 :: Double))+        (F.double "x" .>=. F.lit (1.0 :: Double))         (cvExpr r)  threshAndGt :: Test threshAndGt = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .>. F.lit (3.0 :: Double))         r = combineAndVec a b     assertEqExpr         "AND of x>1 and x>3 collapses to x>3"-        (F.col @Double "x" .>. F.lit (3.0 :: Double))+        (F.double "x" .>. F.lit (3.0 :: Double))         (cvExpr r)  threshOrGt :: Test threshOrGt = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .>. F.lit (3.0 :: Double))         r = combineOrVec a b     assertEqExpr         "OR of x>1 and x>3 collapses to x>1"-        (F.col @Double "x" .>. F.lit (1.0 :: Double))+        (F.double "x" .>. F.lit (1.0 :: Double))         (cvExpr r)  -- Six negative cases: rewrite must NOT fire.  threshNegMixedDirection :: Test threshNegMixedDirection = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .<. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>=. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .<. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .>=. F.lit (1.0 :: Double))         r = combineAndVec a b     assertEqExpr         "mixed-direction AND keeps generic F.and form"@@ -1253,8 +1253,8 @@  threshNegCrossColumn :: Test threshNegCrossColumn = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "y" .>. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "y" .>. F.lit (3.0 :: Double))         r = combineAndVec a b     assertEqExpr         "cross-column AND keeps generic F.and form"@@ -1263,8 +1263,8 @@  threshNegMixedOpFamily :: Test threshNegMixedOpFamily = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .<. F.lit (4.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .<. F.lit (4.0 :: Double))         r = combineAndVec a b     assertEqExpr         "different-op-family AND keeps generic F.and form"@@ -1273,8 +1273,8 @@  threshNegEqualityOp :: Test threshNegEqualityOp = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .==. F.lit (3.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .==. F.lit (1.0 :: Double))+    let a = materializeOrFail (F.double "x" .==. F.lit (3.0 :: Double))+        b = materializeOrFail (F.double "x" .==. F.lit (1.0 :: Double))         r = combineOrVec a b     assertEqExpr         "equality OR keeps generic F.or form"@@ -1283,8 +1283,8 @@  threshNegLitOnLeft :: Test threshNegLitOnLeft = TestCase $ do-    let a = materializeOrFail (F.lit (1.0 :: Double) .<. F.col @Double "x")-        b = materializeOrFail (F.lit (3.0 :: Double) .<. F.col @Double "x")+    let a = materializeOrFail (F.lit (1.0 :: Double) .<. F.double "x")+        b = materializeOrFail (F.lit (3.0 :: Double) .<. F.double "x")         r = combineAndVec a b     assertEqExpr         "Lit-on-left AND keeps generic F.and form"@@ -1293,8 +1293,8 @@  threshNegNonLiteralRhs :: Test threshNegNonLiteralRhs = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.col @Double "y")-        b = materializeOrFail (F.col @Double "x" .>. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.double "y")+        b = materializeOrFail (F.double "x" .>. F.lit (3.0 :: Double))         r = combineAndVec a b     assertEqExpr         "non-literal RHS AND keeps generic F.and form"@@ -1304,8 +1304,8 @@ -- The consolidated cvVec equals the elementwise AND/OR of the inputs. threshSemanticPreservation :: Test threshSemanticPreservation = TestCase $ do-    let a = materializeOrFail (F.col @Double "x" .>. F.lit (1.0 :: Double))-        b = materializeOrFail (F.col @Double "x" .>. F.lit (3.0 :: Double))+    let a = materializeOrFail (F.double "x" .>. F.lit (1.0 :: Double))+        b = materializeOrFail (F.double "x" .>. F.lit (3.0 :: Double))         rAnd = combineAndVec a b         rOr = combineOrVec a b         expectedAnd = VU.zipWith (&&) (cvVec a) (cvVec b)
tests-internal/Learn/EdgeCases.hs view
@@ -175,7 +175,7 @@                 [ ("x", DI.fromList ([-3, -2, -1, -0.5, 0.5, 1, 2, 3] :: [Double]))                 , ("label", DI.fromList ([0, 0, 0, 0, 1, 1, 1, 1] :: [Int]))                 ]-        m = fit defaultLogisticConfig (F.col @Int "label") trainDf+        m = fit defaultLogisticConfig (F.int "label") trainDf         probs = logisticProbExprs m         extremeDf =             D.fromColumns@@ -196,7 +196,7 @@                 [ ("x", DI.fromList ([2] :: [Double]))                 , ("y", DI.fromList ([7] :: [Double]))                 ]-        m = fit defaultLinearConfig (F.col @Double "y") df+        m = fit defaultLinearConfig (F.double "y") df         preds = interpD df (predict m)     assertBool "single OLS prediction finite" (all finite preds)     assertBool@@ -211,7 +211,7 @@                 [ ("x", DI.fromList ([-2, -1, 0, 1, 2] :: [Double]))                 , ("label", DI.fromList ([1, 1, 1, 1, 1] :: [Int]))                 ]-        m = fit defaultLogisticConfig (F.col @Int "label") df+        m = fit defaultLogisticConfig (F.int "label") df         preds = interpI df (predict m)     assertEqual         "single-class logistic predicts that class everywhere"@@ -227,7 +227,7 @@                 , ("const", DI.fromList (replicate 8 (5.0 :: Double)))                 , ("label", DI.fromList ([0, 0, 0, 0, 1, 1, 1, 1] :: [Int]))                 ]-        m = fit defaultLogisticConfig (F.col @Int "label") df+        m = fit defaultLogisticConfig (F.int "label") df         preds = interpI df (predict m)     assertEqual         "logistic ignores constant column and separates"@@ -244,7 +244,7 @@                 , ("const", DI.fromList (replicate 6 (5.0 :: Double)))                 , ("y", DI.fromList [3 * x + 4 | x <- xs])                 ]-        m = fit defaultLinearConfig (F.col @Double "y") df+        m = fit defaultLinearConfig (F.double "y") df         coefs = VU.toList (regCoef m)         names = V.toList (regFeatureNames m)         byName = zip names coefs@@ -266,7 +266,7 @@                 , ("b", DI.fromList ([0, 5, 10] :: [Double]))                 ]         cfg = defaultKMeansConfig{kmK = 10, kmNInit = 3, kmSeed = 1}-        m = fit cfg [F.col @Double "a", F.col @Double "b"] df+        m = fit cfg [F.double "a", F.double "b"] df     assertEqual "k clamped to n=3 centres" 3 (V.length (kmCenters m))     let labels = VU.toList (kmLabels m)     assertBool "all labels in [0,2]" (all (\l -> l >= 0 && l < 3) labels)@@ -284,7 +284,7 @@                 , ("b", DI.fromList (replicate 6 (4.0 :: Double)))                 ]         cfg = defaultKMeansConfig{kmK = 2, kmNInit = 3, kmSeed = 1}-        m = fit cfg [F.col @Double "a", F.col @Double "b"] df+        m = fit cfg [F.double "a", F.double "b"] df     assertBool         "centres finite on degenerate identical data"         (all (VU.all finite) (V.toList (kmCenters m)))@@ -301,7 +301,7 @@                 , ("b", DI.fromList ([0, 10] :: [Double]))                 ]         cfg = defaultGMMConfig{gmmK = 5, gmmSeed = 1}-        m = fit cfg [F.col @Double "a", F.col @Double "b"] df+        m = fit cfg [F.double "a", F.double "b"] df     assertEqual "GMM k clamped to n=2" 2 (VU.length (gmmWeights m))     assertBool "GMM weights finite" (VU.all finite (gmmWeights m))     assertBool "GMM weights sum to ~1" (close 1e-6 (VU.sum (gmmWeights m)) 1)@@ -318,7 +318,7 @@         m =             fit                 (PCAConfig (NComp 2) False)-                [F.col @Double "x", F.col @Double "const"]+                [F.double "x", F.double "const"]                 df         ratio = VU.toList (pcaExplainedVarianceRatio m)     assertBool "explained ratios finite" (all finite ratio)@@ -343,7 +343,7 @@         m =             fit                 (PCAConfig (NComp 1) False)-                [F.col @Double "x", F.col @Double "y"]+                [F.double "x", F.double "y"]                 df         comp0 = pcaComponents m V.! 0         nrm = sqrt (VU.sum (VU.map (^ (2 :: Int)) comp0))
tests-internal/Learn/NumericalRigor.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications #-}  -- | Numerical-rigor suite: gradient checks, reproducibility, RNG properties. module Learn.NumericalRigor (tests) where@@ -206,7 +205,7 @@             kmInertia $                 fit                     defaultKMeansConfig{kmK = 2, kmNInit = 1, kmSeed = s}-                    [F.col @Double "a", F.col @Double "b"]+                    [F.double "a", F.double "b"]                     df         inertias = map fitSeed [0 .. 19]         blob1 = take 5 (zip as bs)@@ -261,7 +260,7 @@ testKMeansReproducible :: Test testKMeansReproducible = TestCase $ do     let cfg s = defaultKMeansConfig{kmK = 4, kmNInit = 1, kmMaxIter = 1, kmSeed = s}-        run s = fit (cfg s) [F.col @Double "a", F.col @Double "b"]+        run s = fit (cfg s) [F.double "a", F.double "b"]         a = run 1 spreadDF         b = run 1 spreadDF     assertEqual "k-means same seed identical model" a b@@ -274,7 +273,7 @@ testGMMReproducible :: Test testGMMReproducible = TestCase $ do     let cfg s = defaultGMMConfig{gmmK = 2, gmmMaxIter = 1, gmmSeed = s}-        run s = fit (cfg s) [F.col @Double "a", F.col @Double "b"] blobsDF+        run s = fit (cfg s) [F.double "a", F.double "b"] blobsDF         a = run 1         b = run 1     assertEqual "GMM same seed identical model" a b@@ -292,7 +291,7 @@                 , ("label", DI.fromList ([0, 0, 0, 0, 1, 1, 1, 1] :: [Int]))                 ]         cfg s = defaultRFFConfig{rffD = 40, rffGamma = 0.2, rffSeed = s}-        run s = fit (cfg s) (F.col @Int "label") clsDF+        run s = fit (cfg s) (F.int "label") clsDF         a = run 5         b = run 5     assertEqual "RFF same seed: same projection B" (rffB a) (rffB b)
tests-internal/Learn/Symbolic.hs view
@@ -47,10 +47,10 @@                     , srPopSize = 300                     , srUnaryOps = []                     }-                (F.col @Double "y")+                (F.double "y")                 df         preds = interpD df (srBest m)-        truth = interpD df (F.col @Double "y")+        truth = interpD df (F.double "y")         err = sum (zipWith (\p t -> (p - t) ^ (2 :: Int)) preds truth) / 10     assertBool "SR recovers x*x+x to low error" (err < 1e-6)     assertBool "Pareto front non-empty" (not (null (srPareto m)))@@ -66,14 +66,14 @@         run =             fit                 defaultSRConfig{srSeed = 9, srGenerations = 20}-                (F.col @Double "y")+                (F.double "y")                 df     assertEqual "SR deterministic best MSE" (srBestMSE run) (srBestMSE (rerun df))   where     rerun =         fit             defaultSRConfig{srSeed = 9, srGenerations = 20}-            (F.col @Double "y")+            (F.double "y")  testSimplifyPreservesEval :: Test testSimplifyPreservesEval = TestCase $ do@@ -100,7 +100,7 @@         m =             fit                 defaultKernelPCAConfig{kpcaNComponents = 2, kpcaNLandmarks = 8, kpcaSeed = 1}-                [F.col @Double "a", F.col @Double "b"]+                [F.double "a", F.double "b"]                 df         pc1 = case kernelPCAExprs m of             ((_, e) : _) -> interpD df e@@ -123,7 +123,7 @@         m =             fit                 defaultRFFConfig{rffD = 80, rffGamma = 0.2, rffSeed = 2}-                (F.col @Int "label")+                (F.int "label")                 df         preds = interpI df (predict m)     assertEqual "RFF SVM separates" [0, 0, 0, 0, 1, 1, 1, 1] preds
tests-internal/Properties/Simplify.hs view
@@ -61,18 +61,18 @@     t <- elements thresholds     oneof         [ elements-            [ F.col @Double "x" .< F.lit t-            , F.col @Double "x" .<= F.lit t-            , F.col @Double "x" .> F.lit t-            , F.col @Double "x" .>= F.lit t-            , F.col @Double "x" .== F.lit t-            , F.col @Double "x" ./= F.lit t+            [ F.double "x" .< F.lit t+            , F.double "x" .<= F.lit t+            , F.double "x" .> F.lit t+            , F.double "x" .>= F.lit t+            , F.double "x" .== F.lit t+            , F.double "x" ./= F.lit t             ]         , elements-            [ F.toDouble (F.col @Int "n") .< F.lit t-            , F.toDouble (F.col @Int "n") .<= F.lit t-            , F.toDouble (F.col @Int "n") .> F.lit t-            , F.toDouble (F.col @Int "n") .>= F.lit t+            [ F.toDouble (F.int "n") .< F.lit t+            , F.toDouble (F.int "n") .<= F.lit t+            , F.toDouble (F.int "n") .> F.lit t+            , F.toDouble (F.int "n") .>= F.lit t             ]         ] @@ -92,12 +92,12 @@ genAtomMaybe = do     t <- elements thresholds     elements-        [ F.col @(Maybe Double) "m" .< F.lit t-        , F.col @(Maybe Double) "m" .<= F.lit t-        , F.col @(Maybe Double) "m" .> F.lit t-        , F.col @(Maybe Double) "m" .>= F.lit t-        , F.col @(Maybe Double) "m" .== F.lit t-        , F.col @(Maybe Double) "m" ./= F.lit t+        [ F.maybeDouble "m" .< F.lit t+        , F.maybeDouble "m" .<= F.lit t+        , F.maybeDouble "m" .> F.lit t+        , F.maybeDouble "m" .>= F.lit t+        , F.maybeDouble "m" .== F.lit t+        , F.maybeDouble "m" ./= F.lit t         ]  genMaybeExpr :: Int -> Gen (Expr (Maybe Bool))
tests-internal/TreePruning.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeApplications #-}  -- | Specification for the fitted-tree pruning pass (pruneDead). module TreePruning (tests) where@@ -33,19 +32,19 @@     [ prunesTo         "ancestor entails child keeps true subtree"         ( Branch-            (F.col @Double "age" .> F.lit (50 :: Double))-            (Branch (F.col @Double "age" .> F.lit (30 :: Double)) (Leaf "a") (Leaf "b"))+            (F.double "age" .> F.lit (50 :: Double))+            (Branch (F.double "age" .> F.lit (30 :: Double)) (Leaf "a") (Leaf "b"))             (Leaf "c")         )-        (Branch (F.col @Double "age" .> F.lit (50 :: Double)) (Leaf "a") (Leaf "c"))+        (Branch (F.double "age" .> F.lit (50 :: Double)) (Leaf "a") (Leaf "c"))     , prunesTo         "ancestor refutes child keeps false subtree"         ( Branch-            (F.col @Double "age" .> F.lit (50 :: Double))-            (Branch (F.col @Double "age" .< F.lit (40 :: Double)) (Leaf "a") (Leaf "b"))+            (F.double "age" .> F.lit (50 :: Double))+            (Branch (F.double "age" .< F.lit (40 :: Double)) (Leaf "a") (Leaf "b"))             (Leaf "c")         )-        (Branch (F.col @Double "age" .> F.lit (50 :: Double)) (Leaf "b") (Leaf "c"))+        (Branch (F.double "age" .> F.lit (50 :: Double)) (Leaf "b") (Leaf "c"))     ]  falseEdgeGate :: [Test]@@ -53,16 +52,16 @@     [ prunesTo         "integral false edge entails child"         ( Branch-            (F.toDouble (F.col @Int "ai") .> F.lit (50 :: Double))+            (F.toDouble (F.int "ai") .> F.lit (50 :: Double))             (Leaf "c")             ( Branch-                (F.toDouble (F.col @Int "ai") .< F.lit (60 :: Double))+                (F.toDouble (F.int "ai") .< F.lit (60 :: Double))                 (Leaf "a")                 (Leaf "b")             )         )         ( Branch-            (F.toDouble (F.col @Int "ai") .> F.lit (50 :: Double))+            (F.toDouble (F.int "ai") .> F.lit (50 :: Double))             (Leaf "c")             (Leaf "a")         )@@ -72,13 +71,13 @@ sameBranchCollapse =     [ prunesTo         "equal leaves collapse the branch"-        (Branch (F.col @Double "age" .> F.lit (50 :: Double)) (Leaf "a") (Leaf "a"))+        (Branch (F.double "age" .> F.lit (50 :: Double)) (Leaf "a") (Leaf "a"))         (Leaf "a")     , prunesTo         "collapse cascades upward"         ( Branch-            (F.col @Double "age" .> F.lit (50 :: Double))-            (Branch (F.col @Double "hours" .> F.lit (40 :: Double)) (Leaf "a") (Leaf "a"))+            (F.double "age" .> F.lit (50 :: Double))+            (Branch (F.double "hours" .> F.lit (40 :: Double)) (Leaf "a") (Leaf "a"))             (Leaf "a")         )         (Leaf "a")@@ -89,22 +88,22 @@     [ preserved         "child not tight enough is kept"         ( Branch-            (F.col @Double "age" .> F.lit (50 :: Double))-            (Branch (F.col @Double "age" .> F.lit (60 :: Double)) (Leaf "a") (Leaf "b"))+            (F.double "age" .> F.lit (50 :: Double))+            (Branch (F.double "age" .> F.lit (60 :: Double)) (Leaf "a") (Leaf "b"))             (Leaf "c")         )     , preserved         "double false edge is kept (NaN)"         ( Branch-            (F.col @Double "weight" .> F.lit (50 :: Double))+            (F.double "weight" .> F.lit (50 :: Double))             (Leaf "c")-            (Branch (F.col @Double "weight" .< F.lit (60 :: Double)) (Leaf "a") (Leaf "b"))+            (Branch (F.double "weight" .< F.lit (60 :: Double)) (Leaf "a") (Leaf "b"))         )     , preserved         "cross-column descendant is kept"         ( Branch-            (F.col @Double "age" .> F.lit (50 :: Double))-            (Branch (F.col @Double "income" .> F.lit (30000 :: Double)) (Leaf "a") (Leaf "b"))+            (F.double "age" .> F.lit (50 :: Double))+            (Branch (F.double "income" .> F.lit (30000 :: Double)) (Leaf "a") (Leaf "b"))             (Leaf "c")         )     ]
tests-internal/Worklist.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeApplications #-}  -- | Spec for the saturateCandidates worklist against the boolExprsVec oracle. module Worklist (tests, props) where@@ -51,16 +50,16 @@         (materializeCondVec fixtureDF e)  xGt, xLt, yGt, yLt, zGt, zLt :: Double -> CondVec-xGt n = mat (F.col @Double "x" .>. F.lit n)-xLt n = mat (F.col @Double "x" .<. F.lit n)-yGt n = mat (F.col @Double "y" .>. F.lit n)-yLt n = mat (F.col @Double "y" .<. F.lit n)-zGt n = mat (F.col @Double "z" .>. F.lit n)-zLt n = mat (F.col @Double "z" .<. F.lit n)+xGt n = mat (F.double "x" .>. F.lit n)+xLt n = mat (F.double "x" .<. F.lit n)+yGt n = mat (F.double "y" .>. F.lit n)+yLt n = mat (F.double "y" .<. F.lit n)+zGt n = mat (F.double "z" .>. F.lit n)+zLt n = mat (F.double "z" .<. F.lit n)  -- Same truth vector as 'xGt 2' but eSize 4 vs 3: a non-degenerate collision. notLe2 :: CondVec-notLe2 = mat (F.not (F.col @Double "x" .<=. F.lit 2))+notLe2 = mat (F.not (F.double "x" .<=. F.lit 2))  litTrue :: CondVec litTrue = mat (F.lit True)@@ -113,9 +112,9 @@  wideBase :: [CondVec] wideBase =-    [ matW (F.col @Double "a" .>. F.lit 3)-    , matW (F.col @Double "b" .<. F.lit 5)-    , matW (F.col @Double "c" .>=. F.lit 3)+    [ matW (F.double "a" .>. F.lit 3)+    , matW (F.double "b" .<. F.lit 5)+    , matW (F.double "c" .>=. F.lit 3)     ]  tests :: [Test]