coya (empty) → 0.1
raw patch · 5 files changed
+211/−0 lines, 5 filesdep +basedep +groupsdep +primitive
Dependencies added: base, groups, primitive, refined, semirings
Files
- CHANGELOG.md +12/−0
- LICENSE +29/−0
- README.md +6/−0
- coya.cabal +73/−0
- src/Coya.hs +91/−0
+ CHANGELOG.md view
@@ -0,0 +1,12 @@+# Changelog++`coya` uses [PVP Versioning][1].+The changelog is available [on GitHub][2].++0.0.0+=====++* Initially created.++[1]: https://pvp.haskell.org+[2]: https://github.com/chessai/coya/releases
+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2019, chessai+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++* Neither the name of the copyright holder nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,6 @@+# coya++[](https://hackage.haskell.org/package/coya)+[](LICENSE)++See README for more info
+ coya.cabal view
@@ -0,0 +1,73 @@+cabal-version: 2.4+name:+ coya+version:+ 0.1+synopsis:+ Coya monoids+description:+ Take some log semiring R. Then, for any two x,y :: R, the following holds:+ .+ x ^ log y == y ^ log x == e ^ (log x * log y)+ .+ A Coya monoid is some commutative monoid (R, #), where x # y = x ^ log y.+ The following laws hold:+ .+ e # x = x (Left Identity)+ . + x # e = x (Right Identity)+ . + (x # y) # z == x # (y # z) (Associativity)+ .+ x # y == y # x (Commutativity)+ .+ If the R is a poset where all elements in R are greater than one, then R+ also forms a group:+ .+ x # (e ^ (1 / log (x))) == x+homepage:+ https://github.com/chessai/coya+bug-reports:+ https://github.com/chessai/coya/issues+license:+ BSD-3-Clause+license-file:+ LICENSE+author:+ chessai+maintainer:+ chessai1996@gmail.com+copyright:+ 2019 chessai+category:+ Data, Math+build-type:+ Simple+extra-doc-files:+ README.md+ , CHANGELOG.md+tested-with:+ GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.3++source-repository head+ type:+ git+ location:+ https://github.com/chessai/coya.git++library+ hs-source-dirs:+ src+ exposed-modules:+ Coya+ build-depends:+ , base >= 4.10.1 && < 4.13+ , groups >= 0.4+ , primitive >= 0.6.4+ , refined >= 0.3+ , semirings >= 0.3+ ghc-options:+ -O2+ -Wall+ default-language:+ Haskell2010
+ src/Coya.hs view
@@ -0,0 +1,91 @@+{-# language DataKinds #-}+{-# language DerivingStrategies #-}+{-# language FlexibleContexts #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language MagicHash #-}+{-# language PolyKinds #-}+{-# language ScopedTypeVariables #-}+{-# language UnboxedTuples #-}++-- | Consider some log-semiring R. Then, for any two x,y :: R, the following holds:+--+-- @x ^ log y == y ^ log x == e ^ (log x * log y)@+--+-- Coya is a commutative monoid (R, #), where x # y = x ^ log y.+--+-- The following laws hold:+-- +-- [__Left Identity__]: @e # x == x@+-- [__Right Identity__]: @x # e == x@+-- [__Associativity__]: @(x \# y) \# z == x \# (y \# z)@+-- [__Commutativity__]: @x \# y == y \# x@+--+-- If R is a poset where all elements in R are greater than one,+-- then R also forms a group:+--+-- @x # (exp (1 / log x)) = x@+module Coya+ ( Coya(..)+ , CoyaGroup(..)+ , coyaGroup+ ) where++import Data.Coerce (coerce)+import Data.Group+import Data.Primitive.Types (Prim)+import Data.Semiring (Semiring(..),Ring(..))+import Foreign.Storable (Storable)+import Prelude hiding (Num(..))+import Refined+import Refined.Unsafe (reallyUnsafeRefine)+import qualified GHC.Num as GHCNum++-- | The 'Coya' monoid. Its 'semigroup' instance+-- is a binary operation that distributes over multiplication, i.e:+--+-- @'Coya' x '<>' ('Coya' y '*' 'Coya' z) '==' ('Coya' x <> 'Coya' y) '*' ('Coya' x <> 'Coya' z)@+--+-- The 'Semiring' and 'GHCNum.Num' instances simply lift the underlying type's.+newtype Coya a = Coya { getCoya :: a }+ deriving newtype (Eq,Ord,Semiring,Ring)+ deriving newtype (GHCNum.Num,Floating,Fractional,Real,RealFloat,RealFrac)+ deriving newtype (Storable,Prim)+ deriving stock (Show,Read)++-- | @'Coya' x '<>' 'Coya' y '==' Coya (x '**' 'log' y)@+instance Floating a => Semigroup (Coya a) where+ Coya x <> Coya y = Coya (x ** log y)+ {-# inline (<>) #-}+ {-# specialise (<>) :: Coya Float -> Coya Float -> Coya Float #-}+ {-# specialise (<>) :: Coya Double -> Coya Double -> Coya Double #-}++-- | @'mempty' '==' e@+instance Floating a => Monoid (Coya a) where+ mempty = Coya (exp 1)+ {-# inline mempty #-}+ {-# specialise mempty :: Coya Float #-}+ {-# specialise mempty :: Coya Double #-}++-- | The 'Coya' monoid constrained to numbers which are greater than+-- 1. This ensures that the group property of inversion holds:+--+-- @x '<>' ('exp' (1 '/' 'log' x)) '==' x@+newtype CoyaGroup a = CoyaGroup { getCoyaGroup :: Refined (From 1) (Coya a) }++-- | A smart constructor for 'CoyaGroup'.+coyaGroup :: forall a. (Ord a, GHCNum.Num a) => a -> Maybe (CoyaGroup a)+coyaGroup a = do+ r <- refineThrow (Coya a)+ pure (coerce r)++-- | Equivalent to the 'Semigroup' instance for 'Coya'.+instance (Floating a, Ord a) => Semigroup (CoyaGroup a) where+ CoyaGroup r <> CoyaGroup r' = CoyaGroup (reallyUnsafeRefine (unrefine r <> unrefine r')) ++-- | Equivalent to the 'Monoid' instance for 'Coya'.+instance (Floating a, Ord a) => Monoid (CoyaGroup a) where+ mempty = CoyaGroup (reallyUnsafeRefine mempty)++-- | @x <> ('exp' (1 '/' 'log' x)) '==' x@+instance (Floating a, Ord a) => Group (CoyaGroup a) where+ invert (CoyaGroup x) = CoyaGroup (reallyUnsafeRefine (Coya (exp (1 / log (getCoya (unrefine x))))))