Data.Bit.ThreadSafe

bitvec-1.1.5.0: Space-efficient bit vectors

Copyright | (c) 2019-2022 Andrew Lelechenko 2012-2016 James Cook
License | BSD3
Maintainer | Andrew Lelechenko <andrew.lelechenko@gmail.com>
Safe Haskell | None
Language | Haskell2010

Data.Bit.ThreadSafe

Contents

- Immutable conversions
- Immutable operations
- Mutable conversions
- Mutable operations
- Binary polynomials

Description

This module exposes an interface with thread-safe writes and flips. Additionally, concurrently modifying non-intersecting slices of the same underlying array works as expected. However, operations that affect multiple elements are not guaranteed to be atomic. Consider using Data.Bit, which is faster (usually 10-20%, up to 50% for short vectors), but not thread-safe.

Since: 1.0

Synopsis

- newtype Bit = Bit {
  - unBit :: Bool
  }
- unsafeFlipBit :: PrimMonad m => MVector (PrimState m) Bit -> Int -> m ()
- flipBit :: PrimMonad m => MVector (PrimState m) Bit -> Int -> m ()
- castFromWords :: Vector Word -> Vector Bit
- castToWords :: Vector Bit -> Maybe (Vector Word)
- cloneToWords :: Vector Bit -> Vector Word
- castFromWords8 :: Vector Word8 -> Vector Bit
- castToWords8 :: Vector Bit -> Maybe (Vector Word8)
- cloneToWords8 :: Vector Bit -> Vector Word8
- cloneFromByteString :: ByteString -> Vector Bit
- cloneToByteString :: Vector Bit -> ByteString
- zipBits :: (forall a. Bits a => a -> a -> a) -> Vector Bit -> Vector Bit -> Vector Bit
- mapBits :: (forall a. Bits a => a -> a) -> Vector Bit -> Vector Bit
- invertBits :: Vector Bit -> Vector Bit
- reverseBits :: Vector Bit -> Vector Bit
- bitIndex :: Bit -> Vector Bit -> Maybe Int
- nthBitIndex :: Bit -> Int -> Vector Bit -> Maybe Int
- countBits :: Vector Bit -> Int
- listBits :: Vector Bit -> [Int]
- selectBits :: Vector Bit -> Vector Bit -> Vector Bit
- excludeBits :: Vector Bit -> Vector Bit -> Vector Bit
- castFromWordsM :: MVector s Word -> MVector s Bit
- castToWordsM :: MVector s Bit -> Maybe (MVector s Word)
- cloneToWordsM :: PrimMonad m => MVector (PrimState m) Bit -> m (MVector (PrimState m) Word)
- zipInPlace :: PrimMonad m => (forall a. Bits a => a -> a -> a) -> Vector Bit -> MVector (PrimState m) Bit -> m ()
- mapInPlace :: PrimMonad m => (forall a. Bits a => a -> a) -> MVector (PrimState m) Bit -> m ()
- invertInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m ()
- reverseInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m ()
- selectBitsInPlace :: PrimMonad m => Vector Bit -> MVector (PrimState m) Bit -> m Int
- excludeBitsInPlace :: PrimMonad m => Vector Bit -> MVector (PrimState m) Bit -> m Int
- data F2Poly
- unF2Poly :: F2Poly -> Vector Bit
- toF2Poly :: Vector Bit -> F2Poly
- gcdExt :: F2Poly -> F2Poly -> (F2Poly, F2Poly)

# Documentation

newtype Bit #

A newtype wrapper with a custom instance for Data.Vector.Unboxed, which packs booleans as efficient as possible (8 values per byte). Unboxed vectors of `Bit` use 8x less memory than unboxed vectors of `Bool` (which store one value per byte), but random writes are slightly slower.

Since: 1.0.0.0

Constructors

Bit |
Fields unBit :: Bool Since: 0.2.0.0

#### Instances

