Skip to content

Commit

Permalink
the blog post is done mostly?
Browse files Browse the repository at this point in the history
  • Loading branch information
mstksg committed Jul 26, 2024
1 parent 94a0366 commit 532ebcd
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 103 deletions.
37 changes: 19 additions & 18 deletions code-samples/kmeans/kmeans.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import Control.Monad.ST
import Data.Finite
import Data.Foldable
import Data.Foldable.WithIndex
import Data.List (sortOn)
import Data.Map (Map)
import qualified Data.Map as M
import Data.Set (Set)
import qualified Data.Set as S
import Data.Traversable
import Data.Type.Equality
import qualified Data.Vector.Mutable.Sized as MV
import Data.Vector.Sized (Vector)
Expand All @@ -38,7 +37,9 @@ initialClusters pts = runST do
let i' = modulo (fromIntegral i)
MV.modify sums (^+^ p) i'
MV.modify counts (+ 1) i'
liftA2 (^/) <$> V.freeze sums <*> (fmap fromInteger <$> V.freeze counts)
sums_ <- V.freeze sums
counts_ <- V.freeze counts
pure $ (^/) <$> sums_ <*> counts_

moveClusters ::
forall k p a.
Expand All @@ -50,7 +51,7 @@ moveClusters pts cs0 = runST do
sums <- MV.replicate zero
counts <- MV.replicate 0
for_ pts \p -> do
let closestIx = V.minIndex @_ @(k - 1) (distance p <$> cs0)
let closestIx = V.minIndex @a @(k - 1) (distance p <$> cs0)
MV.modify sums (^+^ p) closestIx
MV.modify counts (+ 1) closestIx
sums_ <- V.freeze sums
Expand Down Expand Up @@ -98,21 +99,25 @@ groupAndSum pts cs0 = runST do
let closestIx = V.minIndex (distance p <$> cs0)
MV.modify sums (^+^ p) closestIx
MV.modify counts (+ 1) closestIx
liftA2 (,) <$> V.freeze sums <*> V.freeze counts
sums_ <- V.freeze sums
counts_ <- V.freeze counts
pure $ (,) <$> sums_ <*> counts_

applyClusters ::
(Metric p, Floating a, Ord a, Ord (p a), KnownNat (k + 1)) =>
forall k p a.
(Metric p, Floating a, Ord a, Ord (p a), KnownNat k, 1 <= k) =>
[p a] ->
Vector (k + 1) (p a) ->
Vector (k + 1) (Set (p a))
applyClusters pts cs = V.generate \i -> M.findWithDefault S.empty i mp
Vector k (p a) ->
Vector k (Set (p a))
applyClusters pts cs = V.generate \i -> M.findWithDefault S.empty i pointsClosestTo
where
mp =
pointsClosestTo :: Map (Finite k) (Set (p a))
pointsClosestTo =
M.fromListWith
(<>)
[ (closestIx, S.singleton p)
| p <- pts
, let closestIx = V.minIndex (distance p <$> cs)
, let closestIx = V.minIndex @a @(k - 1) (distance p <$> cs)
]

generateSamples ::
Expand All @@ -125,16 +130,12 @@ generateSamples ::
g ->
m ([p Double], [p Double])
generateSamples npts k g = do
(centers, ptsWithSortKey) <-
unzip <$> replicateM k do
(centers, ptss) <- unzip <$> replicateM k do
center <- sequenceA $ pure @p $ MWC.uniformRM (0, boxSize) g
pts <- replicateM npts do
ptSortKey <- uniformWord16 g
pt <- for center \c -> MWC.normal c 0.1 g
pure (ptSortKey, pt)
traverse (\c -> MWC.normal c 0.1 g) center
pure (center, pts)
let shuffledPoints = snd <$> sortOn fst (concat ptsWithSortKey)
pure (centers, shuffledPoints)
pure (centers, concat ptss)
where
dim = length $ pure @p ()
boxSize = (fromIntegral k ** recip (fromIntegral dim)) * 20
Expand Down
14 changes: 10 additions & 4 deletions config/patrons.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ let mkPatron =
{ name, info = { twitter, level } }

in [ mkPatron "Josh Vera" (None Text) Level.Amazing
, mkPatron "Austin Huang" (None Text) Level.Support
, mkPatron "Jon" (None Text) Level.Support
, mkPatron "Josh Miller" (None Text) Level.Support
, mkPatron "Chris Penner" (Some "opticsbyexample") Level.Support
, mkPatron "Jan Hrček" (None Text) Level.Support
, mkPatron "Sam Raker" (None Text) Level.Support
, mkPatron "Julie Moronuki" (None Text) Level.Support
, mkPatron "Andrew Handley-Marsh" (None Text) Level.Support
, mkPatron "Domen Kožar" (None Text) Level.Support
, mkPatron "Fintan Halpenny" (None Text) Level.Support
, mkPatron "Shae Erisson" (None Text) Level.Support
, mkPatron "Amir Saeid" (Some "gluegadget") Level.Support
, mkPatron "Julie Moronuki" (None Text) Level.Support
, mkPatron "Sam Stites" (None Text) Level.Support
, mkPatron "Chris Penner" (Some "opticsbyexample") Level.Inactive
, mkPatron "Jan Hrček" (None Text) Level.Inactive
, mkPatron "Sam Raker" (None Text) Level.Inactive
]
Loading

0 comments on commit 532ebcd

Please sign in to comment.