Instances details

NFData Bit # | Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS Methods rnf :: Bit -> () #
Bits Bit # |
Instance details Defined in Data.Bit.InternalTS Methods (.&.) :: Bit -> Bit -> Bit # (.|.) :: Bit -> Bit -> Bit # xor :: Bit -> Bit -> Bit # complement :: Bit -> Bit # shift :: Bit -> Int -> Bit # rotate :: Bit -> Int -> Bit # zeroBits :: Bit # bit :: Int -> Bit # setBit :: Bit -> Int -> Bit # clearBit :: Bit -> Int -> Bit # complementBit :: Bit -> Int -> Bit # testBit :: Bit -> Int -> Bool # bitSizeMaybe :: Bit -> Maybe Int # bitSize :: Bit -> Int # isSigned :: Bit -> Bool # shiftL :: Bit -> Int -> Bit # unsafeShiftL :: Bit -> Int -> Bit # shiftR :: Bit -> Int -> Bit # unsafeShiftR :: Bit -> Int -> Bit # rotateL :: Bit -> Int -> Bit # rotateR :: Bit -> Int -> Bit # popCount :: Bit -> Int #
FiniteBits Bit # | Since: 0.2.0.0
Instance details Defined in Data.Bit.InternalTS Methods finiteBitSize :: Bit -> Int # countLeadingZeros :: Bit -> Int # countTrailingZeros :: Bit -> Int #
Bounded Bit # |
Instance details Defined in Data.Bit.InternalTS Methods minBound :: Bit # maxBound :: Bit #
Enum Bit # |
Instance details Defined in Data.Bit.InternalTS Methods succ :: Bit -> Bit # pred :: Bit -> Bit # toEnum :: Int -> Bit # fromEnum :: Bit -> Int # enumFrom :: Bit -> [Bit] # enumFromThen :: Bit -> Bit -> [Bit] # enumFromTo :: Bit -> Bit -> [Bit] # enumFromThenTo :: Bit -> Bit -> Bit -> [Bit] #
Generic Bit # |
Instance details Defined in Data.Bit.InternalTS Associated Types
type Rep Bit | Since: bitvec-1.0.1.0
Instance details Defined in Data.Bit.InternalTS type Rep Bit = D1 ('MetaData "Bit" "Data.Bit.InternalTS" "bitvec-1.1.5.0-1WuodrWNWFINz6k1rLZGF" 'True) (C1 ('MetaCons "Bit" 'PrefixI 'True) (S1 ('MetaSel ('Just "unBit") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool)))
Methods from :: Bit -> Rep Bit x # to :: Rep Bit x -> Bit #
Num Bit # | There is only one lawful `Num` instance possible with `+` = `xor` and `fromInteger` = `Bit` . `odd`. Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS Methods (+) :: Bit -> Bit -> Bit # (-) :: Bit -> Bit -> Bit # (*) :: Bit -> Bit -> Bit # negate :: Bit -> Bit # abs :: Bit -> Bit # signum :: Bit -> Bit # fromInteger :: Integer -> Bit #
Read Bit # |
Instance details Defined in Data.Bit.InternalTS Methods readsPrec :: Int -> ReadS Bit # readList :: ReadS [Bit] # readPrec :: ReadPrec Bit # readListPrec :: ReadPrec [Bit] #
Fractional Bit # | Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS Methods (/) :: Bit -> Bit -> Bit # recip :: Bit -> Bit # fromRational :: Rational -> Bit #
Integral Bit # | Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS Methods quot :: Bit -> Bit -> Bit # rem :: Bit -> Bit -> Bit # div :: Bit -> Bit -> Bit # mod :: Bit -> Bit -> Bit # quotRem :: Bit -> Bit -> (Bit, Bit) # divMod :: Bit -> Bit -> (Bit, Bit) # toInteger :: Bit -> Integer #
Real Bit # | Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS Methods toRational :: Bit -> Rational #
Show Bit # |
Instance details Defined in Data.Bit.InternalTS Methods showsPrec :: Int -> Bit -> ShowS # show :: Bit -> String # showList :: [Bit] -> ShowS #
Eq Bit # |
Instance details Defined in Data.Bit.InternalTS Methods (==) :: Bit -> Bit -> Bool # (/=) :: Bit -> Bit -> Bool #
Ord Bit # |
Instance details Defined in Data.Bit.InternalTS Methods compare :: Bit -> Bit -> Ordering # (<) :: Bit -> Bit -> Bool # (<=) :: Bit -> Bit -> Bool # (>) :: Bit -> Bit -> Bool # (>=) :: Bit -> Bit -> Bool # max :: Bit -> Bit -> Bit # min :: Bit -> Bit -> Bit #
Unbox Bit # |
Instance details Defined in Data.Bit.InternalTS
Vector Vector Bit # |
Instance details Defined in Data.Bit.InternalTS Methods basicUnsafeFreeze :: Mutable Vector s Bit -> ST s (Vector Bit) basicUnsafeThaw :: Vector Bit -> ST s (Mutable Vector s Bit) basicLength :: Vector Bit -> Int basicUnsafeSlice :: Int -> Int -> Vector Bit -> Vector Bit basicUnsafeIndexM :: Vector Bit -> Int -> Box Bit basicUnsafeCopy :: Mutable Vector s Bit -> Vector Bit -> ST s () elemseq :: Vector Bit -> Bit -> b -> b
MVector MVector Bit # |
Instance details Defined in Data.Bit.InternalTS Methods basicLength :: MVector s Bit -> Int basicUnsafeSlice :: Int -> Int -> MVector s Bit -> MVector s Bit basicOverlaps :: MVector s Bit -> MVector s Bit -> Bool basicUnsafeNew :: Int -> ST s (MVector s Bit) basicInitialize :: MVector s Bit -> ST s () basicUnsafeReplicate :: Int -> Bit -> ST s (MVector s Bit) basicUnsafeRead :: MVector s Bit -> Int -> ST s Bit basicUnsafeWrite :: MVector s Bit -> Int -> Bit -> ST s () basicClear :: MVector s Bit -> ST s () basicSet :: MVector s Bit -> Bit -> ST s () basicUnsafeCopy :: MVector s Bit -> MVector s Bit -> ST s () basicUnsafeMove :: MVector s Bit -> MVector s Bit -> ST s () basicUnsafeGrow :: MVector s Bit -> Int -> ST s (MVector s Bit)
Bits (Vector Bit) # | Note: For `(.&.)`, `(.|.)` and `xor`, if one input is larger than the other, the remaining bits will be ignored. `bitSize` is undefined (throws an exception).
Instance details Defined in Data.Bit.ImmutableTS Methods (.&.) :: Vector Bit -> Vector Bit -> Vector Bit # (.|.) :: Vector Bit -> Vector Bit -> Vector Bit # xor :: Vector Bit -> Vector Bit -> Vector Bit # complement :: Vector Bit -> Vector Bit # shift :: Vector Bit -> Int -> Vector Bit # rotate :: Vector Bit -> Int -> Vector Bit # zeroBits :: Vector Bit # bit :: Int -> Vector Bit # setBit :: Vector Bit -> Int -> Vector Bit # clearBit :: Vector Bit -> Int -> Vector Bit # complementBit :: Vector Bit -> Int -> Vector Bit # testBit :: Vector Bit -> Int -> Bool # bitSizeMaybe :: Vector Bit -> Maybe Int # bitSize :: Vector Bit -> Int # isSigned :: Vector Bit -> Bool # shiftL :: Vector Bit -> Int -> Vector Bit # unsafeShiftL :: Vector Bit -> Int -> Vector Bit # shiftR :: Vector Bit -> Int -> Vector Bit # unsafeShiftR :: Vector Bit -> Int -> Vector Bit # rotateL :: Vector Bit -> Int -> Vector Bit # rotateR :: Vector Bit -> Int -> Vector Bit # popCount :: Vector Bit -> Int #
type Rep Bit # | Since: 1.0.1.0
Instance details Defined in Data.Bit.InternalTS type Rep Bit = D1 ('MetaData "Bit" "Data.Bit.InternalTS" "bitvec-1.1.5.0-1WuodrWNWFINz6k1rLZGF" 'True) (C1 ('MetaCons "Bit" 'PrefixI 'True) (S1 ('MetaSel ('Just "unBit") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool)))
data Vector Bit # |
Instance details Defined in Data.Bit.InternalTS data Vector Bit = BitVec !Int !Int !ByteArray
data MVector s Bit # |
Instance details Defined in Data.Bit.InternalTS data MVector s Bit = BitMVec !Int !Int !(MutableByteArray s)

unsafeFlipBit :: PrimMonad m => MVector (PrimState m) Bit -> Int -> m () #

Flip the bit at the given position. No bound checks are performed. Equivalent to `flip` `unsafeModify` `complement`, but up to 33% faster and atomic.

In general there is no reason to `unsafeModify` bit vectors: either you modify it with `id` (which is `id` altogether) or with `complement` (which is `unsafeFlipBit`).

    >>> Data.Vector.Unboxed.modify (\v -> unsafeFlipBit v 1) (read "[1,1,1]")
    [1,0,1]

flipBit :: PrimMonad m => MVector (PrimState m) Bit -> Int -> m () #

Flip the bit at the given position. Equivalent to `flip` `modify` `complement`, but up to 33% faster and atomic.

In general there is no reason to `modify` bit vectors: either you modify it with `id` (which is `id` altogether) or with `complement` (which is `flipBit`).

    >>> Data.Vector.Unboxed.modify (\v -> flipBit v 1) (read "[1,1,1]")
    [1,0,1]

# Immutable conversions

castFromWords :: Vector Word -> Vector Bit #

Cast an unboxed vector of words to an unboxed vector of bits. Cf. `castFromWordsM`.

    >>> :set -XOverloadedLists
    >>> castFromWords [123]
    [1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Since: 1.0.0.0

castToWords :: Vector Bit -> Maybe (Vector Word) #

Try to cast an unboxed vector of bits to an unboxed vector of words. It succeeds if the vector of bits is aligned. Use `cloneToWords` otherwise. Cf. `castToWordsM`.

    castToWords (castFromWords v) == Just v

Since: 1.0.0.0

cloneToWords :: Vector Bit -> Vector Word #

Clone an unboxed vector of bits to a new unboxed vector of words. If the bits don't completely fill the words, the last word will be zero-padded. Cf. `cloneToWordsM`.

    >>> :set -XOverloadedLists
    >>> cloneToWords [1,1,0,1,1,1,1]
    [123]

Since: 1.0.0.0

castFromWords8 :: Vector Word8 -> Vector Bit #

Cast an unboxed vector of `Word8` to an unboxed vector of bits.

On big-endian architectures `castFromWords8` resorts to copying instead of aliasing the underlying array.

    >>> :set -XOverloadedLists
    >>> castFromWords8 [123]
    [1,1,0,1,1,1,1,0]

Since: 1.0.3.0

castToWords8 :: Vector Bit -> Maybe (Vector Word8) #

Try to cast an unboxed vector of bits to an unboxed vector of `Word8`. It succeeds if the vector of bits is aligned. Use `cloneToWords8` otherwise.

    castToWords8 (castFromWords8 v) == Just v

Since: 1.0.3.0

cloneToWords8 :: Vector Bit -> Vector Word8 #

Clone an unboxed vector of bits to a new unboxed vector of `Word8`. If the bits don't completely fill the bytes, the last `Word8` will be zero-padded.

    >>> :set -XOverloadedLists
    >>> cloneToWords8 [1,1,0,1,1,1,1]
    [123]

Since: 1.0.3.0

cloneFromByteString :: ByteString -> Vector Bit #

Clone a `ByteString` to a new unboxed vector of bits.

    >>> :set -XOverloadedStrings
    >>> cloneFromByteString "abc"
    [1,0,0,0,0,1,1,0,0,1,0,0,0,1,1,0,1,1,0,0,0,1,1,0]

Since: 1.1.0.0

cloneToByteString :: Vector Bit -> ByteString #

Clone an unboxed vector of bits to a new `ByteString`. If the bits don't completely fill the bytes, the last character will be zero-padded.

    >>> :set -XOverloadedLists
    >>> cloneToByteString [1,0,0,0,0,1,1,0,0,1,0,0,0,1,1,0,1,1,0,0,0,1]
    "ab#"

Since: 1.1.0.0

# Immutable operations

zipBits :: (forall a. Bits a => a -> a -> a) -> Vector Bit -> Vector Bit -> Vector Bit #

Zip two vectors with the given function. Similar to `zipWith`, but up to 3500x (!) faster.

Note: If one input is larger than the other, the remaining bits will be ignored.

For sufficiently dense sets, represented as bitmaps, `zipBits` is up to 64x faster than `union`, `intersection`, etc.

The function passed to zipBits may only use the following `Bits` methods:

`.&.`, `.|.`, `xor`, `complement`, `zeroBits`, and (likely uselessly) `bitSizeMaybe` and `isSigned`.

    >>> :set -XOverloadedLists
    >>> import Data.Bits
    >>> zipBits (.&.) [1,1,0] [0,1,1] -- intersection
    [0,1,0]
    >>> zipBits (.|.) [1,1,0] [0,1,1] -- union
    [1,1,1]
    >>> zipBits (\x y -> x .&. complement y) [1,1,0] [0,1,1] -- difference
    [1,0,0]
    >>> zipBits xor [1,1,0] [0,1,1] -- symmetric difference
    [1,0,1]

Since: 1.0.0.0

mapBits :: (forall a. Bits a => a -> a) -> Vector Bit -> Vector Bit #

Map a vectors with the given function. Similar to `map`, but faster.

    >>> :set -XOverloadedLists
    >>> import Data.Bits
    >>> mapBits complement [0,1,1]
    [1,0,0]

Since: 1.1.0.0

invertBits :: Vector Bit -> Vector Bit #

Invert (flip) all bits.

    >>> :set -XOverloadedLists
    >>> invertBits [0,1,0,1,0]
    [1,0,1,0,1]

Since: 1.0.1.0

reverseBits :: Vector Bit -> Vector Bit #

Reverse the order of bits.

    >>> :set -XOverloadedLists
    >>> reverseBits [1,1,0,1,0]
    [0,1,0,1,1]

Consider using the vector-rotcev package to reverse vectors in O(1) time.

Since: 1.0.1.0

bitIndex :: Bit -> Vector Bit -> Maybe Int #

Return the index of the first bit in the vector with the specified value, if any. Similar to `elemIndex`, but up to 64x faster.

    >>> :set -XOverloadedLists
    >>> bitIndex 1 [0,0,1,0,1]
    Just 2
    >>> bitIndex 1 [0,0,0,0,0]
    Nothing

    bitIndex bit == nthBitIndex bit 1

One can also use it to reduce a vector with disjunction or conjunction:

    import Data.Maybe
    isAnyBitSet   = isJust    . bitIndex 1
    areAllBitsSet = isNothing . bitIndex 0

Since: 1.0.0.0

nthBitIndex :: Bit -> Int -> Vector Bit -> Maybe Int #

Return the index of the `n`-th bit in the vector with the specified value, if any. Here `n` is 1-based and the index is 0-based. Non-positive `n` results in an error.

    >>> :set -XOverloadedLists
    >>> nthBitIndex 1 2 [0,1,0,1,1,1,0] -- 2nd occurence of 1
    Just 3
    >>> nthBitIndex 1 5 [0,1,0,1,1,1,0] -- 5th occurence of 1
    Nothing

One can use `nthBitIndex` to implement to implement `select{0,1}` queries for succinct dictionaries.

Since: 1.0.0.0

countBits :: Vector Bit -> Int #

Return the number of set bits in a vector (population count, popcount).

    >>> :set -XOverloadedLists
    >>> countBits [1,1,0,1,0,1]
    4

One can combine `countBits` with `take` to implement `rank{0,1}` queries for succinct dictionaries.

Since: 0.1

listBits :: Vector Bit -> [Int] #

Return 0-based indices of set bits in a vector.

    >>> :set -XOverloadedLists
    >>> listBits [1,1,0,1,0,1]
    [0,1,3,5]

Since: 0.1

selectBits :: Vector Bit -> Vector Bit -> Vector Bit #

For each set bit of the first argument, extract the corresponding bit of the second argument to the result. Similar to the parallel bit extract instruction (PEXT).

Note: If one input is larger than the other, the remaining bits will be ignored.

    >>> :set -XOverloadedLists
    >>> selectBits [0,1,0,1,1] [1,1,0,0,1]
    [1,0,1]

Here is a reference (but slow) implementation:

    import qualified Data.Vector.Unboxed as U
    selectBits mask ws = U.map snd (U.filter (unBit . fst) (U.zip mask ws))

Since: 0.1

excludeBits :: Vector Bit -> Vector Bit -> Vector Bit #

For each unset bit of the first argument, extract the corresponding bit of the second argument to the result.

Note: If one input is larger than the other, the remaining bits will be ignored.

    >>> :set -XOverloadedLists
    >>> excludeBits [0,1,0,1,1] [1,1,0,0,1]
    [1,0]

Here is a reference (but slow) implementation:

    import qualified Data.Vector.Unboxed as U
    excludeBits mask ws = U.map snd (U.filter (not . unBit . fst) (U.zip mask ws))

Since: 0.1

# Mutable conversions

castFromWordsM :: MVector s Word -> MVector s Bit #

Cast a vector of words to a vector of bits. Cf. `castFromWords`.

Since: 1.0.0.0

castToWordsM :: MVector s Bit -> Maybe (MVector s Word) #

Try to cast a vector of bits to a vector of words. It succeeds if the vector of bits is aligned. Use `cloneToWordsM` otherwise. Cf. `castToWords`.

Since: 1.0.0.0

cloneToWordsM :: PrimMonad m => MVector (PrimState m) Bit -> m (MVector (PrimState m) Word) #

Clone a vector of bits to a new unboxed vector of words. If the bits don't completely fill the words, the last word will be zero-padded. Cf. `cloneToWords`.

Since: 1.0.0.0

# Mutable operations

zipInPlace :: PrimMonad m => (forall a. Bits a => a -> a -> a) -> Vector Bit -> MVector (PrimState m) Bit -> m () #

Zip two vectors with the given function, rewriting the contents of the second argument. Cf. `zipBits`.

Note: If one input is larger than the other, the remaining bits will be ignored.

    >>> :set -XOverloadedLists
    >>> import Data.Bits
    >>> Data.Vector.Unboxed.modify (zipInPlace (.&.) [1,1,0]) [0,1,1]
    [0,1,0]

Warning: if the immutable vector is shorter than the mutable one, it is the caller's responsibility to trim the result:

    >>> :set -XOverloadedLists
    >>> import Data.Bits
    >>> Data.Vector.Unboxed.modify (zipInPlace (.&.) [1,1,0]) [0,1,1,1,1,1]
    [0,1,0,1,1,1] -- note trailing garbage

Since: 1.0.0.0

mapInPlace :: PrimMonad m => (forall a. Bits a => a -> a) -> MVector (PrimState m) Bit -> m () #

Apply a function to a mutable vector bitwise, rewriting its contents. Cf. `mapBits`.

    >>> :set -XOverloadedLists
    >>> import Data.Bits
    >>> Data.Vector.Unboxed.modify (mapInPlace complement) [0,1,1]
    [1,0,0]

Since: 1.1.0.0

invertInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m () #

Invert (flip) all bits in-place.

    >>> :set -XOverloadedLists
    >>> Data.Vector.Unboxed.modify invertInPlace [0,1,0,1,0]
    [1,0,1,0,1]

Since: 0.1

reverseInPlace :: PrimMonad m => MVector (PrimState m) Bit -> m () #

Reverse the order of bits in-place.

    >>> :set -XOverloadedLists
    >>> Data.Vector.Unboxed.modify reverseInPlace [1,1,0,1,0]
    [0,1,0,1,1]

Consider using the vector-rotcev package to reverse vectors in O(1) time.

Since: 0.1

selectBitsInPlace :: PrimMonad m => Vector Bit -> MVector (PrimState m) Bit -> m Int #

Same as `selectBits`, but extract selected bits in-place. Returns the number of selected bits. It is the caller's responsibility to trim the result to this number.

Note: If one input is larger than the other, the remaining bits will be ignored.

    >>> :set -XOverloadedLists
    >>> import Control.Monad.ST (runST)
    >>> import qualified Data.Vector.Unboxed as U
    >>> runST $ do { vec <- U.unsafeThaw [1,1,0,0,1]; n <- selectBitsInPlace [0,1,0,1,1] vec; U.take n <$> U.unsafeFreeze vec }
    [1,0,1]

Since: 0.1

excludeBitsInPlace :: PrimMonad m => Vector Bit -> MVector (PrimState m) Bit -> m Int #

Same as `excludeBits`, but extract excluded bits in-place. Returns the number of excluded bits. It is the caller's responsibility to trim the result to this number.

Note: If one input is larger than the other, the remaining bits will be ignored.

    >>> :set -XOverloadedLists
    >>> import Control.Monad.ST (runST)
    >>> import qualified Data.Vector.Unboxed as U
    >>> runST $ do { vec <- U.unsafeThaw [1,1,0,0,1]; n <- excludeBitsInPlace [0,1,0,1,1] vec; U.take n <$> U.unsafeFreeze vec }
    [1,0]

Since: 0.1

# Binary polynomials

data F2Poly #

Binary polynomials of one variable, backed by an unboxed `Vector` `Bit`.

Polynomials are stored normalized, without leading zero coefficients.

The `Ord` instance does not make much sense mathematically, it is defined only for the sake of `Set`, `Map`, etc.

    >>> :set -XBinaryLiterals
    >>> -- (1 + x) * (1 + x + x^2) = 1 + x^3 (mod 2)
    >>> 0b11 * 0b111 :: F2Poly
    0b1001

Since: 1.0.1.0

#### Instances

Instances details

NFData F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods rnf :: F2Poly -> () #
Enum F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods succ :: F2Poly -> F2Poly # pred :: F2Poly -> F2Poly # toEnum :: Int -> F2Poly # fromEnum :: F2Poly -> Int # enumFrom :: F2Poly -> [F2Poly] # enumFromThen :: F2Poly -> F2Poly -> [F2Poly] # enumFromTo :: F2Poly -> F2Poly -> [F2Poly] # enumFromThenTo :: F2Poly -> F2Poly -> F2Poly -> [F2Poly] #
Generic F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Associated Types
type Rep F2Poly |
Instance details Defined in Data.Bit.F2PolyTS type Rep F2Poly = D1 ('MetaData "F2Poly" "Data.Bit.F2PolyTS" "bitvec-1.1.5.0-1WuodrWNWFINz6k1rLZGF" 'True) (C1 ('MetaCons "F2Poly" 'PrefixI 'True) (S1 ('MetaSel ('Just "unF2Poly") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Vector Bit))))
Methods from :: F2Poly -> Rep F2Poly x # to :: Rep F2Poly x -> F2Poly #
Num F2Poly # | Addition and multiplication are evaluated modulo 2. `abs` = `id` and `signum` = `const` 1. `fromInteger` converts a binary polynomial, encoded as `Integer`, to `F2Poly` encoding.
Instance details Defined in Data.Bit.F2PolyTS Methods (+) :: F2Poly -> F2Poly -> F2Poly # (-) :: F2Poly -> F2Poly -> F2Poly # (*) :: F2Poly -> F2Poly -> F2Poly # negate :: F2Poly -> F2Poly # abs :: F2Poly -> F2Poly # signum :: F2Poly -> F2Poly # fromInteger :: Integer -> F2Poly #
Integral F2Poly # | `toInteger` converts a binary polynomial, encoded as `F2Poly`, to an `Integer` encoding.
Instance details Defined in Data.Bit.F2PolyTS Methods quot :: F2Poly -> F2Poly -> F2Poly # rem :: F2Poly -> F2Poly -> F2Poly # div :: F2Poly -> F2Poly -> F2Poly # mod :: F2Poly -> F2Poly -> F2Poly # quotRem :: F2Poly -> F2Poly -> (F2Poly, F2Poly) # divMod :: F2Poly -> F2Poly -> (F2Poly, F2Poly) # toInteger :: F2Poly -> Integer #
Real F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods toRational :: F2Poly -> Rational #
Show F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods showsPrec :: Int -> F2Poly -> ShowS # show :: F2Poly -> String # showList :: [F2Poly] -> ShowS #
Eq F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods (==) :: F2Poly -> F2Poly -> Bool # (/=) :: F2Poly -> F2Poly -> Bool #
Ord F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS Methods compare :: F2Poly -> F2Poly -> Ordering # (<) :: F2Poly -> F2Poly -> Bool # (<=) :: F2Poly -> F2Poly -> Bool # (>) :: F2Poly -> F2Poly -> Bool # (>=) :: F2Poly -> F2Poly -> Bool # max :: F2Poly -> F2Poly -> F2Poly # min :: F2Poly -> F2Poly -> F2Poly #
type Rep F2Poly # |
Instance details Defined in Data.Bit.F2PolyTS type Rep F2Poly = D1 ('MetaData "F2Poly" "Data.Bit.F2PolyTS" "bitvec-1.1.5.0-1WuodrWNWFINz6k1rLZGF" 'True) (C1 ('MetaCons "F2Poly" 'PrefixI 'True) (S1 ('MetaSel ('Just "unF2Poly") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Vector Bit))))

unF2Poly :: F2Poly -> Vector Bit #

Convert an `F2Poly` to a vector of coefficients (first element corresponds to a constant term).

    >>> :set -XBinaryLiterals
    >>> unF2Poly 0b1101
    [1,0,1,1]

Since: 1.0.1.0

toF2Poly :: Vector Bit -> F2Poly #

Make an `F2Poly` from a list of coefficients (first element corresponds to a constant term).

    >>> :set -XOverloadedLists
    >>> toF2Poly [1,0,1,1,0,0]
    0b1101

Since: 1.0.1.0

gcdExt :: F2Poly -> F2Poly -> (F2Poly, F2Poly) #

Execute the extended Euclidean algorithm. For polynomials `a` and `b`, compute their unique greatest common divisor `g` and the unique coefficient polynomial `s` satisfying \( a \cdot s + b \cdot t = g \).

    >>> :set -XBinaryLiterals
    >>> gcdExt 0b101 0b0101
    (0b101,0b0)
    >>> gcdExt 0b11 0b111
    (0b1,0b10)

Since: 1.0.2.0