numhask 0.2.3.1 → 0.3.0.0
raw patch · 39 files changed
+2813/−2873 lines, 39 filesdep ~base
Dependency ranges changed: base
Files
- numhask.cabal +65/−45
- other/ring.svg +1/−1
- src/NumHask/Algebra.hs +0/−84
- src/NumHask/Algebra/Abstract.hs +74/−0
- src/NumHask/Algebra/Abstract/Action.hs +49/−0
- src/NumHask/Algebra/Abstract/Additive.hs +144/−0
- src/NumHask/Algebra/Abstract/Field.hs +270/−0
- src/NumHask/Algebra/Abstract/Group.hs +122/−0
- src/NumHask/Algebra/Abstract/Homomorphism.hs +43/−0
- src/NumHask/Algebra/Abstract/Lattice.hs +248/−0
- src/NumHask/Algebra/Abstract/Module.hs +23/−0
- src/NumHask/Algebra/Abstract/Multiplicative.hs +105/−0
- src/NumHask/Algebra/Abstract/Ring.hs +146/−0
- src/NumHask/Algebra/Abstract/TensorProduct.hs +68/−0
- src/NumHask/Algebra/Additive.hs +0/−388
- src/NumHask/Algebra/Basis.hs +0/−52
- src/NumHask/Algebra/Distribution.hs +0/−56
- src/NumHask/Algebra/Field.hs +0/−237
- src/NumHask/Algebra/Integral.hs +0/−213
- src/NumHask/Algebra/Linear/Hadamard.hs +43/−0
- src/NumHask/Algebra/Magma.hs +0/−107
- src/NumHask/Algebra/Metric.hs +0/−363
- src/NumHask/Algebra/Module.hs +0/−164
- src/NumHask/Algebra/Multiplicative.hs +0/−342
- src/NumHask/Algebra/Rational.hs +0/−247
- src/NumHask/Algebra/Ring.hs +0/−207
- src/NumHask/Algebra/Singleton.hs +0/−23
- src/NumHask/Analysis/Banach.hs +38/−0
- src/NumHask/Analysis/Metric.hs +312/−0
- src/NumHask/Data.hs +0/−97
- src/NumHask/Data/Complex.hs +98/−96
- src/NumHask/Data/Integral.hs +233/−0
- src/NumHask/Data/LogField.hs +131/−148
- src/NumHask/Data/Pair.hs +217/−0
- src/NumHask/Data/Positive.hs +83/−0
- src/NumHask/Data/Rational.hs +232/−0
- src/NumHask/Data/Wrapped.hs +53/−0
- src/NumHask/Exception.hs +15/−0
- stack.yaml +0/−3
numhask.cabal view
@@ -1,57 +1,77 @@-name: numhask-version: 0.2.3.1-synopsis: numeric classes-description: A numeric class heirarchy.-category: mathematics-homepage: https://github.com/tonyday567/numhask#readme-bug-reports: https://github.com/tonyday567/numhask/issues-author: Tony Day-maintainer: tonyday567@gmail.com-copyright: Tony Day-license: BSD3-license-file: LICENSE-build-type: Simple-cabal-version: >= 1.18--extra-source-files:- stack.yaml+name: numhask+version: 0.3.0.0+synopsis:+ numeric classes+description:+ A numeric class heirarchy.+category:+ mathematics+homepage:+ https://github.com/tonyday567/numhask#readme+bug-reports:+ https://github.com/tonyday567/numhask/issues+author:+ Tony Day+maintainer:+ tonyday567@gmail.com+copyright:+ Tony Day+license:+ BSD3+license-file:+ LICENSE+build-type:+ Simple+cabal-version:+ 1.18 extra-doc-files: other/*.svg source-repository head- type: git- location: https://github.com/tonyday567/numhask-+ type:+ git+ location:+ https://github.com/tonyday567/numhask+ subdir:+ numhask library hs-source-dirs:- src- default-extensions: NegativeLiterals OverloadedStrings UnicodeSyntax+ src+ default-extensions:+ NegativeLiterals+ OverloadedStrings+ UnicodeSyntax ghc-options:- -Wall- -Wcompat- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wredundant-constraints-+ -Wall+ -Wcompat+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wredundant-constraints build-depends:- base >=4.7 && <4.12+ base >=4.7 && <5 exposed-modules:- NumHask.Algebra- NumHask.Algebra.Additive- NumHask.Algebra.Basis- NumHask.Algebra.Distribution- NumHask.Algebra.Ring- NumHask.Algebra.Field- NumHask.Algebra.Integral- NumHask.Algebra.Rational- NumHask.Algebra.Magma- NumHask.Algebra.Metric- NumHask.Algebra.Module- NumHask.Algebra.Multiplicative- NumHask.Algebra.Singleton- NumHask.Data- NumHask.Data.Complex - NumHask.Data.LogField + NumHask.Algebra.Abstract+ NumHask.Algebra.Abstract.Action+ NumHask.Algebra.Abstract.Additive+ NumHask.Algebra.Abstract.Field+ NumHask.Algebra.Abstract.Group+ NumHask.Algebra.Abstract.Homomorphism+ NumHask.Algebra.Abstract.Lattice+ NumHask.Algebra.Abstract.Module+ NumHask.Algebra.Abstract.Multiplicative+ NumHask.Algebra.Abstract.Ring+ NumHask.Algebra.Abstract.TensorProduct+ NumHask.Algebra.Linear.Hadamard+ NumHask.Analysis.Banach+ NumHask.Analysis.Metric+ NumHask.Data.Complex+ NumHask.Data.Integral+ NumHask.Data.LogField+ NumHask.Data.Pair+ NumHask.Data.Positive+ NumHask.Data.Rational+ NumHask.Data.Wrapped+ NumHask.Exception other-modules: default-language: Haskell2010
other/ring.svg view
@@ -1,3 +1,3 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" height="600.0000" stroke-opacity="1" viewBox="0 0 600 600" font-size="1" width="600.0000" xmlns:xlink="http://www.w3.org/1999/xlink" stroke="rgb(0,0,0)" version="1.1"><defs></defs><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,236.0194,583.6788)" stroke="none" text-anchor="middle">CRing</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 268.6619,600.0000 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,271.2733,487.6094)" stroke="none" text-anchor="middle">Ring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9158,503.9306 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,271.2733,392.3625)" stroke="none" text-anchor="middle">Semiring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9158,408.6838 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,271.2733,298.3522)" stroke="none" text-anchor="middle">Distribution</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9158,314.6734 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,203.3770,204.3419)" stroke="none" text-anchor="middle">Multiplicative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 236.0194,220.6631 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,394.0116,298.3522)" stroke="none" text-anchor="middle">AdditiveGroup</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 426.6541,314.6734 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,273.8847,204.3419)" stroke="none" text-anchor="middle">Additive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 306.5272,220.6631 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,399.2344,204.3419)" stroke="none" text-anchor="middle">Invertible</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 431.8769,220.6631 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,271.2733,110.3316)" stroke="none" text-anchor="middle">Commutative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9158,126.6528 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,200.7656,110.3316)" stroke="none" text-anchor="middle">Associative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 233.4080,126.6528 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,341.7837,110.3316)" stroke="none" text-anchor="middle">Unital</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 374.4261,126.6528 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="6.528494703214632px" stroke="rgb(0,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,271.2733,16.3212)" stroke="none" text-anchor="middle">Magma</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.9158,32.6425 l -0.0000,-32.6425 h -65.2849 l -0.0000,32.6425 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 283.5147,32.6425 l 41.2275,54.9679 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 329.5423,94.0103 l -3.1096,-9.0974 l -1.4396,3.0321 l -3.3139,0.5331 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 324.9932,87.9450 l -0.2510,-0.3346 l 0.6365,-0.4774 l -0.3855,0.8120 l -0.2510,-0.3346 l -0.6365,0.4774 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 259.0324,32.6425 l -41.2259,54.9679 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 213.0065,94.0103 l 7.8629,-5.5323 l -3.3139,-0.5330 l -1.4396,-3.0321 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 217.5555,87.9449 l 0.2510,-0.3346 l 0.6365,0.4774 l -0.8875,-0.1427 l 0.2510,-0.3346 l -0.6365,-0.4774 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,32.6425 l 0.0000,53.3679 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,94.0103 l 2.9709,-9.1436 l -2.9709,1.5619 l -2.9709,-1.5619 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,86.4286 l -0.0000,-0.4183 l 0.7956,-0.0000 l -0.7956,0.4183 l -0.0000,-0.4183 l -0.7956,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.3811,32.6425 l 101.2446,148.7645 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 388.1267,188.0206 l -2.6884,-9.2307 l -1.5773,2.9628 l -3.3349,0.3803 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 383.8610,181.7528 l -0.2353,-0.3458 l 0.6577,-0.4476 l -0.4224,0.7934 l -0.2353,-0.3458 l -0.6577,0.4476 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.7267,126.6528 l 1.4825,53.3709 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.4313,188.0206 l 2.7159,-9.2226 l -2.9264,1.6438 l -3.0132,-1.4788 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.2208,180.4419 l -0.0116,-0.4181 l 0.7953,-0.0221 l -0.7837,0.4402 l -0.0116,-0.4181 l -0.7953,0.0221 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 329.9957,126.6528 l -39.6389,54.8825 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 285.6727,188.0206 l 7.7621,-5.6730 l -3.3230,-0.4733 l -1.4939,-3.0057 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 290.1119,181.8744 l 0.2449,-0.3391 l 0.6450,0.4658 l -0.8899,-0.1268 l 0.2449,-0.3391 l -0.6450,-0.4658 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 213.4599,126.6528 l 42.8190,55.0530 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.1904,188.0206 l -3.2685,-9.0415 l -1.3862,3.0569 l -3.3041,0.5911 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 256.5357,182.0360 l -0.2568,-0.3302 l 0.6280,-0.4885 l -0.3712,0.8186 l -0.2568,-0.3302 l -0.6280,0.4885 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 294.7401,220.6631 l 72.1161,56.4375 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 373.1563,282.0310 l -5.3697,-7.9749 l -0.6010,3.3023 l -3.0610,1.3770 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.1856,277.3584 l -0.3294,-0.2578 l 0.4903,-0.6266 l -0.1609,0.8843 l -0.3294,-0.2578 l -0.4903,0.6266 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 398.3277,220.6631 l -2.9656,53.3802 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 394.9184,282.0310 l 3.4736,-8.9648 l -3.0530,1.3947 l -2.8797,-1.7243 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 395.3389,274.4609 l 0.0232,-0.4176 l 0.7944,0.0441 l -0.8176,0.3735 l 0.0232,-0.4176 l -0.7944,-0.0441 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 259.4858,126.6528 l -39.6373,54.8824 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 215.1645,188.0206 l 7.7620,-5.6731 l -3.3230,-0.4732 l -1.4940,-3.0057 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.6036,181.8743 l 0.2449,-0.3391 l 0.6450,0.4658 l -0.8899,-0.1267 l 0.2449,-0.3391 l -0.6450,-0.4658 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 317.7547,126.6528 l -83.7310,56.8728 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 227.4059,188.0206 l 9.2331,-2.6800 l -2.9614,-1.5800 l -0.3772,-3.3352 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 233.6777,183.7607 l 0.3460,-0.2350 l 0.4470,0.6582 l -0.7931,-0.4231 l 0.3460,-0.2350 l -0.4470,-0.6582 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 201.2189,126.6528 l 1.4825,53.3709 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 202.9236,188.0206 l 2.7159,-9.2226 l -2.9264,1.6438 l -3.0132,-1.4788 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 202.7131,180.4419 l -0.0116,-0.4181 l 0.7953,-0.0221 l -0.7837,0.4402 l -0.0116,-0.4181 l -0.7953,0.0221 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.4313,220.6631 l -1.4825,53.3709 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.7267,282.0310 l 3.2237,-9.0576 l -3.0132,1.4788 l -2.9264,-1.6438 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.9372,274.4522 l 0.0116,-0.4181 l 0.7953,0.0221 l -0.8069,0.3960 l 0.0116,-0.4181 l -0.7953,-0.0221 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,32.6425 l 0.0000,241.3885 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,282.0310 l 2.9709,-9.1436 l -2.9709,1.5619 l -2.9709,-1.5619 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,274.4493 l -0.0000,-0.4183 l 0.7956,-0.0000 l -0.7956,0.4183 l -0.0000,-0.4183 l -0.7956,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 204.8459,126.6528 l 60.4068,241.6274 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 267.1930,376.0413 l 0.6646,-9.5912 l -2.5034,2.2358 l -3.2611,-0.7947 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.3542,368.6859 l -0.1014,-0.4058 l 0.7719,-0.1930 l -0.6704,0.5988 l -0.1014,-0.4058 l -0.7719,0.1930 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 337.7032,126.6528 l -60.4091,241.6274 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 275.3538,376.0413 l 5.1000,-8.1500 l -3.2611,0.7947 l -2.5034,-2.2359 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 277.1927,368.6860 l 0.1015,-0.4058 l 0.7719,0.1930 l -0.8733,0.2128 l 0.1015,-0.4058 l -0.7719,-0.1930 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,314.6734 l 0.0000,53.3679 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,376.0413 l 2.9709,-9.1436 l -2.9709,1.5619 l -2.9709,-1.5619 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,368.4596 l -0.0000,-0.4183 l 0.7956,-0.0000 l -0.7956,0.4183 l -0.0000,-0.4183 l -0.7956,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 383.4269,314.6734 l -97.2158,149.9026 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 281.8581,471.2881 l 7.4679,-6.0550 l -3.3425,-0.3061 l -1.6428,-2.9270 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 285.9834,464.9270 l 0.2276,-0.3509 l 0.6675,0.4329 l -0.8951,-0.0820 l 0.2276,-0.3509 l -0.6675,-0.4329 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,408.6838 l 0.0000,54.6043 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,471.2881 l 2.9709,-9.1436 l -2.9709,1.5619 l -2.9709,-1.5619 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 271.2733,463.7064 l -0.0000,-0.4183 l 0.7956,-0.0000 l -0.7956,0.4183 l -0.0000,-0.4183 l -0.7956,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 204.7814,220.6631 l 29.1477,338.7239 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 234.6150,567.3575 l 2.1761,-9.3647 l -2.8261,1.8109 l -3.0939,-1.3015 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 233.9650,559.8037 l -0.0359,-0.4167 l 0.7927,-0.0682 l -0.7568,0.4850 l -0.0359,-0.4167 l -0.7927,0.0682 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.5912373974723018" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.2840,503.9306 l -20.5193,55.9166 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.0087,567.3575 l 5.9391,-7.5604 l -3.3272,0.4428 l -2.2510,-2.4898 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 244.6206,560.2399 l 0.1441,-0.3927 l 0.7469,0.2741 l -0.8910,0.1186 l 0.1441,-0.3927 l -0.7469,-0.2741 Z"/></g></svg>+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" height="600.0000" stroke-opacity="1" viewBox="0 0 600 600" font-size="1" width="600.0000" xmlns:xlink="http://www.w3.org/1999/xlink" stroke="rgb(0,0,0)" version="1.1"><defs></defs><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,218.2130,587.6829)" stroke="none" text-anchor="middle">Field</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.8472,600.0000 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,218.2130,514.8633)" stroke="none" text-anchor="middle">IntegralDomain</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.8472,527.1804 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,218.2130,442.0456)" stroke="none" text-anchor="middle">CRing</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.8472,454.3627 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,255.6570,369.5423)" stroke="none" text-anchor="middle">Ring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 280.2912,381.8594 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,255.6570,297.0488)" stroke="none" text-anchor="middle">Semiring</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 280.2912,309.3659 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,240.8765,225.1564)" stroke="none" text-anchor="middle">Distributive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.5107,237.4735 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,294.0893,154.2100)" stroke="none" text-anchor="middle">Multiplicative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 318.7235,166.5271 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,316.7527,297.0488)" stroke="none" text-anchor="middle">Subtractive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 341.3869,309.3659 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,240.8765,154.2100)" stroke="none" text-anchor="middle">Additive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.5107,166.5271 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,347.2991,154.2100)" stroke="none" text-anchor="middle">AbelianGroup</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 371.9333,166.5271 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,381.7870,83.2635)" stroke="none" text-anchor="middle">Invertible</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 406.4211,95.5806 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,222.1545,83.2635)" stroke="none" text-anchor="middle">Commutative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 246.7887,95.5806 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,328.5771,83.2635)" stroke="none" text-anchor="middle">Associative</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 353.2113,95.5806 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,275.3643,83.2635)" stroke="none" text-anchor="middle">Unital</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 299.9985,95.5806 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.926836478297286px" stroke="rgb(0,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><text dominant-baseline="middle" transform="matrix(1.0000,0.0000,0.0000,1.0000,275.3643,12.3171)" stroke="none" text-anchor="middle">Magma</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 299.9985,24.6342 l -0.0000,-24.6342 h -49.2684 l -0.0000,24.6342 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 275.3643,24.6342 l 0.0000,38.3123 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 275.3643,70.9464 l 2.9876,-9.1949 l -2.9876,1.5707 l -2.9876,-1.5707 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 275.3643,63.3222 l -0.0000,-0.3757 l 0.7147,-0.0000 l -0.7147,0.3757 l -0.0000,-0.3757 l -0.7147,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 284.6027,24.6342 l 29.9360,39.9124 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 319.3388,70.9464 l -3.1271,-9.1484 l -1.4476,3.0492 l -3.3325,0.5361 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 314.7641,64.8472 l -0.2255,-0.3006 l 0.5718,-0.4288 l -0.3463,0.7294 l -0.2255,-0.3006 l -0.5718,0.4288 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 266.1265,24.6342 l -29.9342,39.9123 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 231.3923,70.9464 l 7.9071,-5.5634 l -3.3325,-0.5360 l -1.4477,-3.0491 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 235.9669,64.8470 l 0.2254,-0.3006 l 0.5718,0.4288 l -0.7972,-0.1282 l 0.2254,-0.3006 l -0.5718,-0.4288 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 293.8405,24.6342 l 62.8139,41.8747 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 363.3108,70.9464 l -5.9935,-7.5862 l -0.3503,3.3571 l -2.9641,1.6146 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 356.9670,66.7174 l -0.3126,-0.2084 l 0.3964,-0.5947 l -0.0838,0.8031 l -0.3126,-0.2084 l -0.3964,0.5947 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 287.8530,95.5806 l 41.2616,40.6947 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.8104,141.8929 l -4.4487,-8.5838 l -0.9796,3.2301 l -3.2162,1.0242 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 329.3821,136.5392 l -0.2675,-0.2639 l 0.5019,-0.5089 l -0.2343,0.7727 l -0.2675,-0.2639 l -0.5019,0.5089 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 375.7995,95.5806 l -19.0154,39.1173 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 353.2866,141.8929 l 6.7069,-6.9635 l -3.3737,0.1065 l -2.0003,-2.7188 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 356.6198,135.0359 l 0.1643,-0.3379 l 0.6428,0.3125 l -0.8071,0.0255 l 0.1643,-0.3379 l -0.6428,-0.3125 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 331.8275,95.5806 l 10.1801,38.5771 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 344.0488,141.8929 l 0.5426,-9.6529 l -2.4880,2.2810 l -3.2895,-0.7564 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 342.1034,134.5210 l -0.0959,-0.3633 l 0.6911,-0.1824 l -0.5952,0.5457 l -0.0959,-0.3633 l -0.6911,0.1824 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 243.8810,95.5806 l 74.7322,42.3669 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 325.5726,141.8929 l -6.5255,-7.1337 l -0.1070,3.3736 l -2.8398,1.8244 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 318.9401,138.1328 l -0.3269,-0.1853 l 0.3525,-0.6218 l -0.0256,0.8071 l -0.3269,-0.1853 l -0.3525,0.6218 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 225.4048,95.5806 l 10.1801,38.5771 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.6261,141.8929 l 0.5426,-9.6529 l -2.4880,2.2810 l -3.2895,-0.7564 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 235.6808,134.5210 l -0.0959,-0.3633 l 0.6911,-0.1824 l -0.5952,0.5457 l -0.0959,-0.3633 l -0.6911,0.1824 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 269.3769,95.5806 l -19.0154,39.1173 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 246.8640,141.8929 l 6.7069,-6.9635 l -3.3737,0.1065 l -2.0003,-2.7188 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 250.1972,135.0359 l 0.1643,-0.3379 l 0.6428,0.3125 l -0.8071,0.0255 l 0.1643,-0.3379 l -0.6428,-0.3125 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 313.3513,95.5806 l -51.0294,41.2808 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 256.1023,141.8929 l 9.0277,-3.4603 l -3.1002,-1.3349 l -0.6579,-3.3106 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 262.0298,137.0977 l 0.2921,-0.2363 l 0.4495,0.5557 l -0.7416,-0.3193 l 0.2921,-0.2363 l -0.4495,-0.5557 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 344.6651,166.5271 l -23.6053,110.3815 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 319.3868,284.7317 l 4.8444,-8.3668 l -3.2500,0.9112 l -2.5931,-2.1607 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(255,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 320.9812,277.2761 l 0.0786,-0.3674 l 0.6989,0.1495 l -0.7775,0.2180 l 0.0786,-0.3674 l -0.6989,-0.1495 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 234.6432,95.5806 l 41.2616,40.6947 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 281.6006,141.8929 l -4.4487,-8.5838 l -0.9796,3.2301 l -3.2162,1.0242 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 276.1723,136.5392 l -0.2675,-0.2639 l 0.5019,-0.5089 l -0.2343,0.7727 l -0.2675,-0.2639 l -0.5019,0.5089 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.6152,95.5806 l 10.1817,38.5771 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 290.8384,141.8929 l 0.5422,-9.6529 l -2.4879,2.2811 l -3.2895,-0.7563 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 288.8928,134.5211 l -0.0959,-0.3633 l 0.6911,-0.1824 l -0.5952,0.5457 l -0.0959,-0.3633 l -0.6911,0.1824 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 322.5897,95.5806 l -19.0154,39.1173 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 300.0767,141.8929 l 6.7069,-6.9635 l -3.3737,0.1065 l -2.0003,-2.7188 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.4100,135.0359 l 0.1643,-0.3379 l 0.6428,0.3125 l -0.8071,0.0255 l 0.1643,-0.3379 l -0.6428,-0.3125 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.8765,166.5271 l 0.0000,38.3123 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.8765,212.8393 l 2.9876,-9.1949 l -2.9876,1.5707 l -2.9876,-1.5707 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.8765,205.2151 l -0.0000,-0.3757 l 0.7147,-0.0000 l -0.7147,0.3757 l -0.0000,-0.3757 l -0.7147,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.3685,24.6342 l -29.2166,180.3082 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.8723,212.8393 l 4.4199,-8.5987 l -3.2004,1.0726 l -2.6979,-2.0283 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 244.0918,205.3132 l 0.0601,-0.3709 l 0.7055,0.1143 l -0.7656,0.2566 l 0.0601,-0.3709 l -0.7055,-0.1143 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 242.1510,166.5271 l 11.4080,110.2471 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 254.3825,284.7317 l 2.0253,-9.4536 l -2.8101,1.8698 l -3.1334,-1.2548 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 253.5977,277.1480 l -0.0387,-0.3738 l 0.7109,-0.0736 l -0.6722,0.4473 l -0.0387,-0.3738 l -0.7109,0.0736 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 243.4088,237.4735 l 8.1049,39.4221 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 253.1247,284.7317 l 1.0747,-9.6082 l -2.6101,2.1402 l -3.2427,-0.9369 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 251.5893,277.2637 l -0.0757,-0.3681 l 0.7001,-0.1439 l -0.6244,0.5120 l -0.0757,-0.3681 l -0.7001,0.1439 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 306.3722,309.3659 l -35.1792,41.7420 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 266.0375,357.2252 l 8.2100,-5.1057 l -3.2967,-0.7243 l -1.2723,-3.1264 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 270.9509,351.3953 l 0.2421,-0.2873 l 0.5465,0.4606 l -0.7887,-0.1733 l 0.2421,-0.2873 l -0.5465,-0.4606 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 255.6570,309.3659 l 0.0000,39.8593 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 255.6570,357.2252 l 2.9876,-9.1949 l -2.9876,1.5707 l -2.9876,-1.5707 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 255.6570,349.6010 l -0.0000,-0.3757 l 0.7147,-0.0000 l -0.7147,0.3757 l -0.0000,-0.3757 l -0.7147,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 222.0192,95.5806 l -3.5830,326.1484 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.3483,429.7285 l 3.0884,-9.1616 l -3.0047,1.5378 l -2.9702,-1.6034 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.5" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,255)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.4321,422.1047 l 0.0041,-0.3757 l 0.7147,0.0079 l -0.7188,0.3679 l 0.0041,-0.3757 l -0.7147,-0.0079 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 249.2959,381.8594 l -21.0508,40.7611 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 224.5741,429.7285 l 6.8737,-6.7988 l -3.3752,0.0247 l -1.9338,-2.7665 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 228.0726,422.9543 l 0.1724,-0.3339 l 0.6350,0.3280 l -0.8074,0.0059 l 0.1724,-0.3339 l -0.6350,-0.3280 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,454.3627 l 0.0000,40.1835 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,502.5462 l 2.9876,-9.1949 l -2.9876,1.5707 l -2.9876,-1.5707 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,494.9219 l -0.0000,-0.3757 l 0.7147,-0.0000 l -0.7147,0.3757 l -0.0000,-0.3757 l -0.7147,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="1.4294355539364358" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,527.1804 l 0.0000,40.1854 "/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,575.3658 l 2.9876,-9.1949 l -2.9876,1.5707 l -2.9876,-1.5707 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" opacity="0.3" stroke="rgb(0,0,0)" stroke-width="0.0" fill="rgb(84,84,84)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 218.2130,567.7416 l -0.0000,-0.3757 l 0.7147,-0.0000 l -0.7147,0.3757 l -0.0000,-0.3757 l -0.7147,0.0000 Z"/></g></svg>
− src/NumHask/Algebra.hs
@@ -1,84 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | The basic algebraic class structure of a number.------ > import NumHask.Algebra--- > import Prelude hiding (Integral(..), (*), (**), (+), (-), (/), (^), (^^), abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, exp, floor, fromInteger, fromIntegral, log, logBase, negate, pi, product, recip, round, sin, sinh, sqrt, sum, tan, tanh, toInteger, fromRational)----module NumHask.Algebra- ( -- * Mapping from Num- --- -- $numMap- module NumHask.Algebra.Additive- , module NumHask.Algebra.Basis- , module NumHask.Algebra.Distribution- , module NumHask.Algebra.Field- , module NumHask.Algebra.Integral- , module NumHask.Algebra.Magma- , module NumHask.Algebra.Metric- , module NumHask.Algebra.Module- , module NumHask.Algebra.Multiplicative- , module NumHask.Algebra.Rational- , module NumHask.Algebra.Ring- , module NumHask.Data.Complex- ) where--import NumHask.Data.Complex (Complex(..))-import NumHask.Algebra.Additive-import NumHask.Algebra.Basis-import NumHask.Algebra.Distribution-import NumHask.Algebra.Field-import NumHask.Algebra.Integral-import NumHask.Algebra.Magma-import NumHask.Algebra.Metric-import NumHask.Algebra.Module-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Rational-import NumHask.Algebra.Ring---- $numMap------ `Num` is a very old part of haskell, and a lot of different numeric concepts are tossed in there. The closest analogue in numhask is the `Ring` class, which combines the classical `+`, `-` and `*`, together with the distribution laws.------ ------ No attempt is made, however, to reconstruct the particular combination of laws and classes that represent the old `Num`. A rough mapping of `Num` to numhask classes follows:------ > -- | Basic numeric class.--- > class Num a where--- > {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}--- >--- > (+), (-), (*) :: a -> a -> a--- > -- | Unary negation.--- > negate :: a -> a--- --- `+` is a function of the `Additive` class, --- `-` is a function of the `AdditiveGroup` class, and--- `*` is a function of the `Multiplicative` class.--- `negate` is specifically in the `AdditiveInvertible` class. There are many useful constructions between negate and (-), involving cancellative properties.------ > -- | Absolute value.--- > abs :: a -> a--- > -- | Sign of a number.--- > -- The functions 'abs' and 'signum' should satisfy the law:--- > ----- > -- > abs x * signum x == x--- > ----- > -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)--- > -- or @1@ (positive).--- > signum :: a -> a------ `abs` is a function in the `Signed` class. The concept of an absolute value of a number can include situations where the domain and codomain are different, and `size` as a function in the `Normed` class is supplied for these cases.------ `sign` replaces `signum`, because signum is a heinous name.------ > -- | Conversion from an 'Integer'.--- > -- An integer literal represents the application of the function--- > -- 'fromInteger' to the appropriate value of type 'Integer',--- > -- so such literals have type @('Num' a) => a@.--- > fromInteger :: Integer -> a------ `fromInteger` is given its own class `FromInteger`-----
+ src/NumHask/Algebra/Abstract.hs view
@@ -0,0 +1,74 @@+{-# OPTIONS_GHC -Wall #-}++-- | The abstract algebraic class structure of a number.+--+module NumHask.Algebra.Abstract+ ( -- * Mapping from Num+ --+ -- $numMap+ module NumHask.Algebra.Abstract.Group+ , module NumHask.Algebra.Abstract.Additive+ , module NumHask.Algebra.Abstract.Multiplicative+ , module NumHask.Algebra.Abstract.Ring+ , module NumHask.Algebra.Abstract.Field+ , module NumHask.Algebra.Abstract.Module+ , module NumHask.Algebra.Abstract.Action+ , module NumHask.Algebra.Abstract.Lattice+ , module NumHask.Algebra.Abstract.Homomorphism+ )+where++import NumHask.Algebra.Abstract.Group+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Module+import NumHask.Algebra.Abstract.Action+import NumHask.Algebra.Abstract.Lattice+import NumHask.Algebra.Abstract.Homomorphism++-- $numMap+--+-- `Num` is a very old part of haskell, and a lot of different numeric concepts are tossed in there. The closest analogue in numhask is the `Ring` class, which magmaines the classical `+`, `-` and `*`, together with the Distributive laws.+--+-- +--+-- No attempt is made, however, to reconstruct the particular magmaination of laws and classes that represent the old `Num`. A rough mapping of `Num` to numhask classes follows:+--+-- > -- | Basic numeric class.+-- > class Num a where+-- > {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}+-- >+-- > (+), (-), (*) :: a -> a -> a+-- > -- | Unary negation.+-- > negate :: a -> a+--+-- `+` is a function of the `Additive` class,+-- `-` is a function of the `Subtractive` class, and+-- `*` is a function of the `Multiplicative` class.+-- `negate` is specifically in the `Subtractive` class. There are many useful constructions between negate and (-), involving cancellative properties.+--+-- > -- | Absolute value.+-- > abs :: a -> a+-- > -- | Sign of a number.+-- > -- The functions 'abs' and 'signum' should satisfy the law:+-- > --+-- > -- > abs x * signum x == x+-- > --+-- > -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)+-- > -- or @1@ (positive).+-- > signum :: a -> a+--+-- `abs` is a function in the `Signed` class. The concept of an absolute value of a number can include situations where the domain and codomain are different, and `size` as a function in the `Normed` class is supplied for these cases.+--+-- `sign` replaces `signum`, because signum is a heinous name.+--+-- > -- | Conversion from an 'Integer'.+-- > -- An integer literal represents the application of the function+-- > -- 'fromInteger' to the appropriate value of type 'Integer',+-- > -- so such literals have type @('Num' a) => a@.+-- > fromInteger :: Integer -> a+--+-- `fromInteger` is given its own class `FromInteger`+--
+ src/NumHask/Algebra/Abstract/Action.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -Wall #-}++-- | Action+module NumHask.Algebra.Abstract.Action+ ( Actor+ , AdditiveAction(..)+ , SubtractiveAction(..)+ , MultiplicativeAction(..)+ , DivisiveAction(..)+ ) where++import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Multiplicative++-- | a type class to represent an action on a higher-kinded number+type family Actor h++class (Additive (Actor h)) =>+ AdditiveAction h where+ infixl 6 .++ (.+) :: h -> Actor h -> h++ infixl 6 +.+ (+.) :: Actor h -> h -> h++class (Subtractive (Actor h)) =>+ SubtractiveAction h where+ infixl 6 .-+ (.-) :: h -> Actor h -> h++ infixl 6 -.+ (-.) :: Actor h -> h -> h++class (Multiplicative (Actor h)) =>+ MultiplicativeAction h where+ infixl 7 .*+ (.*) :: h -> Actor h -> h+ infixl 7 *.+ (*.) :: Actor h -> h -> h++class (Divisive (Actor h)) =>+ DivisiveAction h where+ infixl 7 ./+ (./) :: h -> Actor h -> h+ infixl 7 /.+ (/.) :: Actor h -> h -> h
+ src/NumHask/Algebra/Abstract/Additive.hs view
@@ -0,0 +1,144 @@+{-# OPTIONS_GHC -Wall #-}++-- | Additive+module NumHask.Algebra.Abstract.Additive+ ( Additive(..)+ , sum+ , Subtractive(..)+ )+where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import Prelude (Int, Integer, Float, Double, Bool)+import qualified Prelude as P++class Additive a where+ infixl 6 ++ (+) :: a -> a -> a++ zero :: a++sum :: (Additive a, P.Foldable f) => f a -> a+sum = P.foldr (+) zero++class (Additive a) => Subtractive a where+ negate :: a -> a++ infixl 6 -+ (-) :: a -> a -> a+ (-) a b = a + negate b++instance Additive Double where+ (+) = (P.+)+ zero = 0++instance Subtractive Double where+ negate = P.negate++instance Additive Float where+ (+) = (P.+)+ zero = 0++instance Subtractive Float where+ negate = P.negate++instance Additive Int where+ (+) = (P.+)+ zero = 0++instance Subtractive Int where+ negate = P.negate++instance Additive Integer where+ (+) = (P.+)+ zero = 0++instance Subtractive Integer where+ negate = P.negate++instance Additive Bool where+ (+) = (P.||)+ zero = P.False++instance Subtractive Bool where+ negate = P.not++instance Additive Natural where+ (+) = (P.+)+ zero = 0++instance Subtractive Natural where+ negate = P.negate++instance Additive Int8 where+ (+) = (P.+)+ zero = 0++instance Subtractive Int8 where+ negate = P.negate++instance Additive Int16 where+ (+) = (P.+)+ zero = 0++instance Subtractive Int16 where+ negate = P.negate++instance Additive Int32 where+ (+) = (P.+)+ zero = 0++instance Subtractive Int32 where+ negate = P.negate++instance Additive Int64 where+ (+) = (P.+)+ zero = 0++instance Subtractive Int64 where+ negate = P.negate++instance Additive Word where+ (+) = (P.+)+ zero = 0++instance Subtractive Word where+ negate = P.negate++instance Additive Word8 where+ (+) = (P.+)+ zero = 0++instance Subtractive Word8 where+ negate = P.negate++instance Additive Word16 where+ (+) = (P.+)+ zero = 0++instance Subtractive Word16 where+ negate = P.negate++instance Additive Word32 where+ (+) = (P.+)+ zero = 0++instance Subtractive Word32 where+ negate = P.negate++instance Additive Word64 where+ (+) = (P.+)+ zero = 0++instance Subtractive Word64 where+ negate = P.negate+++instance Additive b => Additive (a -> b) where+ f + f' = \a -> f a + f' a + zero _ = zero++instance Subtractive b => Subtractive (a -> b) where+ negate f = negate P.. f
+ src/NumHask/Algebra/Abstract/Field.hs view
@@ -0,0 +1,270 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}++-- | Field classes+module NumHask.Algebra.Abstract.Field+ ( Field+ , ExpField(..)+ , QuotientField(..)+ , UpperBoundedField(..)+ , LowerBoundedField(..)+ , TrigField(..)+ , half+ )+where++import Data.Bool (bool)+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Data.Integral+import qualified Prelude as P++-- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is an+-- Integral domain in which every non-zero element has a multiplicative+-- inverse.+--+-- A summary of the rules inherited from super-classes of Field+--+-- > zero + a == a+-- > a + zero == a+-- > (a + b) + c == a + (b + c)+-- > a + b == b + a+-- > a - a = zero+-- > negate a = zero - a+-- > negate a + a = zero+-- > a + negate a = zero+-- > one * a == a+-- > a * one == a+-- > (a * b) * c == a * (b * c)+-- > a * (b + c) == a * b + a * c+-- > (a + b) * c == a * c + b * c+-- > a * zero == zero+-- > zero * a == zero+-- > a * b == b * a+-- > a / a = one+-- > recip a = one / a+-- > recip a * a = one+-- > a * recip a = one+class (IntegralDomain a) =>+ Field a++instance Field P.Double++instance Field P.Float++-- instance Field b => Field (a -> b)++-- | A hyperbolic field class+--+-- > sqrt . (**2) == identity+-- > log . exp == identity+-- > for +ive b, a != 0,1: a ** logBase a b ≈ b+class (Field a) =>+ ExpField a where+ exp :: a -> a+ log :: a -> a+ logBase :: a -> a -> a+ logBase a b = log b / log a+ (**) :: a -> a -> a+ (**) a b = exp (log a * b)+ sqrt :: a -> a+ sqrt a = a ** (one / (one + one))++instance ExpField P.Double where+ exp = P.exp+ log = P.log+ (**) = (P.**)++instance ExpField P.Float where+ exp = P.exp+ log = P.log+ (**) = (P.**)++{-+instance ExpField b => ExpField (a -> b) where+ exp f = exp . f+ log f = log . f+ logBase f f' = \a -> logBase (f a) (f' a)+ f ** f' = \a -> f a ** f' a+ sqrt f = sqrt . f+-}++-- | quotient fields explode constraints if they allow for polymorphic integral types+--+-- > a - one < floor a <= a <= ceiling a < a + one+-- > round a == floor (a + one/(one+one))+--+-- fixme: had to redefine Signed operators here because of the Field import in Metric, itself due to Complex being defined there+class (Field a, Subtractive a, Integral b) => QuotientField a b where+ properFraction :: a -> (b, a)++ round :: a -> b+ default round ::(P.Ord a, P.Ord b, Subtractive b) => a -> b+ round x = case properFraction x of+ (n,r) -> let+ m = bool (n+one) (n-one) (r P.< zero)+ half_down = abs' r - (one/(one+one))+ abs' a+ | a P.< zero = negate a+ | P.otherwise = a+ in+ case P.compare half_down zero of+ P.LT -> n+ P.EQ -> bool m n (even n)+ P.GT -> m++ ceiling :: a -> b+ default ceiling :: (P.Ord a) => a -> b+ ceiling x = bool n (n+one) (r P.>= zero)+ where (n,r) = properFraction x++ floor :: a -> b+ default floor :: (P.Ord a, Subtractive b) => a -> b+ floor x = bool n (n-one) (r P.< zero)+ where (n,r) = properFraction x++ truncate :: a -> b+ default truncate :: (P.Ord a) => a -> b+ truncate x = bool (ceiling x) (floor x) (x P.> zero)++instance QuotientField P.Float P.Integer where+ properFraction = P.properFraction++instance QuotientField P.Double P.Integer where+ properFraction = P.properFraction++{-+instance QuotientField b c => QuotientField (a -> b) (a -> c) where+ properFraction f = (fst . frac, snd . frac)+ where+ frac a = properFraction @b @c (f a)++ round f = round . f++ ceiling f = ceiling . f++ floor f = floor . f++ truncate f = truncate . f++-}++-- | A bounded field includes the concepts of infinity and NaN, thus moving away from error throwing.+--+-- > one / zero + infinity == infinity+-- > infinity + a == infinity+-- > zero / zero != nan+--+-- Note the tricky law that, although nan is assigned to zero/zero, they are never-the-less not equal. A committee decided this.+class (IntegralDomain a) =>+ UpperBoundedField a where++ infinity :: a+ infinity = one / zero++ nan :: a+ nan = zero / zero++ isNaN :: a -> P.Bool++instance UpperBoundedField P.Float where+ isNaN = P.isNaN++instance UpperBoundedField P.Double where+ isNaN = P.isNaN++{-+instance UpperBoundedField b => UpperBoundedField (a -> b) where+ infinity _ = infinity+ nan _ = nan+ isNaN = P.undefined++-}++class (Subtractive a, Field a) =>+ LowerBoundedField a where++ negInfinity :: a+ negInfinity = negate (one / zero)++instance LowerBoundedField P.Float++instance LowerBoundedField P.Double++{-+instance LowerBoundedField b => LowerBoundedField (a -> b) where+ negInfinity _ = negInfinity++-}++-- | todo: work out boundings for complex+-- as it stands now, complex is different eg+--+-- > one / (zero :: Complex Float) == nan+-- instance (UpperBoundedField a) =>+-- UpperBoundedField (Complex a)++-- | Trigonometric Field+class (Field a) =>+ TrigField a where+ pi :: a+ sin :: a -> a+ cos :: a -> a+ tan :: a -> a+ tan x = sin x / cos x+ asin :: a -> a+ acos :: a -> a+ atan :: a -> a+ sinh :: a -> a+ cosh :: a -> a+ tanh :: a -> a+ tanh x = sinh x / cosh x+ asinh :: a -> a+ acosh :: a -> a+ atanh :: a -> a++instance TrigField P.Double where+ pi = P.pi+ sin = P.sin+ cos = P.cos+ asin = P.asin+ acos = P.acos+ atan = P.atan+ sinh = P.sinh+ cosh = P.cosh+ asinh = P.sinh+ acosh = P.acosh+ atanh = P.atanh++instance TrigField P.Float where+ pi = P.pi+ sin = P.sin+ cos = P.cos+ asin = P.asin+ acos = P.acos+ atan = P.atan+ sinh = P.sinh+ cosh = P.cosh+ asinh = P.sinh+ acosh = P.acosh+ atanh = P.atanh++{-+instance TrigField b => TrigField (a -> b) where+ pi _ = pi+ sin f = sin . f+ cos f = cos . f+ asin f = asin . f+ acos f = acos . f+ atan f = atan . f+ sinh f = sinh . f+ cosh f = cosh . f+ asinh f = asinh . f+ acosh f = acosh . f+ atanh f = atanh . f+-}++half :: (Field a) => a+half = one / two
+ src/NumHask/Algebra/Abstract/Group.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | The Group hierarchy+module NumHask.Algebra.Abstract.Group+ ( Magma(..)+ , Unital(..)+ , Associative+ , Commutative+ , Absorbing(..)+ , Invertible(..)+ , Idempotent+ , Group+ , AbelianGroup+ )+where++import Prelude++-- * Magma structure+-- | A <https://en.wikipedia.org/wiki/Magma_(algebra) Magma> is a tuple (T,magma) consisting of+--+-- - a type a, and+--+-- - a function (magma) :: T -> T -> T+--+-- The mathematical laws for a magma are:+--+-- - magma is defined for all possible pairs of type T, and+--+-- - magma is closed in the set of all possible values of type T+--+-- or, more tersly,+--+-- > ∀ a, b ∈ T: a magma b ∈ T+--+-- These laws are true by construction in haskell: the type signature of 'magma' and the above mathematical laws are synonyms.+--+--+class Magma a where+ magma :: a -> a -> a++instance Magma b => Magma (a -> b) where+ {-# INLINE magma #-}+ f `magma` g = \a -> f a `magma` g a++-- | A Unital Magma is a magma with an+-- <https://en.wikipedia.org/wiki/Identity_element identity element> (the+-- unit).+--+-- > unit magma a = a+-- > a magma unit = a+--+class Magma a =>+ Unital a where+ unit :: a++instance Unital b => Unital (a -> b) where+ {-# INLINE unit #-}+ unit _ = unit++-- | An Associative Magma+--+-- > (a magma b) magma c = a magma (b magma c)+class Magma a =>+ Associative a++instance Associative b => Associative (a -> b)++-- | A Commutative Magma is a Magma where the binary operation is+-- <https://en.wikipedia.org/wiki/Commutative_property commutative>.+--+-- > a magma b = b magma a+class Magma a =>+ Commutative a++instance Commutative b => Commutative (a -> b)++-- | An Invertible Magma+--+-- > ∀ a,b ∈ T: inv a `magma` (a `magma` b) = b = (b `magma` a) `magma` inv a+--+class Magma a =>+ Invertible a where+ inv :: a -> a++instance Invertible b => Invertible (a -> b) where+ {-# INLINE inv #-}+ inv f = inv . f++-- | A <https://en.wikipedia.org/wiki/Group_(mathematics) Group> is a+-- Associative, Unital and Invertible Magma.+class (Associative a, Unital a, Invertible a) => Group a+instance (Associative a, Unital a, Invertible a) => Group a++-- | An Absorbing is a Magma with an+-- <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element>+--+-- > a `times` absorb = absorb+class Magma a =>+ Absorbing a where+ absorb :: a++instance Absorbing b => Absorbing (a -> b) where+ {-# INLINE absorb #-}+ absorb _ = absorb++-- | An Idempotent Magma is a magma where every element is+-- <https://en.wikipedia.org/wiki/Idempotence Idempotent>.+--+-- > a magma a = a+class Magma a =>+ Idempotent a++instance Idempotent b => Idempotent (a -> b)++-- | An <https://en.wikipedia.org/wiki/Abelian_group Abelian Group> is an+-- Associative, Unital, Invertible and Commutative Magma . In other words, it+-- is a Commutative Group+class (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a+instance (Associative a, Unital a, Invertible a, Commutative a) => AbelianGroup a
+ src/NumHask/Algebra/Abstract/Homomorphism.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | The Homomorphism Hierarchy+module NumHask.Algebra.Abstract.Homomorphism+ ( Hom(..)+ , End+ , Iso+ , iso+ , invIso+ , Automorphism+ )+where++import NumHask.Algebra.Abstract.Group++-- | A Homomorphism between two magmas+-- law: forall a b. hom(a `magma` b) = hom(a) `magma` hom(b)+class (Magma a, Magma b) => Hom a b where+ hom :: a -> b++instance Hom b c => Hom (a -> b) (a -> c) where+ hom f = hom . f++class (Hom a a) => End a+instance (Hom a a) => End a++-- | A Isomorphism between two magmas+-- an Isomorphism is a bijective Homomorphism+class (Hom a b, Hom b a) => Iso a b++iso :: Iso a b => a -> b+iso = hom++invIso :: Iso a b => b -> a+invIso = hom++instance Iso b c => Iso (a -> b) (a -> c)++class (Iso a a) => Automorphism a+instance (Iso a a) => Automorphism a
+ src/NumHask/Algebra/Abstract/Lattice.hs view
@@ -0,0 +1,248 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++module NumHask.Algebra.Abstract.Lattice where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import NumHask.Algebra.Abstract.Field++-- | A algebraic structure with element joins: <http://en.wikipedia.org/wiki/Semilattice>+--+-- > Associativity: x \/ (y \/ z) == (x \/ y) \/ z+-- > Commutativity: x \/ y == y \/ x+-- > Idempotency: x \/ x == x+class (Eq a) => JoinSemiLattice a where+ infixr 5 \/+ (\/) :: a -> a -> a++-- | The partial ordering induced by the join-semilattice structure+joinLeq :: (JoinSemiLattice a) => a -> a -> Bool+joinLeq x y = (x \/ y) == y++-- | A algebraic structure with element meets: <http://en.wikipedia.org/wiki/Semilattice>+--+-- > Associativity: x /\ (y /\ z) == (x /\ y) /\ z+-- > Commutativity: x /\ y == y /\ x+-- > Idempotency: x /\ x == x+class (Eq a) => MeetSemiLattice a where+ infixr 6 /\+ (/\) :: a -> a -> a++-- | The partial ordering induced by the meet-semilattice structure+meetLeq :: (MeetSemiLattice a) => a -> a -> Bool+meetLeq x y = (x /\ y) == x++-- | The combination of two semi lattices makes a lattice if the absorption law holds:+-- see <http://en.wikipedia.org/wiki/Absorption_law> and <http://en.wikipedia.org/wiki/Lattice_(order)>+--+-- > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a+class (JoinSemiLattice a, MeetSemiLattice a) => Lattice a+instance (JoinSemiLattice a, MeetSemiLattice a) => Lattice a++-- | A join-semilattice with an identity element 'bottom' for '\/'.+--+-- > Identity: x \/ bottom == x+class JoinSemiLattice a => BoundedJoinSemiLattice a where+ bottom :: a++-- | A meet-semilattice with an identity element 'top' for '/\'.+--+-- > Identity: x /\ top == x+class MeetSemiLattice a => BoundedMeetSemiLattice a where+ top :: a++-- | Lattices with both bounds+class (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a+instance (JoinSemiLattice a, MeetSemiLattice a, BoundedJoinSemiLattice a, BoundedMeetSemiLattice a) => BoundedLattice a++instance JoinSemiLattice Float where+ (\/) = min++instance MeetSemiLattice Float where+ (/\) = max++instance JoinSemiLattice Double where+ (\/) = min++instance MeetSemiLattice Double where+ (/\) = max++instance JoinSemiLattice Int where+ (\/) = min++instance MeetSemiLattice Int where+ (/\) = max++instance JoinSemiLattice Integer where+ (\/) = min++instance MeetSemiLattice Integer where+ (/\) = max++instance JoinSemiLattice Bool where+ (\/) = (||)++instance MeetSemiLattice Bool where+ (/\) = (&&)++instance JoinSemiLattice Natural where+ (\/) = min++instance MeetSemiLattice Natural where+ (/\) = max++instance JoinSemiLattice Int8 where+ (\/) = min++instance MeetSemiLattice Int8 where+ (/\) = max++instance JoinSemiLattice Int16 where+ (\/) = min++instance MeetSemiLattice Int16 where+ (/\) = max++instance JoinSemiLattice Int32 where+ (\/) = min++instance MeetSemiLattice Int32 where+ (/\) = max++instance JoinSemiLattice Int64 where+ (\/) = min++instance MeetSemiLattice Int64 where+ (/\) = max++instance JoinSemiLattice Word where+ (\/) = min++instance MeetSemiLattice Word where+ (/\) = max++instance JoinSemiLattice Word8 where+ (\/) = min++instance MeetSemiLattice Word8 where+ (/\) = max++instance JoinSemiLattice Word16 where+ (\/) = min++instance MeetSemiLattice Word16 where+ (/\) = max++instance JoinSemiLattice Word32 where+ (\/) = min++instance MeetSemiLattice Word32 where+ (/\) = max++instance JoinSemiLattice Word64 where+ (\/) = min++instance MeetSemiLattice Word64 where+ (/\) = max++instance (Eq (a -> b), JoinSemiLattice b) => JoinSemiLattice (a -> b) where+ f \/ f' = \a -> f a \/ f' a ++instance (Eq (a -> b), MeetSemiLattice b) => MeetSemiLattice (a -> b) where+ f /\ f' = \a -> f a /\ f' a ++-- from here++instance BoundedJoinSemiLattice Float where+ bottom = negInfinity++instance BoundedMeetSemiLattice Float where+ top = infinity++instance BoundedJoinSemiLattice Double where+ bottom = negInfinity++instance BoundedMeetSemiLattice Double where+ top = infinity++instance BoundedJoinSemiLattice Int where+ bottom = minBound++instance BoundedMeetSemiLattice Int where+ top = maxBound++instance BoundedJoinSemiLattice Bool where+ bottom = False++instance BoundedMeetSemiLattice Bool where+ top = True++instance BoundedJoinSemiLattice Natural where+ bottom = 0++instance BoundedJoinSemiLattice Int8 where+ bottom = minBound++instance BoundedMeetSemiLattice Int8 where+ top = maxBound++instance BoundedJoinSemiLattice Int16 where+ bottom = minBound++instance BoundedMeetSemiLattice Int16 where+ top = maxBound++instance BoundedJoinSemiLattice Int32 where+ bottom = minBound++instance BoundedMeetSemiLattice Int32 where+ top = maxBound++instance BoundedJoinSemiLattice Int64 where+ bottom = minBound++instance BoundedMeetSemiLattice Int64 where+ top = maxBound++instance BoundedJoinSemiLattice Word where+ bottom = minBound++instance BoundedMeetSemiLattice Word where+ top = maxBound++instance BoundedJoinSemiLattice Word8 where+ bottom = minBound++instance BoundedMeetSemiLattice Word8 where+ top = maxBound++instance BoundedJoinSemiLattice Word16 where+ bottom = minBound++instance BoundedMeetSemiLattice Word16 where+ top = maxBound++instance BoundedJoinSemiLattice Word32 where+ bottom = minBound++instance BoundedMeetSemiLattice Word32 where+ top = maxBound++instance BoundedJoinSemiLattice Word64 where+ bottom = minBound++instance BoundedMeetSemiLattice Word64 where+ top = maxBound++instance (Eq (a -> b), BoundedJoinSemiLattice b) => BoundedJoinSemiLattice (a -> b) where+ bottom = const bottom++instance (Eq (a -> b), BoundedMeetSemiLattice b) => BoundedMeetSemiLattice (a -> b) where+ top = const top++++
+ src/NumHask/Algebra/Abstract/Module.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}++-- | Algebra for Modules+module NumHask.Algebra.Abstract.Module+ ( Module+ ) where++import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Action++-- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module> over r a is+-- a (Ring a), an abelian (Group r a) and an scalar-mult. (.*, *.) with the+-- laws:+--+-- > a .* one == a+-- > (a + b) .* c == (a .* c) + (b .* c)+-- > c *. (a + b) == (c *. a) + (c *. b)+-- > a .* zero == zero+-- > a .* b == b *. a+class (Distributive (Actor h), Divisive h, MultiplicativeAction h) => Module h
+ src/NumHask/Algebra/Abstract/Multiplicative.hs view
@@ -0,0 +1,105 @@+{-# OPTIONS_GHC -Wall #-}++-- | Multiplicative+module NumHask.Algebra.Abstract.Multiplicative+ ( Multiplicative(..)+ , product+ , Divisive(..)+ )+where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import Prelude (Int, Integer, Float, Double)+import qualified Prelude as P++class Multiplicative a where++ infixl 7 *+ (*) :: a -> a -> a++ one :: a++product :: (Multiplicative a, P.Foldable f) => f a -> a+product = P.foldr (*) one++class (Multiplicative a) => Divisive a where+ recip :: a -> a++ infixl 7 /+ (/) :: a -> a -> a+ (/) a b = a * recip b++instance Multiplicative Double where+ (*) = (P.*)+ one = 1.0++instance Divisive Double where+ recip = P.recip++instance Multiplicative Float where+ (*) = (P.*)+ one = 1.0++instance Divisive Float where+ recip = P.recip++instance Multiplicative Int where+ (*) = (P.*)+ one = 1++instance Multiplicative Integer where+ (*) = (P.*)+ one = 1++instance Multiplicative P.Bool where+ (*) = (P.&&)+ one = P.True++instance Multiplicative Natural where+ (*) = (P.*)+ one = 1++instance Multiplicative Int8 where+ (*) = (P.*)+ one = 1++instance Multiplicative Int16 where+ (*) = (P.*)+ one = 1+instance Multiplicative Int32 where+ (*) = (P.*)+ one = 1++instance Multiplicative Int64 where+ (*) = (P.*)+ one = 1++instance Multiplicative Word where+ (*) = (P.*)+ one = 1++instance Multiplicative Word8 where+ (*) = (P.*)+ one = 1++instance Multiplicative Word16 where+ (*) = (P.*)+ one = 1++instance Multiplicative Word32 where+ (*) = (P.*)+ one = 1++instance Multiplicative Word64 where+ (*) = (P.*)+ one = 1++instance Multiplicative b => Multiplicative (a -> b) where+ f * f' = \a -> f a * f' a + one _ = one++instance Divisive b => Divisive (a -> b) where+ recip f = recip P.. f+
+ src/NumHask/Algebra/Abstract/Ring.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | Ring+module NumHask.Algebra.Abstract.Ring+ ( Distributive+ , Semiring+ , Ring+ , CommutativeRing+ , IntegralDomain+ , StarSemiring(..)+ , KleeneAlgebra+ , InvolutiveRing(..)+ , two+ )+where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Group+import NumHask.Algebra.Abstract.Multiplicative+import qualified Prelude as P++-- | <https://en.wikipedia.org/wiki/Distributive_property Distributive> laws+--+-- > a * (b + c) == a * b + a * c+-- > (a * b) * c == a * c + b * c+class (Additive a, Multiplicative a) =>+ Distributive a++instance Distributive P.Double+instance Distributive P.Float+instance Distributive P.Int+instance Distributive P.Integer+instance Distributive Natural+instance Distributive Int8+instance Distributive Int16+instance Distributive Int32+instance Distributive Int64+instance Distributive Word+instance Distributive Word8+instance Distributive Word16+instance Distributive Word32+instance Distributive Word64+instance Distributive P.Bool+instance Distributive b => Distributive (a -> b)++-- | A <https://en.wikipedia.org/wiki/Semiring Semiring> is a ring without,+-- necessarily, negative elements.+--+-- TODO: rule zero' = zero. Is this somehow expressible in haskell?+class (Distributive a) =>+ Semiring a where+instance (Distributive a) =>+ Semiring a++-- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian+-- group under addition and monoid under multiplication where multiplication+-- distributes over addition. Alternatively, a ring is semiring where additive+-- inverses exist+class (Distributive a, Subtractive a) =>+ Ring a+instance (Distributive a, Subtractive a) =>+ Ring a++-- | A <https://en.wikipedia.org/wiki/Commutative_ring Commutative Ring> is a+-- ring with a Commutative Multiplication operation. Recall that Addition is+-- Commutative in all Rings+class (Distributive a, Subtractive a) =>+ CommutativeRing a+instance (Distributive a, Subtractive a) =>+ CommutativeRing a++-- | An <https://en.wikipedia.org/wiki/Integral_domain Integral Domain>+-- generalizes a ring of integers by requiring the product of any two nonzero+-- elements to be nonzero. This means that if a ≠ 0, an equality ab = ac+-- implies b = c.+-- FIXME: write a rule for this+--+class (Distributive a, Divisive a) =>+ IntegralDomain a++instance IntegralDomain P.Double++instance IntegralDomain P.Float++instance IntegralDomain b => IntegralDomain (a -> b)++-- | A <https://en.wikipedia.org/wiki/Semiring#Star_semirings StarSemiring>+-- is a semiring with an additional unary operator star satisfying:+--+-- > star a = one + a `times` star a+--+class (Distributive a) => StarSemiring a where+ star :: a -> a+ star a = one + plus a++ plus :: a -> a+ plus a = a * star a++instance StarSemiring b => StarSemiring (a -> b)++-- | A <https://en.wikipedia.org/wiki/Kleene_algebra Kleene Algebra> is+-- a Star Semiring with idempotent addition+--+-- > a `times` x + x = a ==> star a `times` x + x = x+-- > x `times` a + x = a ==> x `times` star a + x = x+--+class (StarSemiring a, Idempotent a) => KleeneAlgebra a++instance KleeneAlgebra b => KleeneAlgebra (a -> b)++-- | Involutive Ring+--+-- > adj (a + b) ==> adj a + adj b+-- > adj (a * b) ==> adj a * adj b+-- > adj one ==> one+-- > adj (adj a) ==> a+--+-- Note: elements for which @adj a == a@ are called "self-adjoint".+--+class (Distributive a) => InvolutiveRing a where+ adj :: a -> a+ adj x = x++instance InvolutiveRing P.Double+instance InvolutiveRing P.Float+instance InvolutiveRing P.Integer+instance InvolutiveRing P.Int+instance InvolutiveRing Natural+instance InvolutiveRing Int8+instance InvolutiveRing Int16+instance InvolutiveRing Int32+instance InvolutiveRing Int64+instance InvolutiveRing Word+instance InvolutiveRing Word8+instance InvolutiveRing Word16+instance InvolutiveRing Word32+instance InvolutiveRing Word64+instance InvolutiveRing b => InvolutiveRing (a -> b)++two :: (Multiplicative a, Additive a) => a+two = one + one
+ src/NumHask/Algebra/Abstract/TensorProduct.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# OPTIONS_GHC -Wall #-}++-- | TensorProduct+module NumHask.Algebra.Abstract.TensorProduct+ ( TensorProduct(..)+ , type (><)+ ) where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural+import Prelude (Double, Float, Int, Integer)++-- | tensorial type+type family (><) (a :: k1) (b :: k2) :: *++type instance Int >< Int = Int++type instance Integer >< Integer = Integer++type instance Double >< Double = Double++type instance Float >< Float = Float++type instance Natural >< Natural = Natural++type instance Int8 >< Int8 = Int8++type instance Int16 >< Int16 = Int16++type instance Int32 >< Int32 = Int32++type instance Int64 >< Int64 = Int64++type instance Word >< Word = Word++type instance Word8 >< Word8 = Word8++type instance Word16 >< Word16 = Word16++type instance Word32 >< Word32 = Word32++type instance Word64 >< Word64 = Word64++-- | representation synthesis+type family TensorRep k1 k2 where+ TensorRep (r a) (r a) = r (r a)+ TensorRep (r a) (s a) = r (s a)+ TensorRep (r a) a = r a++type instance r a >< b = TensorRep (r a) b++-- | generalised outer product+--+-- > a><b + c><b == (a+c) >< b+-- > a><b + a><c == a >< (b+c)+-- > a *. (b><c) == (a><b) .* c+-- > (a><b) .* c == a *. (b><c)+class TensorProduct a where+ infix 8 ><+ (><) :: a -> a -> (a >< a)+ outer :: a -> a -> (a >< a)+ outer = (><)+ timesleft :: a -> (a >< a) -> a+ timesright :: (a >< a) -> a -> a
− src/NumHask/Algebra/Additive.hs
@@ -1,388 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | A magma heirarchy for addition. The basic magma structure is repeated and prefixed with 'Additive-'.-module NumHask.Algebra.Additive- ( AdditiveMagma(..)- , AdditiveUnital(..)- , AdditiveAssociative- , AdditiveCommutative- , AdditiveInvertible(..)- , AdditiveIdempotent- , sum- , Additive(..)- , AdditiveRightCancellative(..)- , AdditiveLeftCancellative(..)- , AdditiveGroup(..)- , subtract- ) where--import Data.Complex (Complex(..))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))--import qualified Prelude as P-import Prelude (Bool(..), Double, Float, Int, Integer)---- | 'plus' is used as the operator for the additive magma to distinguish from '+' which, by convention, implies commutativity------ > ∀ a,b ∈ A: a `plus` b ∈ A------ law is true by construction in Haskell-class AdditiveMagma a where- plus :: a -> a -> a--instance AdditiveMagma Double where- plus = (P.+)--instance AdditiveMagma Float where- plus = (P.+)--instance AdditiveMagma Int where- plus = (P.+)--instance AdditiveMagma Integer where- plus = (P.+)--instance AdditiveMagma Bool where- plus = (P.||)--instance (AdditiveMagma a) => AdditiveMagma (Complex a) where- (rx :+ ix) `plus` (ry :+ iy) = (rx `plus` ry) :+ (ix `plus` iy)--instance AdditiveMagma Natural where- plus = (P.+)--instance AdditiveMagma Int8 where- plus = (P.+)--instance AdditiveMagma Int16 where- plus = (P.+)--instance AdditiveMagma Int32 where- plus = (P.+)--instance AdditiveMagma Int64 where- plus = (P.+)--instance AdditiveMagma Word where- plus = (P.+)--instance AdditiveMagma Word8 where- plus = (P.+)--instance AdditiveMagma Word16 where- plus = (P.+)--instance AdditiveMagma Word32 where- plus = (P.+)--instance AdditiveMagma Word64 where- plus = (P.+)---- | Unital magma for addition.------ > zero `plus` a == a--- > a `plus` zero == a-class AdditiveMagma a =>- AdditiveUnital a where- zero :: a--instance AdditiveUnital Double where- zero = 0--instance AdditiveUnital Float where- zero = 0--instance AdditiveUnital Int where- zero = 0--instance AdditiveUnital Integer where- zero = 0--instance AdditiveUnital Bool where- zero = False--instance (AdditiveUnital a) => AdditiveUnital (Complex a) where- zero = zero :+ zero--instance AdditiveUnital Natural where- zero = 0--instance AdditiveUnital Int8 where- zero = 0--instance AdditiveUnital Int16 where- zero = 0--instance AdditiveUnital Int32 where- zero = 0--instance AdditiveUnital Int64 where- zero = 0--instance AdditiveUnital Word where- zero = 0--instance AdditiveUnital Word8 where- zero = 0--instance AdditiveUnital Word16 where- zero = 0--instance AdditiveUnital Word32 where- zero = 0--instance AdditiveUnital Word64 where- zero = 0---- | Associative magma for addition.------ > (a `plus` b) `plus` c == a `plus` (b `plus` c)-class AdditiveMagma a =>- AdditiveAssociative a--instance AdditiveAssociative Double--instance AdditiveAssociative Float--instance AdditiveAssociative Int--instance AdditiveAssociative Integer--instance AdditiveAssociative Bool--instance (AdditiveAssociative a) => AdditiveAssociative (Complex a)--instance AdditiveAssociative Natural--instance AdditiveAssociative Int8--instance AdditiveAssociative Int16--instance AdditiveAssociative Int32--instance AdditiveAssociative Int64--instance AdditiveAssociative Word--instance AdditiveAssociative Word8--instance AdditiveAssociative Word16--instance AdditiveAssociative Word32--instance AdditiveAssociative Word64---- | Commutative magma for addition.------ > a `plus` b == b `plus` a-class AdditiveMagma a =>- AdditiveCommutative a--instance AdditiveCommutative Double--instance AdditiveCommutative Float--instance AdditiveCommutative Int--instance AdditiveCommutative Integer--instance AdditiveCommutative Bool--instance (AdditiveCommutative a) => AdditiveCommutative (Complex a)--instance AdditiveCommutative Natural--instance AdditiveCommutative Int8--instance AdditiveCommutative Int16--instance AdditiveCommutative Int32--instance AdditiveCommutative Int64--instance AdditiveCommutative Word--instance AdditiveCommutative Word8--instance AdditiveCommutative Word16--instance AdditiveCommutative Word32--instance AdditiveCommutative Word64---- | Invertible magma for addition.------ > ∀ a ∈ A: negate a ∈ A------ law is true by construction in Haskell-class AdditiveMagma a =>- AdditiveInvertible a where- negate :: a -> a--instance AdditiveInvertible Double where- negate = P.negate--instance AdditiveInvertible Float where- negate = P.negate--instance AdditiveInvertible Int where- negate = P.negate--instance AdditiveInvertible Integer where- negate = P.negate--instance AdditiveInvertible Bool where- negate = P.not--instance (AdditiveInvertible a) => AdditiveInvertible (Complex a) where- negate (rx :+ ix) = negate rx :+ negate ix--instance AdditiveInvertible Int8 where- negate = P.negate--instance AdditiveInvertible Int16 where- negate = P.negate--instance AdditiveInvertible Int32 where- negate = P.negate--instance AdditiveInvertible Int64 where- negate = P.negate--instance AdditiveInvertible Word where- negate = P.negate--instance AdditiveInvertible Word8 where- negate = P.negate--instance AdditiveInvertible Word16 where- negate = P.negate--instance AdditiveInvertible Word32 where- negate = P.negate--instance AdditiveInvertible Word64 where- negate = P.negate---- | Idempotent magma for addition.------ > a `plus` a == a-class AdditiveMagma a =>- AdditiveIdempotent a--instance AdditiveIdempotent Bool---- | sum definition avoiding a clash with the Sum monoid in base--- fixme: fit in with the Sum monoid----sum :: (Additive a, P.Foldable f) => f a -> a-sum = P.foldr (+) zero---- | Additive is commutative, unital and associative under addition------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a-class (AdditiveCommutative a, AdditiveUnital a, AdditiveAssociative a) =>- Additive a where- infixl 6 +- (+) :: a -> a -> a- a + b = plus a b--instance Additive Double--instance Additive Float--instance Additive Int--instance Additive Integer--instance Additive Bool--instance (Additive a) => Additive (Complex a)--instance Additive Natural--instance Additive Int8--instance Additive Int16--instance Additive Int32--instance Additive Int64--instance Additive Word--instance Additive Word8--instance Additive Word16--instance Additive Word32--instance Additive Word64---- | Non-commutative left minus------ > negate a `plus` a = zero-class (AdditiveUnital a, AdditiveAssociative a, AdditiveInvertible a) =>- AdditiveLeftCancellative a where- infixl 6 ~-- (~-) :: a -> a -> a- (~-) a b = negate b `plus` a---- | Non-commutative right minus------ > a `plus` negate a = zero-class (AdditiveUnital a, AdditiveAssociative a, AdditiveInvertible a) =>- AdditiveRightCancellative a where- infixl 6 -~- (-~) :: a -> a -> a- (-~) a b = a `plus` negate b---- | Minus ('-') is reserved for where both the left and right cancellative laws hold. This then implies that the AdditiveGroup is also Abelian.------ Syntactic unary negation - substituting "negate a" for "-a" in code - is hard-coded in the language to assume a Num instance. So, for example, using ''-a = zero - a' for the second rule below doesn't work.------ > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = zero-class (Additive a, AdditiveInvertible a) =>- AdditiveGroup a where- infixl 6 -- (-) :: a -> a -> a- (-) a b = a `plus` negate b--instance AdditiveGroup Double--instance AdditiveGroup Float--instance AdditiveGroup Int--instance AdditiveGroup Integer--instance (AdditiveGroup a) => AdditiveGroup (Complex a)--instance AdditiveGroup Int8--instance AdditiveGroup Int16--instance AdditiveGroup Int32--instance AdditiveGroup Int64--instance AdditiveGroup Word--instance AdditiveGroup Word8--instance AdditiveGroup Word16--instance AdditiveGroup Word32--instance AdditiveGroup Word64--subtract :: (AdditiveGroup a) => a -> a -> a-subtract = P.flip (-)
− src/NumHask/Algebra/Basis.hs
@@ -1,52 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -Wall #-}---- | Element-by-element operations-module NumHask.Algebra.Basis- ( AdditiveBasis(..)- , AdditiveGroupBasis(..)- , MultiplicativeBasis(..)- , MultiplicativeGroupBasis(..)- ) where--import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative---- | element by element addition------ > (a .+. b) .+. c == a .+. (b .+. c)--- > zero .+. a = a--- > a .+. zero = a--- > a .+. b == b .+. a-class (Additive a) =>- AdditiveBasis m a where- infixl 7 .+.- (.+.) :: m a -> m a -> m a---- | element by element subtraction------ > a .-. a = singleton zero-class (AdditiveGroup a) =>- AdditiveGroupBasis m a where- infixl 6 .-.- (.-.) :: m a -> m a -> m a---- | element by element multiplication------ > (a .*. b) .*. c == a .*. (b .*. c)--- > singleton one .*. a = a--- > a .*. singelton one = a--- > a .*. b == b .*. a-class (Multiplicative a) =>- MultiplicativeBasis m a where- infixl 7 .*.- (.*.) :: m a -> m a -> m a---- | element by element division------ > a ./. a == singleton one-class (MultiplicativeGroup a) =>- MultiplicativeGroupBasis m a where- infixl 7 ./.- (./.) :: m a -> m a -> m a
− src/NumHask/Algebra/Distribution.hs
@@ -1,56 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | 'Distribution' avoids a name clash with 'Data.Distributive'-module NumHask.Algebra.Distribution- ( Distribution- ) where--import Data.Complex (Complex(..))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import Prelude (Bool(..), Double, Float, Int, Integer)---- | Distribution (and annihilation) laws------ > a * (b + c) == a * b + a * c--- > (a + b) * c == a * c + b * c--- > a * zero == zero--- > zero * a == zero-class (Additive a, MultiplicativeMagma a) =>- Distribution a--instance Distribution Double--instance Distribution Float--instance Distribution Int--instance Distribution Integer--instance Distribution Bool--instance (AdditiveGroup a, Distribution a) => Distribution (Complex a)--instance Distribution Natural--instance Distribution Int8--instance Distribution Int16--instance Distribution Int32--instance Distribution Int64--instance Distribution Word--instance Distribution Word8--instance Distribution Word16--instance Distribution Word32--instance Distribution Word64-
− src/NumHask/Algebra/Field.hs
@@ -1,237 +0,0 @@-{-# LANGUAGE RebindableSyntax #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE DefaultSignatures #-}-{-# OPTIONS_GHC -Wall #-}---- | Field classes-module NumHask.Algebra.Field- ( Semifield- , Field- , ExpField(..)- , QuotientField(..)- , UpperBoundedField(..)- , LowerBoundedField(..)- , BoundedField- , TrigField(..)- ) where--import Data.Complex (Complex(..))-import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Ring-import NumHask.Algebra.Integral-import Data.Bool (bool)-import Prelude (Double, Float, Integer, (||))-import qualified Prelude as P---- | A Semifield is chosen here to be a Field without an Additive Inverse-class (MultiplicativeInvertible a, MultiplicativeGroup a, Semiring a) =>- Semifield a--instance Semifield Double--instance Semifield Float--instance (Semifield a, AdditiveGroup a) => Semifield (Complex a)---- | A Field is a Ring plus additive invertible and multiplicative invertible operations.------ A summary of the rules inherited from super-classes of Field------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a--- > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = zero--- > one * a == a--- > a * one == a--- > (a * b) * c == a * (b * c)--- > a * (b + c) == a * b + a * c--- > (a + b) * c == a * c + b * c--- > a * zero == zero--- > zero * a == zero--- > a * b == b * a--- > a / a = one--- > recip a = one / a--- > recip a * a = one--- > a * recip a = one-class (AdditiveGroup a, MultiplicativeGroup a, Ring a) =>- Field a--instance Field Double--instance Field Float--instance (Field a) => Field (Complex a)---- | A hyperbolic field class------ > sqrt . (**2) == identity--- > log . exp == identity--- > for +ive b, a != 0,1: a ** logBase a b ≈ b-class (Field a) =>- ExpField a where- exp :: a -> a- log :: a -> a- logBase :: a -> a -> a- logBase a b = log b / log a- (**) :: a -> a -> a- (**) a b = exp (log a * b)- sqrt :: a -> a- sqrt a = a ** (one / (one + one))--instance ExpField Double where- exp = P.exp- log = P.log- (**) = (P.**)--instance ExpField Float where- exp = P.exp- log = P.log- (**) = (P.**)---- | todo: bottom is here somewhere???-instance (P.Ord a, TrigField a, ExpField a) => ExpField (Complex a) where- exp (rx :+ ix) = exp rx * cos ix :+ exp rx * sin ix- log (rx :+ ix) = log (sqrt (rx * rx + ix * ix)) :+ atan2 ix rx- where- atan2 y x- | x P.> zero = atan (y / x)- | x P.== zero P.&& y P.> zero = pi / (one + one)- | x P.< one P.&& y P.> one = pi + atan (y / x)- | (x P.<= zero P.&& y P.< zero) || (x P.< zero) =- negate (atan2 (negate y) x)- | y P.== zero = pi -- must be after the previous test on zero y- | x P.== zero P.&& y P.== zero = y -- must be after the other double zero tests- | P.otherwise = x + y -- x or y is a NaN, return a NaN (via +)---- | quotient fields explode constraints if they allow for polymorphic integral types------ > a - one < floor a <= a <= ceiling a < a + one--- > round a == floor (a + one/(one+one))------ fixme: had to redefine Signed operators here because of the Field import in Metric, itself due to Complex being defined there-class (Field a, Integral b, AdditiveGroup b, MultiplicativeUnital b) =>- QuotientField a b where- properFraction :: a -> (b, a)-- round :: a -> b- default round :: (P.Ord a, P.Eq b) => a -> b- round x = case properFraction x of- (n,r) -> let- m = bool (n+one) (n-one) (r P.< zero)- half_down = abs' r - (one/(one+one))- abs' a- | a P.< zero = negate a- | P.otherwise = a- in- case P.compare half_down zero of- P.LT -> n- P.EQ -> bool m n (even n)- P.GT -> m-- ceiling :: a -> b- default ceiling :: (P.Ord a) => a -> b- ceiling x = bool n (n+one) (r P.> zero)- where (n,r) = properFraction x-- floor :: a -> b- default floor :: (P.Ord a) => a -> b- floor x = bool n (n-one) (r P.< zero)- where (n,r) = properFraction x--instance QuotientField Float Integer where- properFraction = P.properFraction--instance QuotientField Double Integer where- properFraction = P.properFraction---- | A bounded field includes the concepts of infinity and NaN, thus moving away from error throwing.------ > one / zero + infinity == infinity--- > infinity + a == infinity--- > zero / zero != nan------ Note the tricky law that, although nan is assigned to zero/zero, they are never-the-less not equal. A committee decided this.-class (Semifield a) =>- UpperBoundedField a where-- infinity :: a- infinity = one / zero- nan :: a- nan = zero / zero--instance UpperBoundedField Float--instance UpperBoundedField Double--class (Field a) =>- LowerBoundedField a where-- negInfinity :: a- negInfinity = negate (one / zero)--instance LowerBoundedField Float--instance LowerBoundedField Double---- | todo: work out boundings for complex--- as it stands now, complex is different eg------ > one / (zero :: Complex Float) == nan-instance (AdditiveGroup a, UpperBoundedField a) =>- UpperBoundedField (Complex a)--class (UpperBoundedField a, LowerBoundedField a) => BoundedField a--instance (UpperBoundedField a, LowerBoundedField a) => BoundedField a---- | Trigonometric Field-class (Field a) =>- TrigField a where- pi :: a- sin :: a -> a- cos :: a -> a- tan :: a -> a- tan x = sin x / cos x- asin :: a -> a- acos :: a -> a- atan :: a -> a- sinh :: a -> a- cosh :: a -> a- tanh :: a -> a- tanh x = sinh x / cosh x- asinh :: a -> a- acosh :: a -> a- atanh :: a -> a--instance TrigField Double where- pi = P.pi- sin = P.sin- cos = P.cos- asin = P.asin- acos = P.acos- atan = P.atan- sinh = P.sinh- cosh = P.cosh- asinh = P.sinh- acosh = P.acosh- atanh = P.atanh--instance TrigField Float where- pi = P.pi- sin = P.sin- cos = P.cos- asin = P.asin- acos = P.acos- atan = P.atan- sinh = P.sinh- cosh = P.cosh- asinh = P.sinh- acosh = P.acosh- atanh = P.atanh
− src/NumHask/Algebra/Integral.hs
@@ -1,213 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | Integral classes-module NumHask.Algebra.Integral- ( Integral(..)- , ToInteger(..)- , FromInteger(..)- , fromIntegral- , even- , odd- , (^)- , (^^)- ) where--import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import NumHask.Algebra.Ring-import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import qualified Prelude as P-import Prelude (Double, Float, Int, Integer, (.), fst, snd)---- | Integral laws------ > b == zero || b * (a `div` b) + (a `mod` b) == a-class (Semiring a) =>- Integral a where- infixl 7 `div`, `mod`- div :: a -> a -> a- div a1 a2 = fst (divMod a1 a2)- mod :: a -> a -> a- mod a1 a2 = snd (divMod a1 a2)-- divMod :: a -> a -> (a, a)-- quot :: a -> a -> a- quot a1 a2 = fst (quotRem a1 a2)- rem :: a -> a -> a- rem a1 a2 = snd (quotRem a1 a2)-- quotRem :: a -> a -> (a, a)--instance Integral Int where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Integer where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Natural where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Int8 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Int16 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Int32 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Int64 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Word where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Word8 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Word16 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Word32 where- divMod = P.divMod- quotRem = P.quotRem--instance Integral Word64 where- divMod = P.divMod- quotRem = P.quotRem---- | toInteger is kept separate from Integral to help with compatability issues.-class ToInteger a where- toInteger :: a -> Integer--instance ToInteger Int where- toInteger = P.toInteger--instance ToInteger Integer where- toInteger = P.toInteger--instance ToInteger Natural where- toInteger = P.toInteger--instance ToInteger Int8 where- toInteger = P.toInteger--instance ToInteger Int16 where- toInteger = P.toInteger--instance ToInteger Int32 where- toInteger = P.toInteger--instance ToInteger Int64 where- toInteger = P.toInteger--instance ToInteger Word where- toInteger = P.toInteger--instance ToInteger Word8 where- toInteger = P.toInteger--instance ToInteger Word16 where- toInteger = P.toInteger--instance ToInteger Word32 where- toInteger = P.toInteger--instance ToInteger Word64 where- toInteger = P.toInteger---- | fromInteger is the most problematic of the 'Num' class operators. Particularly heinous, it is assumed that any number type can be constructed from an Integer, so that the broad classes of objects that are composed of multiple elements is avoided in haskell.-class FromInteger a where- fromInteger :: Integer -> a---- | coercion of 'Integral's------ > fromIntegral a == a-fromIntegral :: (ToInteger a, FromInteger b) => a -> b-fromIntegral = fromInteger . toInteger--instance FromInteger Double where- fromInteger = P.fromInteger--instance FromInteger Float where- fromInteger = P.fromInteger--instance FromInteger Int where- fromInteger = P.fromInteger--instance FromInteger Integer where- fromInteger = P.fromInteger--instance FromInteger Natural where- fromInteger = P.fromInteger--instance FromInteger Int8 where- fromInteger = P.fromInteger--instance FromInteger Int16 where- fromInteger = P.fromInteger--instance FromInteger Int32 where- fromInteger = P.fromInteger--instance FromInteger Int64 where- fromInteger = P.fromInteger--instance FromInteger Word where- fromInteger = P.fromInteger--instance FromInteger Word8 where- fromInteger = P.fromInteger--instance FromInteger Word16 where- fromInteger = P.fromInteger--instance FromInteger Word32 where- fromInteger = P.fromInteger--instance FromInteger Word64 where- fromInteger = P.fromInteger---- $operators--even :: (P.Eq a, Integral a) => a -> P.Bool-even n = n `rem` (one + one) P.== zero--odd :: (P.Eq a, Integral a) => a -> P.Bool-odd = P.not . even------------------------------------------------------------ | raise a number to a non-negative integral power-(^) :: (P.Ord b, Integral b, Multiplicative a) => a -> b -> a-x0 ^ y0 | y0 P.< zero = P.undefined -- P.errorWithoutStackTrace "Negative exponent"- | y0 P.== zero = one- | P.otherwise = f x0 y0- where- two = one+one-- -- f : x0 ^ y0 = x ^ y- f x y | even y = f (x * x) (y `quot` two)- | y P.== one = x- | P.otherwise = g (x * x) (y `quot` two) x- -- See Note [Half of y - 1]- -- g : x0 ^ y0 = (x ^ y) * z- g x y z | even y = g (x * x) (y `quot` two) z- | y P.== one = x * z- | P.otherwise = g (x * x) (y `quot` two) (x * z)- -- See Note [Half of y - 1]--(^^) :: (MultiplicativeGroup a) => a -> Integer -> a-(^^) x n = if n P.>= zero then x^n else recip (x ^ negate n)
+ src/NumHask/Algebra/Linear/Hadamard.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wall #-}++-- | Element-by-element operations+module NumHask.Algebra.Linear.Hadamard+ ( HadamardMultiplication(..)+ , HadamardDivision(..)+ , Hadamard+ )+where++import NumHask.Algebra.Abstract.Multiplicative+import Data.Coerce++-- | element by element multiplication+--+-- > (a .*. b) .*. c == a .*. (b .*. c)+-- > singleton one .*. a = a+-- > a .*. singelton one = a+-- > a .*. b == b .*. a+class (Multiplicative a) =>+ HadamardMultiplication m a where+ infixl 7 .*.+ (.*.) :: m a -> m a -> m a+ (.*.) = coerce ((.*.) @m @a)+++-- | element by element division+--+-- > a ./. a == singleton one+class (Divisive a) =>+ HadamardDivision m a where+ infixl 7 ./.+ (./.) :: m a -> m a -> m a+ (./.) = coerce ((./.) @m @a)++class (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a+instance (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a+
− src/NumHask/Algebra/Magma.hs
@@ -1,107 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | Bootstrapping the number system.------ This heirarchy is repeated for the Additive and Multiplicative structures, in order to achieve class separation, so these classes are not used in the main numerical classes.-module NumHask.Algebra.Magma- ( Magma(..)- , Unital(..)- , Associative- , Commutative- , Invertible(..)- , Idempotent- , Monoidal- , CMonoidal- , Loop- , Group- , groupSwap- , Abelian- ) where---- * Magma structure--- | A <https://en.wikipedia.org/wiki/Magma_(algebra) Magma> is a tuple (T,⊕) consisting of------ - a type a, and------ - a function (⊕) :: T -> T -> T------ The mathematical laws for a magma are:------ - ⊕ is defined for all possible pairs of type T, and------ - ⊕ is closed in the set of all possible values of type T------ or, more tersly,------ > ∀ a, b ∈ T: a ⊕ b ∈ T------ These laws are true by construction in haskell: the type signature of 'magma' and the above mathematical laws are synonyms.-------class Magma a where- (⊕) :: a -> a -> a---- | A Unital Magma------ > unit ⊕ a = a--- > a ⊕ unit = a----class Magma a =>- Unital a where- unit :: a---- | An Associative Magma------ > (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)-class Magma a =>- Associative a---- | A Commutative Magma------ > a ⊕ b = b ⊕ a-class Magma a =>- Commutative a---- | An Invertible Magma------ > ∀ a ∈ T: inv a ∈ T------ law is true by construction in Haskell----class Magma a =>- Invertible a where- inv :: a -> a---- | An Idempotent Magma------ > a ⊕ a = a-class Magma a =>- Idempotent a---- | A Monoidal Magma is associative and unital.-class (Associative a, Unital a) =>- Monoidal a---- | A CMonoidal Magma is commutative, associative and unital.-class (Commutative a, Associative a, Unital a) =>- CMonoidal a---- | A Loop is unital and invertible-class (Unital a, Invertible a) =>- Loop a---- | A Group is associative, unital and invertible-class (Associative a, Unital a, Invertible a) =>- Group a---- | see http://chris-taylor.github.io/blog/2013/02/25/xor-trick/-groupSwap :: (Group a) => (a, a) -> (a, a)-groupSwap (a, b) =- let a' = a ⊕ b- b' = a ⊕ inv b- a'' = inv b' ⊕ a'- in (a'', b')---- | An Abelian Group is associative, unital, invertible and commutative-class (Associative a, Unital a, Invertible a, Commutative a) =>- Abelian a
− src/NumHask/Algebra/Metric.hs
@@ -1,363 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE DefaultSignatures #-}-{-# OPTIONS_GHC -Wall #-}---- | Metric classes-module NumHask.Algebra.Metric- ( Signed(..)- , Normed(..)- , Metric(..)- , Epsilon(..)- , (≈)- ) where--import qualified Prelude as P-import Prelude- hiding (fromInteger, Bounded(..), Integral(..), (*), (/), (+), (-), abs, negate, sqrt, (**))--import Data.Complex (Complex(..))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import NumHask.Algebra.Additive-import NumHask.Algebra.Field-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Integral---- | 'signum' from base is not an operator replicated in numhask, being such a very silly name, and preferred is the much more obvious 'sign'. Compare with 'Norm' and 'Banach' where there is a change in codomain------ > abs a * sign a == a------ Generalising this class tends towards size and direction (abs is the size on the one-dim number line of a vector with its tail at zero, and sign is the direction, right?).-class (MultiplicativeUnital a) =>- Signed a where- sign :: a -> a- abs :: a -> a--instance Signed Double where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Float where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Int where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Integer where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Natural where- sign a- | a == zero = zero- | otherwise = one- abs = id--instance Signed Int8 where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Int16 where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Int32 where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Int64 where- sign a- | a == zero = zero- | a > zero = one- | otherwise = negate one- abs = P.abs--instance Signed Word where- sign a- | a == zero = zero- | otherwise = one- abs = P.abs--instance Signed Word8 where- sign a- | a == zero = zero- | otherwise = one- abs = P.abs--instance Signed Word16 where- sign a- | a == zero = zero- | otherwise = one- abs = P.abs--instance Signed Word32 where- sign a- | a == zero = zero- | otherwise = one- abs = P.abs--instance Signed Word64 where- sign a- | a == zero = zero- | otherwise = one- abs = P.abs---- | L1 and L2 norms are provided for potential speedups, as well as the generalized p-norm.------ for p >= 1------ > normLp p a >= zero--- > normLp p zero == zero------ Note that the Normed codomain can be different to the domain.----class Normed a b where- normL1 :: a -> b- normL2 :: a -> b- normLp :: b -> a -> b--instance Normed Double Double where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Float Float where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Int Int where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Integer Integer where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance (Multiplicative a, ExpField a, Normed a a) =>- Normed (Complex a) a where- normL1 (rx :+ ix) = normL1 rx + normL1 ix- normL2 (rx :+ ix) = sqrt (rx * rx + ix * ix)- normLp p (rx :+ ix) = (normL1 rx ** p + normL1 ix ** p) ** (one / p)--instance Normed Natural Natural where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Int8 Int8 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Int16 Int16 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Int32 Int32 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Int64 Int64 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Word Word where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Word8 Word8 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Word16 Word16 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Word32 Word32 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a--instance Normed Word64 Word64 where- normL1 = P.abs- normL2 = P.abs- normLp _ a = P.abs a---- | distance between numbers using L1, L2 or Lp-norms------ > distanceL2 a b >= zero--- > distanceL2 a a == zero--- > \a b c -> distanceL2 a c + distanceL2 b c - distanceL2 a b >= zero &&--- > distanceL2 a b + distanceL2 b c - distanceL2 a c >= zero &&--- > distanceL2 a b + distanceL2 a c - distanceL2 b c >= zero &&-class Metric a b where- distanceL1 :: a -> a -> b- distanceL2 :: a -> a -> b- distanceLp :: b -> a -> a -> b--instance Metric Double Double where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Float Float where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Int Int where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Integer Integer where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance (Multiplicative a, ExpField a, Normed a a) =>- Metric (Complex a) a where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Natural Natural where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))--instance Metric Int8 Int8 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Int16 Int16 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Int32 Int32 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance Metric Int64 Int64 where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)---- fixme: circular distance may be more appropriate-instance Metric Word Word where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))--instance Metric Word8 Word8 where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))--instance Metric Word16 Word16 where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))--instance Metric Word32 Word32 where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))--instance Metric Word64 Word64 where- distanceL1 a b = fromInteger $ normL1 (toInteger a - toInteger b)- distanceL2 a b = fromInteger $ normL2 (toInteger a - toInteger b)- distanceLp p a b = fromInteger (normLp (toInteger p) (toInteger a - toInteger b))---- | todo: This should probably be split off into some sort of alternative Equality logic, but to what end?-class (Eq a, AdditiveUnital a) =>- Epsilon a where- nearZero :: a -> Bool- nearZero a = a == zero-- aboutEqual :: a -> a -> Bool- default aboutEqual :: AdditiveGroup a => a -> a -> Bool- aboutEqual a b = nearZero $ a - b-- positive :: (Signed a) => a -> Bool- positive a = a == abs a- veryPositive :: (Signed a) => a -> Bool- veryPositive a = P.not (nearZero a) && positive a- veryNegative :: (Signed a) => a -> Bool- veryNegative a = P.not (nearZero a P.|| positive a)--infixl 4 ≈---- | todo: is utf perfectly acceptable these days?-(≈) :: (Epsilon a) => a -> a -> Bool-(≈) = aboutEqual--instance Epsilon Double where- nearZero a = abs a <= (1e-12 :: Double)--instance Epsilon Float where- nearZero a = abs a <= (1e-6 :: Float)--instance Epsilon Int--instance Epsilon Integer--instance (Epsilon a, AdditiveGroup a) => Epsilon (Complex a) where- nearZero (rx :+ ix) = nearZero rx && nearZero ix- aboutEqual a b = nearZero $ a - b--instance Epsilon Int8--instance Epsilon Int16--instance Epsilon Int32--instance Epsilon Int64--instance Epsilon Word--instance Epsilon Word8--instance Epsilon Word16--instance Epsilon Word32--instance Epsilon Word64-
− src/NumHask/Algebra/Module.hs
@@ -1,164 +0,0 @@-{-# LANGUAGE ExplicitNamespaces #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}---- | Algebra for Modules-module NumHask.Algebra.Module- ( AdditiveModule(..)- , AdditiveGroupModule(..)- , MultiplicativeModule(..)- , MultiplicativeGroupModule(..)- , Banach(..)- , Hilbert(..)- , type (><)- , TensorProduct(..)- ) where--import NumHask.Algebra.Additive-import NumHask.Algebra.Field-import NumHask.Algebra.Metric-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Ring-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural-import Prelude- (Double, Float, Int, Integer)---- | Additive Module Laws------ > (a + b) .+ c == a + (b .+ c)--- > (a + b) .+ c == (a .+ c) + b--- > a .+ zero == a--- > a .+ b == b +. a-class (Additive a) =>- AdditiveModule r a where- infixl 6 .+- (.+) :: r a -> a -> r a-- infixl 6 +.- (+.) :: a -> r a -> r a---- | Subtraction Module Laws------ > (a + b) .- c == a + (b .- c)--- > (a + b) .- c == (a .- c) + b--- > a .- zero == a--- > a .- b == negate b +. a-class (AdditiveGroup a, AdditiveModule r a) =>- AdditiveGroupModule r a where- infixl 6 .-- (.-) :: r a -> a -> r a-- infixl 6 -.- (-.) :: a -> r a -> r a---- | Multiplicative Module Laws------ > a .* one == a--- > (a + b) .* c == (a .* c) + (b .* c)--- > c *. (a + b) == (c *. a) + (c *. b)--- > a .* zero == zero--- > a .* b == b *. a-class (Multiplicative a) =>- MultiplicativeModule r a where- infixl 7 .*- (.*) :: r a -> a -> r a- infixl 7 *.- (*.) :: a -> r a -> r a---- | Division Module Laws------ > nearZero a || a ./ one == a--- > b == zero || a ./ b == recip b *. a-class (MultiplicativeGroup a, MultiplicativeModule r a) =>- MultiplicativeGroupModule r a where- infixl 7 ./- (./) :: r a -> a -> r a- infixl 7 /.- (/.) :: a -> r a -> r a---- | Banach (with Norm) laws form rules around size and direction of a number, with a potential crossing into another codomain.------ > a == singleton zero || normalizeL2 a *. normL2 a == a-class (ExpField a, Normed (r a) a, MultiplicativeGroupModule r a) =>- Banach r a where- normalizeL1 :: r a -> r a- normalizeL1 a = a ./ normL1 a-- normalizeL2 :: r a -> r a- normalizeL2 a = a ./ normL2 a-- normalizeLp :: a -> r a -> r a- normalizeLp p a = a ./ normLp p a---- | the inner product of a representable over a semiring------ > a <.> b == b <.> a--- > a <.> (b +c) == a <.> b + a <.> c--- > a <.> (s *. b + c) == s * (a <.> b) + a <.> c--- (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)-class (Semiring a) =>- Hilbert r a where- infix 8 <.>- (<.>) :: r a -> r a -> a---- | tensorial type-type family (><) (a :: k1) (b :: k2) :: *--type instance Int >< Int = Int--type instance Integer >< Integer = Integer--type instance Double >< Double = Double--type instance Float >< Float = Float--type instance Natural >< Natural = Natural--type instance Int8 >< Int8 = Int8--type instance Int16 >< Int16 = Int16--type instance Int32 >< Int32 = Int32--type instance Int64 >< Int64 = Int64--type instance Word >< Word = Word--type instance Word8 >< Word8 = Word8--type instance Word16 >< Word16 = Word16--type instance Word32 >< Word32 = Word32--type instance Word64 >< Word64 = Word64---- | representation synthesis-type family TensorRep k1 k2 where- TensorRep (r a) (r a) = r (r a)- TensorRep (r a) (s a) = r (s a)- TensorRep (r a) a = r a--type instance r a >< b = TensorRep (r a) b---- | generalised outer product------ > a><b + c><b == (a+c) >< b--- > a><b + a><c == a >< (b+c)------ todo: work out why these laws down't apply--- > a *. (b><c) == (a><b) .* c--- > (a><b) .* c == a *. (b><c)-class TensorProduct a where- infix 8 ><- (><) :: a -> a -> (a >< a)- outer :: a -> a -> (a >< a)- outer = (><)- timesleft :: a -> (a >< a) -> a- timesright :: (a >< a) -> a -> a
− src/NumHask/Algebra/Multiplicative.hs
@@ -1,342 +0,0 @@-{-# OPTIONS_GHC -Wall #-}---- | A magma heirarchy for multiplication. The basic magma structure is repeated and prefixed with 'Multiplicative-'.-module NumHask.Algebra.Multiplicative- ( MultiplicativeMagma(..)- , MultiplicativeUnital(..)- , MultiplicativeAssociative- , MultiplicativeCommutative- , MultiplicativeInvertible(..)- , product- , Multiplicative(..)- , MultiplicativeRightCancellative(..)- , MultiplicativeLeftCancellative(..)- , MultiplicativeGroup(..)- , MultiplicativeIdempotent- ) where--import Data.Complex (Complex(..))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import NumHask.Algebra.Additive-import qualified Prelude as P-import Prelude (Bool(..), Double, Float, Int, Integer)---- | 'times' is used as the operator for the multiplicative magam to distinguish from '*' which, by convention, implies commutativity------ > ∀ a,b ∈ A: a `times` b ∈ A------ law is true by construction in Haskell-class MultiplicativeMagma a where- times :: a -> a -> a--instance MultiplicativeMagma Double where- times = (P.*)--instance MultiplicativeMagma Float where- times = (P.*)--instance MultiplicativeMagma Int where- times = (P.*)--instance MultiplicativeMagma Integer where- times = (P.*)--instance MultiplicativeMagma Bool where- times = (P.&&)--instance (MultiplicativeMagma a, AdditiveGroup a) =>- MultiplicativeMagma (Complex a) where- (rx :+ ix) `times` (ry :+ iy) =- (rx `times` ry - ix `times` iy) :+ (ix `times` ry + iy `times` rx)--instance MultiplicativeMagma Natural where- times = (P.*)--instance MultiplicativeMagma Int8 where- times = (P.*)--instance MultiplicativeMagma Int16 where- times = (P.*)--instance MultiplicativeMagma Int32 where- times = (P.*)--instance MultiplicativeMagma Int64 where- times = (P.*)--instance MultiplicativeMagma Word where- times = (P.*)--instance MultiplicativeMagma Word8 where- times = (P.*)--instance MultiplicativeMagma Word16 where- times = (P.*)--instance MultiplicativeMagma Word32 where- times = (P.*)--instance MultiplicativeMagma Word64 where- times = (P.*)---- | Unital magma for multiplication.------ > one `times` a == a--- > a `times` one == a-class MultiplicativeMagma a =>- MultiplicativeUnital a where- one :: a--instance MultiplicativeUnital Double where- one = 1--instance MultiplicativeUnital Float where- one = 1--instance MultiplicativeUnital Int where- one = 1--instance MultiplicativeUnital Integer where- one = 1--instance MultiplicativeUnital Bool where- one = True--instance (AdditiveUnital a, AdditiveGroup a, MultiplicativeUnital a) =>- MultiplicativeUnital (Complex a) where- one = one :+ zero--instance MultiplicativeUnital Natural where- one = 1--instance MultiplicativeUnital Int8 where- one = 1--instance MultiplicativeUnital Int16 where- one = 1--instance MultiplicativeUnital Int32 where- one = 1--instance MultiplicativeUnital Int64 where- one = 1--instance MultiplicativeUnital Word where- one = 1--instance MultiplicativeUnital Word8 where- one = 1--instance MultiplicativeUnital Word16 where- one = 1--instance MultiplicativeUnital Word32 where- one = 1--instance MultiplicativeUnital Word64 where- one = 1---- | Associative magma for multiplication.------ > (a `times` b) `times` c == a `times` (b `times` c)-class MultiplicativeMagma a =>- MultiplicativeAssociative a--instance MultiplicativeAssociative Double--instance MultiplicativeAssociative Float--instance MultiplicativeAssociative Int--instance MultiplicativeAssociative Integer--instance MultiplicativeAssociative Bool--instance (AdditiveGroup a, MultiplicativeAssociative a) =>- MultiplicativeAssociative (Complex a)--instance MultiplicativeAssociative Natural--instance MultiplicativeAssociative Int8--instance MultiplicativeAssociative Int16--instance MultiplicativeAssociative Int32--instance MultiplicativeAssociative Int64--instance MultiplicativeAssociative Word--instance MultiplicativeAssociative Word8--instance MultiplicativeAssociative Word16--instance MultiplicativeAssociative Word32--instance MultiplicativeAssociative Word64---- | Commutative magma for multiplication.------ > a `times` b == b `times` a-class MultiplicativeMagma a =>- MultiplicativeCommutative a--instance MultiplicativeCommutative Double--instance MultiplicativeCommutative Float--instance MultiplicativeCommutative Int--instance MultiplicativeCommutative Integer--instance MultiplicativeCommutative Bool--instance (AdditiveGroup a, MultiplicativeCommutative a) =>- MultiplicativeCommutative (Complex a)--instance MultiplicativeCommutative Natural--instance MultiplicativeCommutative Int8--instance MultiplicativeCommutative Int16--instance MultiplicativeCommutative Int32--instance MultiplicativeCommutative Int64--instance MultiplicativeCommutative Word--instance MultiplicativeCommutative Word8--instance MultiplicativeCommutative Word16--instance MultiplicativeCommutative Word32--instance MultiplicativeCommutative Word64---- | Invertible magma for multiplication.------ > ∀ a ∈ A: recip a ∈ A------ law is true by construction in Haskell-class MultiplicativeMagma a =>- MultiplicativeInvertible a where- recip :: a -> a--instance MultiplicativeInvertible Double where- recip = P.recip--instance MultiplicativeInvertible Float where- recip = P.recip--instance (AdditiveGroup a, MultiplicativeInvertible a) =>- MultiplicativeInvertible (Complex a) where- recip (rx :+ ix) = (rx `times` d) :+ (negate ix `times` d)- where- d = recip ((rx `times` rx) `plus` (ix `times` ix))---- | Idempotent magma for multiplication.------ > a `times` a == a-class MultiplicativeMagma a =>- MultiplicativeIdempotent a--instance MultiplicativeIdempotent Bool---- | product definition avoiding a clash with the Product monoid in base--- fixme: fit in with Product in base----product :: (Multiplicative a, P.Foldable f) => f a -> a-product = P.foldr (*) one---- | Multiplicative is commutative, associative and unital under multiplication------ > one * a == a--- > a * one == a--- > (a * b) * c == a * (b * c)--- > a * b == b * a-class ( MultiplicativeCommutative a- , MultiplicativeUnital a- , MultiplicativeAssociative a- ) =>- Multiplicative a where- infixl 7 *- (*) :: a -> a -> a- a * b = times a b--instance Multiplicative Double--instance Multiplicative Float--instance Multiplicative Int--instance Multiplicative Integer--instance Multiplicative Bool--instance (AdditiveGroup a, Multiplicative a) => Multiplicative (Complex a)--instance Multiplicative Natural--instance Multiplicative Int8--instance Multiplicative Int16--instance Multiplicative Int32--instance Multiplicative Int64--instance Multiplicative Word--instance Multiplicative Word8--instance Multiplicative Word16--instance Multiplicative Word32--instance Multiplicative Word64---- | Non-commutative left divide------ > recip a `times` a = one-class ( MultiplicativeUnital a- , MultiplicativeAssociative a- , MultiplicativeInvertible a- ) =>- MultiplicativeLeftCancellative a where- infixl 7 ~/- (~/) :: a -> a -> a- a ~/ b = recip b `times` a---- | Non-commutative right divide------ > a `times` recip a = one-class ( MultiplicativeUnital a- , MultiplicativeAssociative a- , MultiplicativeInvertible a- ) =>- MultiplicativeRightCancellative a where- infixl 7 /~- (/~) :: a -> a -> a- a /~ b = a `times` recip b---- | Divide ('/') is reserved for where both the left and right cancellative laws hold. This then implies that the MultiplicativeGroup is also Abelian.------ > a / a = one--- > recip a = one / a--- > recip a * a = one--- > a * recip a = one-class (Multiplicative a, MultiplicativeInvertible a) =>- MultiplicativeGroup a where- infixl 7 /- (/) :: a -> a -> a- (/) a b = a `times` recip b--instance MultiplicativeGroup Double--instance MultiplicativeGroup Float--instance (AdditiveGroup a, MultiplicativeGroup a) =>- MultiplicativeGroup (Complex a)
− src/NumHask/Algebra/Rational.hs
@@ -1,247 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -Wall #-}---- | Integral classes-module NumHask.Algebra.Rational- ( Ratio(..)- , Rational- , ToRatio(..)- , FromRatio(..)- , fromRational- -- * $integral_functionality- , reduce- , gcd- ) where---- import Data.Coerce-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Float-import GHC.Natural (Natural(..))-import qualified GHC.Real-import qualified Prelude as P-import Prelude (Double, Float, Int, Integer, (.))-import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Distribution-import NumHask.Algebra.Integral-import NumHask.Algebra.Metric-import NumHask.Algebra.Ring-import NumHask.Algebra.Field--data Ratio a = !a :% !a deriving (P.Show)--instance (P.Eq a, AdditiveUnital a) => P.Eq (Ratio a) where- a == b- | (isRNaN a P.|| isRNaN b) = P.False- | P.otherwise = (x P.== x') P.&& (y P.== y')- where- (x:%y) = a- (x':%y') = b--isRNaN :: (P.Eq a, AdditiveUnital a) => Ratio a -> P.Bool-isRNaN (x :% y) | (x P.== zero P.&& y P.== zero) = P.True- | P.otherwise = P.False---type Rational = Ratio Integer--instance (P.Ord a, Multiplicative a, Integral a) => P.Ord (Ratio a) where- (x:%y) <= (x':%y') = x * y' P.<= x' * y- (x:%y) < (x':%y') = x * y' P.< x' * y--instance (P.Ord a, Integral a, Signed a, AdditiveInvertible a) => AdditiveMagma (Ratio a) where- (x :% y) `plus` (x' :% y')- | (y P.== zero P.&& y' P.== zero) = sign (x `plus` x') :% zero- | (y P.== zero) = x :% y- | (y' P.== zero) = x' :% y'- | P.otherwise = reduce ((x `times` y') `plus` (x' `times` y)) (y `times` y')--instance (P.Ord a, Integral a, Signed a, AdditiveInvertible a) => AdditiveUnital (Ratio a) where- zero = zero :% one--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => AdditiveAssociative (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => AdditiveCommutative (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => AdditiveInvertible (Ratio a) where- negate (x :% y) = negate x :% y--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => Additive (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveGroup a) => AdditiveGroup (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => MultiplicativeMagma (Ratio a) where- (x:%y) `times` (x':%y') = reduce (x `times` x') (y `times` y')--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => MultiplicativeUnital (Ratio a) where- one = one :% one--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) =>- MultiplicativeAssociative (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) =>- MultiplicativeCommutative (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) =>- MultiplicativeInvertible (Ratio a) where- recip (x :% y)- | x P.< zero = negate y :% negate x- | P.otherwise = y :% x--instance (Signed a, AdditiveInvertible a, AdditiveUnital a, Integral a, P.Ord a, Multiplicative a) => Multiplicative (Ratio a)--instance (Signed a, AdditiveInvertible a, AdditiveUnital a, Integral a, P.Ord a, Multiplicative a) =>- MultiplicativeGroup (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => Distribution (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => Semiring (Ratio a)-instance (P.Ord a, Signed a, Integral a, AdditiveGroup a) => Ring (Ratio a)-instance (P.Ord a, Signed a, Integral a, Multiplicative a, Ring a) => CRing (Ratio a)-instance (P.Ord a, Signed a, Integral a, Multiplicative a, Ring a) =>- InvolutiveRing (Ratio a)--instance (P.Ord a, Signed a, Integral a, Multiplicative a, Ring a) =>- Semifield (Ratio a)--instance (P.Ord a, Signed a, Integral a, Multiplicative a, Ring a) =>- Field (Ratio a)--instance (P.Ord a, Signed a, ToInteger a, Integral a, Multiplicative a, Ring a, P.Eq b, AdditiveGroup b, Integral b, FromInteger b) => QuotientField (Ratio a) b where- properFraction (n :% d) = let (w,r) = quotRem n d in (fromIntegral w,r:%d)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a, Multiplicative a, Ring a) => UpperBoundedField (Ratio a)--instance (P.Ord a, Signed a, Integral a, Multiplicative a, Ring a, AdditiveInvertible a) => LowerBoundedField (Ratio a)--instance (P.Ord a, Signed a, Integral a, AdditiveInvertible a) => Signed (Ratio a) where- sign (n :% _)- | n P.== zero = zero- | n P.> zero = one- | P.otherwise = negate one- abs (n :% d) = abs n :% abs d--instance (P.Ord a, Integral a, Signed a, AdditiveInvertible a) => Normed (Ratio a) (Ratio a) where- normL1 = abs- normL2 = abs- normLp _ = abs--instance (P.Ord a, Integral a, Signed a, AdditiveGroup a) => Metric (Ratio a) (Ratio a) where- distanceL1 a b = normL1 (a - b)- distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b)--instance (P.Ord a, Signed a, Integral a, AdditiveGroup a) => Epsilon (Ratio a)--instance (FromInteger a, MultiplicativeUnital a) => FromInteger (Ratio a) where- fromInteger x = fromInteger x :% one---- | toRatio is equivalent to `Real` in base.-class ToRatio a where- toRatio :: a -> Ratio Integer--instance (ToInteger a) => ToRatio (Ratio a) where- toRatio (n :% d) = toInteger n :% toInteger d---- | `Fractional` in base splits into fromRatio and MultiplicativeGroup-class FromRatio a where- fromRatio :: Ratio Integer -> a--instance (FromInteger a) => FromRatio (Ratio a) where- fromRatio (n :% d) = fromInteger n :% fromInteger d---- | coercion of 'Rational's------ > fromRational a == a-fromRational :: (ToRatio a, FromRatio b) => a -> b-fromRational = fromRatio . toRatio---- | fixme: use coerce-fromBaseRational :: P.Rational -> Ratio Integer-fromBaseRational (n GHC.Real.:% d) = n :% d--instance FromRatio Double where- fromRatio (n:%d)= rationalToDouble n d--instance FromRatio Float where- fromRatio (n:%d)= rationalToFloat n d--instance ToRatio Double where- toRatio = fromBaseRational . P.toRational--instance ToRatio Float where- toRatio = fromBaseRational . P.toRational--instance ToRatio Int where- toRatio = fromBaseRational . P.toRational--instance ToRatio Integer where- toRatio = fromBaseRational . P.toRational--instance ToRatio Natural where- toRatio = fromBaseRational . P.toRational--instance ToRatio P.Rational where- toRatio = fromBaseRational . P.toRational--instance ToRatio Int8 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Int16 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Int32 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Int64 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Word where- toRatio = fromBaseRational . P.toRational--instance ToRatio Word8 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Word16 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Word32 where- toRatio = fromBaseRational . P.toRational--instance ToRatio Word64 where- toRatio = fromBaseRational . P.toRational---- * $integral_functions--- integral functionality is largely based on GHC.Real------ | 'reduce' is a subsidiary function used only in this module.--- It normalises a ratio by dividing both numerator and denominator by--- their greatest common divisor.-reduce :: (P.Ord a, AdditiveInvertible a, Signed a, Integral a) => a -> a -> Ratio a-reduce x y- | x P.== zero P.&& y P.== zero = zero :% zero- | z P.== zero = one :% zero- | P.otherwise = (x `quot` z) % (y `quot` z)- where- z = gcd x y- n % d- | d P.< zero = negate n :% negate d- | P.otherwise = n:%d---- | @'gcd' x y@ is the non-negative factor of both @x@ and @y@ of which--- every common factor of @x@ and @y@ is also a factor; for example--- @'gcd' 4 2 = 2@, @'gcd' (-4) 6 = 2@, @'gcd' 0 4@ = @4@. @'gcd' 0 0@ = @0@.--- (That is, the common divisor that is \"greatest\" in the divisibility--- preordering.)------ Note: Since for signed fixed-width integer types, @'abs' 'minBound' < 0@,--- the result may be negative if one of the arguments is @'minBound'@ (and--- necessarily is if the other is @0@ or @'minBound'@) for such types.-gcd :: (P.Ord a, Signed a, Integral a) => a -> a -> a-gcd x y = gcd' (abs x) (abs y)- where- gcd' a b- | b P.== zero = a- | P.otherwise = gcd' b (a `rem` b)
− src/NumHask/Algebra/Ring.hs
@@ -1,207 +0,0 @@-{-# OPTIONS_GHC -Wall #-}-{-# language FlexibleInstances #-}---- | Ring classes. A distinguishment is made between Rings and Commutative Rings.-module NumHask.Algebra.Ring- ( Semiring- , Ring- , CRing- , StarSemiring(..)- , KleeneAlgebra- , InvolutiveRing(..)- ) where--import Data.Complex (Complex(..))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64)-import GHC.Natural (Natural(..))-import NumHask.Algebra.Additive-import NumHask.Algebra.Distribution-import NumHask.Algebra.Multiplicative-import Prelude (Bool(..), Double, Float, Int, Integer)---- | Semiring-class (MultiplicativeAssociative a, MultiplicativeUnital a, Distribution a) =>- Semiring a--instance Semiring Double--instance Semiring Float--instance Semiring Int--instance Semiring Integer--instance Semiring Bool--instance (AdditiveGroup a, Semiring a) => Semiring (Complex a)--instance Semiring Natural--instance Semiring Int8--instance Semiring Int16--instance Semiring Int32--instance Semiring Int64--instance Semiring Word--instance Semiring Word8--instance Semiring Word16--instance Semiring Word32--instance Semiring Word64---- | Ring--- --- A Ring consists of a set equipped with two binary operations that generalize the arithmetic operations of addition and multiplication; it is an abelian group with a second binary operation that is associative, is distributive over the abelian group operation, and has an identity element.--- --- Summary of the laws inherited from the ring super-classes:------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a--- > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = zero--- > one `times` a == a--- > a `times` one == a--- > (a `times` b) `times` c == a `times` (b `times` c)--- > a `times` (b + c) == a `times` b + a `times` c--- > (a + b) `times` c == a `times` c + b `times` c--- > a `times` zero == zero--- > zero `times` a == zero--- -class ( Semiring a- , AdditiveGroup a- ) =>- Ring a--instance Ring Double--instance Ring Float--instance Ring Int--instance Ring Integer--instance (Ring a) => Ring (Complex a)--instance Ring Int8--instance Ring Int16--instance Ring Int32--instance Ring Int64--instance Ring Word--instance Ring Word8--instance Ring Word16--instance Ring Word32--instance Ring Word64---- | CRing is a Ring with Multiplicative Commutation. It arises often due to '*' being defined as a multiplicative commutative operation.-class (Multiplicative a, Ring a) =>- CRing a--instance CRing Double--instance CRing Float--instance CRing Int--instance CRing Integer--instance (CRing a) => CRing (Complex a)--instance CRing Int8--instance CRing Int16--instance CRing Int32--instance CRing Int64--instance CRing Word--instance CRing Word8--instance CRing Word16--instance CRing Word32--instance CRing Word64---- | StarSemiring------ > star a = one + a `times` star a----class (Semiring a) => StarSemiring a where- star :: a -> a- star a = one + plus' a-- plus' :: a -> a- plus' a = a `times` star a---- | KleeneAlgebra------ > a `times` x + x = a ==> star a `times` x + x = x--- > x `times` a + x = a ==> x `times` star a + x = x----class (StarSemiring a, AdditiveIdempotent a) => KleeneAlgebra a---- | Involutive Ring------ > adj (a + b) ==> adj a + adj b--- > adj (a * b) ==> adj a * adj b--- > adj one ==> one--- > adj (adj a) ==> a------ Note: elements for which @adj a == a@ are called "self-adjoint".----class Semiring a => InvolutiveRing a where- adj :: a -> a- adj x = x--instance InvolutiveRing Double--instance InvolutiveRing Float--instance InvolutiveRing Integer--instance InvolutiveRing Int--instance (Ring a) => InvolutiveRing (Complex a) where- adj (a :+ b) = a :+ negate b--instance InvolutiveRing Natural--instance InvolutiveRing Int8--instance InvolutiveRing Int16--instance InvolutiveRing Int32--instance InvolutiveRing Int64--instance InvolutiveRing Word--instance InvolutiveRing Word8--instance InvolutiveRing Word16--instance InvolutiveRing Word32--instance InvolutiveRing Word64-
− src/NumHask/Algebra/Singleton.hs
@@ -1,23 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -Wall #-}---- | Homomorphic operation from element to structured number-module NumHask.Algebra.Singleton- ( Singleton(..)- ) where---- | This class could also be called replicate. Looking forward, however, it may be useful to consider a Representable such as------ > VectorThing a = Vector a | Single a | Zero------ and then------ > singleton a = Single a--- > singleton zero = Zero------ short-circuiting an expensive computation. As the class action then doesn't actually involve replication, it would be mis-named.----class Singleton f where- singleton :: a -> f a-
+ src/NumHask/Analysis/Banach.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}++-- | Metric classes+module NumHask.Analysis.Banach+ ( Banach(..)+ , Hilbert(..)+ )+where++import NumHask.Algebra.Abstract.Action+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Field+import NumHask.Analysis.Metric++-- | Banach (with Norm) laws form rules around size and direction of a number, with a potential crossing into another codomain.+--+-- > a == singleton zero || normalizeL2 a *. normL2 a == a+class (ExpField (Actor h), Normed h (Actor h), DivisiveAction h) =>+ Banach h where+ normalizeL1 :: h -> h+ normalizeL1 a = a ./ normL1 a ++ normalizeL2 :: h -> h+ normalizeL2 a = a ./ normL2 a++-- | the inner product: a distributive fold+--+-- > a <.> b == b <.> a+-- > a <.> (b +c) == a <.> b + a <.> c+-- > a <.> (s *. b + c) == s * (a <.> b) + a <.> c+-- (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)+class (Distributive (Actor h)) =>+ Hilbert h where+ infix 8 <.>+ (<.>) :: h -> h -> Actor h
+ src/NumHask/Analysis/Metric.hs view
@@ -0,0 +1,312 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}++-- | Metric classes+module NumHask.Analysis.Metric+ ( Signed(..)+ , Normed(..)+ , Metric(..)+ , Epsilon(..)+ , (~=)+ )+where++import qualified Prelude as P+import Prelude+ hiding ( Bounded(..)+ , Integral(..)+ , (-)+ , negate+ )++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Lattice++-- | 'signum' from base is not an operator replicated in numhask, being such a very silly name, and preferred is the much more obvious 'sign'. Compare with 'Norm' and 'Banach' where there is a change in codomain+--+-- > abs a * sign a == a+--+-- Generalising this class tends towards size and direction (abs is the size on the one-dim number line of a vector with its tail at zero, and sign is the direction, right?).+class (Multiplicative a) =>+ Signed a where+ sign :: a -> a+ abs :: a -> a++instance Signed Double where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Float where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Int where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Integer where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Natural where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = id++instance Signed Int8 where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Int16 where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Int32 where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Int64 where+ sign a+ | a == zero = zero+ | a > zero = one+ | otherwise = negate one+ abs = P.abs++instance Signed Word where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = P.abs++instance Signed Word8 where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = P.abs++instance Signed Word16 where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = P.abs++instance Signed Word32 where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = P.abs++instance Signed Word64 where+ sign a+ | a == zero = zero+ | otherwise = one+ abs = P.abs++-- | L1 and L2 norms are provided for potential speedups, as well as the generalized p-norm.+--+-- for p >= 1+--+-- > normLp p a >= zero+-- > normLp p zero == zero+--+-- Note that the Normed codomain can be different to the domain.+--+class (Additive a, Additive b) => Normed a b where+ normL1 :: a -> b+ normL2 :: a -> b++instance Normed Double Double where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Float Float where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Int Int where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Integer Integer where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Natural Natural where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Int8 Int8 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Int16 Int16 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Int32 Int32 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Int64 Int64 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Word Word where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Word8 Word8 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Word16 Word16 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Word32 Word32 where+ normL1 = P.abs+ normL2 = P.abs++instance Normed Word64 Word64 where+ normL1 = P.abs+ normL2 = P.abs++-- | distance between numbers using L1, L2 or Lp-norms+--+-- > distanceL2 a b >= zero+-- > distanceL2 a a == zero+-- > \a b c -> distanceL2 a c + distanceL2 b c - distanceL2 a b >= zero &&+-- > distanceL2 a b + distanceL2 b c - distanceL2 a c >= zero &&+-- > distanceL2 a b + distanceL2 a c - distanceL2 b c >= zero &&+class Metric a b where+ distanceL1 :: a -> a -> b+ distanceL2 :: a -> a -> b++instance Metric Double Double where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Float Float where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Int Int where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Integer Integer where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Natural Natural where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++instance Metric Int8 Int8 where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Int16 Int16 where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Int32 Int32 where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance Metric Int64 Int64 where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++-- fixme: circular distance may be more appropriate+instance Metric Word Word where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++instance Metric Word8 Word8 where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++instance Metric Word16 Word16 where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++instance Metric Word32 Word32 where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++instance Metric Word64 Word64 where+ distanceL1 a b = P.fromInteger $ normL1 (P.toInteger a - P.toInteger b)+ distanceL2 a b = P.fromInteger $ normL2 (P.toInteger a - P.toInteger b)++class (Eq a, Additive a, Subtractive a, MeetSemiLattice a) =>+ Epsilon a where++ epsilon :: a+ epsilon = zero++ nearZero :: a -> Bool+ nearZero a = a `meetLeq` epsilon && negate a `meetLeq` epsilon++ aboutEqual :: a -> a -> Bool+ aboutEqual a b = nearZero $ a - b++infixl 4 ~=++(~=) :: (Epsilon a) => a -> a -> Bool+(~=) = aboutEqual++instance Epsilon Double where+ epsilon = 1e-14++instance Epsilon Float where+ epsilon = 1e-6++instance Epsilon Int++instance Epsilon Integer++instance Epsilon Int8++instance Epsilon Int16++instance Epsilon Int32++instance Epsilon Int64++instance Epsilon Word++instance Epsilon Word8++instance Epsilon Word16++instance Epsilon Word32++instance Epsilon Word64
− src/NumHask/Data.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveFunctor, GeneralizedNewtypeDeriving #-}-module NumHask.Data where--import Data.Coerce (coerce)-import GHC.Generics-import NumHask.Algebra-import Prelude hiding (Num(..), sum, recip)--#if !MIN_VERSION_base(4,11,0)-import Data.Semigroup ((<>), Semigroup)-#endif---- | Monoid under addition.------ >>> getSum (Sum 1 <> Sum 2 <> mempty)--- 3-newtype Sum a = Sum { getSum :: a }- deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Functor)---- | @since 4.8.0.0-instance Applicative Sum where- pure = Sum- (<*>) = coerce ---- | @since 4.8.0.0-instance Monad Sum where- m >>= k = k (getSum m)--instance AdditiveMagma a => AdditiveMagma (Sum a) where- (Sum x) `plus` (Sum y) = Sum (x `plus` y)--instance AdditiveUnital a => AdditiveUnital (Sum a) where- zero = Sum zero--instance AdditiveMagma a => AdditiveAssociative (Sum a)--instance AdditiveInvertible a => AdditiveInvertible (Sum a) where- negate (Sum x) = Sum (negate x)--instance AdditiveMagma a => AdditiveCommutative (Sum a) where--instance (AdditiveUnital a, AdditiveMagma a) => Additive (Sum a) where --instance (AdditiveInvertible a, AdditiveUnital a) => AdditiveGroup (Sum a) where---instance AdditiveMagma a => Semigroup (Sum a) where- (Sum x) <> (Sum y) = Sum $ x `plus` y--instance AdditiveUnital a => Monoid (Sum a) where- mempty = Sum zero------- | Monoid under multiplication.------ >>> getProduct (Product 3 <> Product 4 <> mempty)--- 12-newtype Product a = Product { getProduct :: a }- deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Functor)---- | @since 4.8.0.0-instance Applicative Product where- pure = Product- (<*>) = coerce---- | @since 4.8.0.0-instance Monad Product where- m >>= k = k (getProduct m)---instance MultiplicativeMagma a => MultiplicativeMagma (Product a) where- (Product x) `times` (Product y) = Product (x `times` y)--instance MultiplicativeUnital a => MultiplicativeUnital (Product a) where- one = Product one--instance MultiplicativeMagma a => MultiplicativeAssociative (Product a) --instance MultiplicativeInvertible a => MultiplicativeInvertible (Product a) where- recip (Product x) = Product (recip x)--instance MultiplicativeMagma a => MultiplicativeCommutative (Product a)--instance MultiplicativeUnital a => Multiplicative (Product a) where--instance (MultiplicativeUnital a, MultiplicativeInvertible a) => MultiplicativeGroup (Product a) where---instance MultiplicativeMagma a => Semigroup (Product a) where- (Product x) <> (Product y) = Product $ x `times` y--instance MultiplicativeUnital a => Monoid (Product a) where- mempty = Product one
src/NumHask/Data/Complex.hs view
@@ -1,24 +1,31 @@-{-# LANGUAGE DeriveGeneric, DeriveDataTypeable, DeriveFunctor, GeneralizedNewtypeDeriving, DeriveFoldable, DeriveTraversable #-}-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}+ module NumHask.Data.Complex where -import GHC.Generics (Generic, Generic1) import Data.Data (Data)--import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Ring-import NumHask.Algebra.Distribution-import NumHask.Algebra.Field-import NumHask.Algebra.Metric+import GHC.Generics (Generic, Generic1)+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Lattice+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Analysis.Metric+import NumHask.Data.Integral -import Prelude hiding (Num(..), negate, sin, cos, sqrt, (/), atan, pi, exp, log, recip, (**))-import qualified Prelude as P ( (&&), (>), (<=), (<), (==), otherwise, Ord(..) )+import Prelude+ hiding (Num(..), (**), (/), atan, cos, exp, log, negate, pi, recip, sin, sqrt, isNaN)+import qualified Prelude as P (Ord(..), (&&), (<), (<=), (==), (>), otherwise) -- ----------------------------------------------------------------------------- -- The Complex type--infix 6 :++infix 6 :+ -- | Complex numbers are an algebraic type. --@@ -27,100 +34,75 @@ -- has the phase of @z@, but unit magnitude. -- -- The 'Foldable' and 'Traversable' instances traverse the real part first.-data Complex a- = !a :+ !a -- ^ forms a complex number from its real and imaginary+data Complex a =+ !a :+ !a -- ^ forms a complex number from its real and imaginary -- rectangular components.- deriving (Eq, Show, Read, Data, Generic, Generic1- , Functor, Foldable, Traversable)+ deriving ( Eq+ , Show+ , Read+ , Data+ , Generic+ , Generic1+ , Functor+ , Foldable+ , Traversable+ ) -- | Extracts the real part of a complex number. realPart :: Complex a -> a-realPart (x :+ _) = x+realPart (x :+ _) = x -- | Extracts the imaginary part of a complex number. imagPart :: Complex a -> a-imagPart (_ :+ y) = y-----instance (AdditiveMagma a) => AdditiveMagma (Complex a) where- (rx :+ ix) `plus` (ry :+ iy) = (rx `plus` ry) :+ (ix `plus` iy)--instance (AdditiveUnital a) => AdditiveUnital (Complex a) where- zero = zero :+ zero --instance (AdditiveAssociative a) => AdditiveAssociative (Complex a)--instance (AdditiveCommutative a) => AdditiveCommutative (Complex a)+imagPart (_ :+ y) = y -instance (Additive a) => Additive (Complex a)+instance (Additive a) => Additive (Complex a) where+ (rx :+ ix) + (ry :+ iy) = (rx + ry) :+ (ix + iy)+ zero = zero :+ zero -instance (AdditiveInvertible a) => AdditiveInvertible (Complex a) where+instance (Subtractive a) => Subtractive (Complex a) where negate (rx :+ ix) = negate rx :+ negate ix -instance (AdditiveGroup a) => AdditiveGroup (Complex a)---instance (Distribution a, AdditiveGroup a) => Distribution (Complex a)-+instance (Distributive a, Subtractive a) =>+ Distributive (Complex a) -instance (AdditiveUnital a, AdditiveGroup a, MultiplicativeUnital a) => MultiplicativeUnital (Complex a) where+instance (Subtractive a, Multiplicative a) =>+ Multiplicative (Complex a) where+ (rx :+ ix) * (ry :+ iy) =+ (rx * ry - ix * iy) :+ (ix * ry + iy * rx) one = one :+ zero -instance (MultiplicativeMagma a, AdditiveGroup a) => MultiplicativeMagma (Complex a) where- (rx :+ ix) `times` (ry :+ iy) =- (rx `times` ry - ix `times` iy) :+ (ix `times` ry + iy `times` rx)--instance (MultiplicativeMagma a, AdditiveGroup a) => MultiplicativeCommutative (Complex a)--instance (MultiplicativeUnital a, MultiplicativeAssociative a, AdditiveGroup a) => Multiplicative (Complex a)---instance (AdditiveGroup a, MultiplicativeInvertible a) => MultiplicativeInvertible (Complex a) where- recip (rx :+ ix) = (rx `times` d) :+ (negate ix `times` d)+instance (Subtractive a, Divisive a) =>+ Divisive (Complex a) where+ recip (rx :+ ix) = (rx * d) :+ (negate ix * d) where- d = recip ((rx `times` rx) `plus` (ix `times` ix))----instance (MultiplicativeUnital a, MultiplicativeAssociative a, MultiplicativeInvertible a, AdditiveGroup a) => MultiplicativeGroup (Complex a) -----instance (AdditiveGroup a, MultiplicativeAssociative a) =>- MultiplicativeAssociative (Complex a)---instance (Semiring a, AdditiveGroup a) => Semiring (Complex a)--instance (Semiring a, AdditiveGroup a) => Ring (Complex a)--instance (Semiring a, AdditiveGroup a) => InvolutiveRing (Complex a)--instance (MultiplicativeAssociative a, MultiplicativeUnital a, AdditiveGroup a, Semiring a) =>- CRing (Complex a)--instance (MultiplicativeGroup a, AdditiveGroup a, Semiring a) => Field (Complex a) + d = recip ((rx * rx) + (ix * ix)) +instance (Additive a, FromInteger a) =>+ FromInteger (Complex a) where+ fromInteger x = fromInteger x :+ zero instance (Multiplicative a, ExpField a, Normed a a) =>- Normed (Complex a) a where+ Normed (Complex a) a where normL1 (rx :+ ix) = normL1 rx + normL1 ix normL2 (rx :+ ix) = sqrt (rx * rx + ix * ix)- normLp p (rx :+ ix) = (normL1 rx ** p + normL1 ix ** p) ** (one / p) -instance (Multiplicative a, ExpField a, Normed a a) => Metric (Complex a) a where+instance (Multiplicative a, Subtractive a, ExpField a, Normed a a) =>+ Metric (Complex a) a where distanceL1 a b = normL1 (a - b) distanceL2 a b = normL2 (a - b)- distanceLp p a b = normLp p (a - b) +instance (Ord a, Signed a, Subtractive a, Epsilon a)+ => Epsilon (Complex a) where+ epsilon = epsilon :+ epsilon+ nearZero (a :+ b) = nearZero a && nearZero b +instance (IntegralDomain a, Subtractive a) => IntegralDomain (Complex a) --- | todo: bottom is here somewhere???-instance (P.Ord a, TrigField a, ExpField a) => ExpField (Complex a) where- exp (rx :+ ix) = exp rx * cos ix :+ exp rx * sin ix+instance (Field a, Subtractive a) => Field (Complex a)++instance (Ord a, TrigField a, ExpField a, Subtractive a) => ExpField (Complex a) where+ exp (rx :+ ix) = (exp rx * cos ix) :+ (exp rx * sin ix) log (rx :+ ix) = log (sqrt (rx * rx + ix * ix)) :+ atan2' ix rx where atan2' y x@@ -133,42 +115,62 @@ | x P.== zero P.&& y P.== zero = y -- must be after the other double zero tests | P.otherwise = x + y -- x or y is a NaN, return a NaN (via +) +instance (Distributive a, Subtractive a) => InvolutiveRing (Complex a) where+ adj (a :+ b) = a :+ negate b +instance (UpperBoundedField a, IntegralDomain a, Subtractive a) => UpperBoundedField (Complex a) where+ isNaN (a :+ b) = isNaN a || isNaN b +instance (LowerBoundedField a) => LowerBoundedField (Complex a) +instance (JoinSemiLattice a) => JoinSemiLattice (Complex a) where+ (\/) (ar :+ ai) (br :+ bi) = (ar \/ br) :+ (ai \/ bi) +instance (MeetSemiLattice a) => MeetSemiLattice (Complex a) where+ (/\) (ar :+ ai) (br :+ bi) = (ar /\ br) :+ (ai /\ bi) --- * Helpers from Data.Complex +instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (Complex a) where+ bottom = bottom :+ bottom -mkPolar :: TrigField a => a -> a -> Complex a-mkPolar r theta = r * cos theta :+ r * sin theta+instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (Complex a) where+ top = top :+ top +-- * Helpers from Data.Complex+mkPolar :: TrigField a => a -> a -> Complex a+mkPolar r theta = (r * cos theta) :+ (r * sin theta) -- | @'cis' t@ is a complex value with magnitude @1@ -- and phase @t@ (modulo @2*'pi'@). {-# SPECIALISE cis :: Double -> Complex Double #-}-cis :: TrigField a => a -> Complex a-cis theta = cos theta :+ sin theta +cis :: TrigField a => a -> Complex a+cis theta = cos theta :+ sin theta+ -- | The function 'polar' takes a complex number and -- returns a (magnitude, phase) pair in canonical form: -- the magnitude is nonnegative, and the phase in the range @(-'pi', 'pi']@; -- if the magnitude is zero, then so is the phase.-{-# SPECIALISE polar :: Complex Double -> (Double,Double) #-}-polar :: (RealFloat a, ExpField a) => Complex a -> (a,a)-polar z = (magnitude z, phase z)+{-# SPECIALISE polar :: Complex Double -> (Double, Double) #-} +polar :: (RealFloat a, ExpField a) => Complex a -> (a, a)+polar z = (magnitude z, phase z)+ -- | The nonnegative magnitude of a complex number. {-# SPECIALISE magnitude :: Complex Double -> Double #-}+ magnitude :: (ExpField a, RealFloat a) => Complex a -> a-magnitude (x :+ y) = scaleFloat k (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y)))- where k = max (exponent x) (exponent y)- mk = - k- sqr z = z * z+magnitude (x :+ y) = scaleFloat+ k+ (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y)))+ where+ k = max (exponent x) (exponent y)+ mk = -k+ sqr z = z * z -- | The phase of a complex number, in the range @(-'pi', 'pi']@. -- If the magnitude is zero, then so is the phase. {-# SPECIALISE phase :: Complex Double -> Double #-}+ phase :: (RealFloat a) => Complex a -> a-phase (0 :+ 0) = 0 -- SLPJ July 97 from John Peterson-phase (x :+ y) = atan2 y x+phase (0 :+ 0) = 0 -- SLPJ July 97 from John Peterson+phase (x :+ y) = atan2 y x
+ src/NumHask/Data/Integral.hs view
@@ -0,0 +1,233 @@+{-# OPTIONS_GHC -Wall #-}++-- | Integral classes+module NumHask.Data.Integral+ ( Integral(..)+ , ToInteger(..)+ , FromInteger(..)+ , fromIntegral+ , even+ , odd+ , (^)+ , (^^)+ )+where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import GHC.Natural (Natural(..))+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import Prelude (Double, Float, Int, Integer, (.), fst, snd)+import qualified Prelude as P++-- | Integral laws+--+-- > b == zero || b * (a `div` b) + (a `mod` b) == a+class (Distributive a) =>+ Integral a where+ infixl 7 `div`, `mod`+ div :: a -> a -> a+ div a1 a2 = fst (divMod a1 a2)+ mod :: a -> a -> a+ mod a1 a2 = snd (divMod a1 a2)++ divMod :: a -> a -> (a, a)++ quot :: a -> a -> a+ quot a1 a2 = fst (quotRem a1 a2)+ rem :: a -> a -> a+ rem a1 a2 = snd (quotRem a1 a2)++ quotRem :: a -> a -> (a, a)++instance Integral Int where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Integer where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Natural where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Int8 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Int16 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Int32 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Int64 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Word where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Word8 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Word16 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Word32 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral Word64 where+ divMod = P.divMod+ quotRem = P.quotRem++instance Integral b => Integral (a -> b) where+ div f f' a = f a `div` f' a+ mod f f' a = f a `mod` f' a+ divMod f f' = (\a -> fst (f a `divMod` f' a), \a -> snd (f a `divMod` f' a))+ quot f f' a = f a `mod` f' a+ rem f f' a = f a `mod` f' a+ quotRem f f' = (\a -> fst (f a `quotRem` f' a), \a -> snd (f a `quotRem` f' a))++-- | toInteger is kept separate from Integral to help with compatability issues.+class ToInteger a where+ toInteger :: a -> Integer++instance ToInteger Int where+ toInteger = P.toInteger++instance ToInteger Integer where+ toInteger = P.toInteger++instance ToInteger Natural where+ toInteger = P.toInteger++instance ToInteger Int8 where+ toInteger = P.toInteger++instance ToInteger Int16 where+ toInteger = P.toInteger++instance ToInteger Int32 where+ toInteger = P.toInteger++instance ToInteger Int64 where+ toInteger = P.toInteger++instance ToInteger Word where+ toInteger = P.toInteger++instance ToInteger Word8 where+ toInteger = P.toInteger++instance ToInteger Word16 where+ toInteger = P.toInteger++instance ToInteger Word32 where+ toInteger = P.toInteger++instance ToInteger Word64 where+ toInteger = P.toInteger++-- | fromInteger is the most problematic of the 'Num' class operators. Particularly heinous, it is assumed that any number type can be constructed from an Integer, so that the broad classes of objects that are composed of multiple elements is avoided in haskell.+class FromInteger a where+ fromInteger :: Integer -> a++instance FromInteger b => FromInteger (a -> b) where+ fromInteger i _ = fromInteger i++-- | coercion of 'Integral's+--+-- > fromIntegral a == a+fromIntegral :: (ToInteger a, FromInteger b) => a -> b+fromIntegral = fromInteger . toInteger++instance FromInteger Double where+ fromInteger = P.fromInteger++instance FromInteger Float where+ fromInteger = P.fromInteger++instance FromInteger Int where+ fromInteger = P.fromInteger++instance FromInteger Integer where+ fromInteger = P.fromInteger++instance FromInteger Natural where+ fromInteger = P.fromInteger++instance FromInteger Int8 where+ fromInteger = P.fromInteger++instance FromInteger Int16 where+ fromInteger = P.fromInteger++instance FromInteger Int32 where+ fromInteger = P.fromInteger++instance FromInteger Int64 where+ fromInteger = P.fromInteger++instance FromInteger Word where+ fromInteger = P.fromInteger++instance FromInteger Word8 where+ fromInteger = P.fromInteger++instance FromInteger Word16 where+ fromInteger = P.fromInteger++instance FromInteger Word32 where+ fromInteger = P.fromInteger++instance FromInteger Word64 where+ fromInteger = P.fromInteger++-- $operators++even :: (P.Eq a, Integral a) => a -> P.Bool+even n = n `rem` (one + one) P.== zero++odd :: (P.Eq a, Integral a) => a -> P.Bool+odd = P.not . even++-------------------------------------------------------+-- | raise a number to a non-negative integral power+(^)+ :: (P.Ord b, Multiplicative a, Integral b)+ => a+ -> b+ -> a+x0 ^ y0+ | y0 P.< zero = P.undefined+ | -- P.errorWithoutStackTrace "Negative exponent"+ y0 P.== zero = one+ | P.otherwise = f x0 y0+ where++ -- f : x0 ^ y0 = x ^ y+ f x y+ | even y = f (x * x) (y `quot` two)+ | y P.== one = x+ | P.otherwise = g (x * x) (y `quot` two) x+ -- See Note [Half of y - 1]+ -- g : x0 ^ y0 = (x ^ y) * z+ g x y z+ | even y = g (x * x) (y `quot` two) z+ | y P.== one = x * z+ | P.otherwise = g (x * x) (y `quot` two) (x * z)+ -- See Note [Half of y - 1]++(^^)+ :: (Divisive a, Subtractive b, Integral b, P.Ord b) => a -> b -> a+(^^) x n = if n P.>= zero then x ^ n else recip (x ^ negate n)
src/NumHask/Data/LogField.hs view
@@ -1,48 +1,38 @@-{-# LANGUAGE DeriveGeneric, DeriveDataTypeable, DeriveFunctor, GeneralizedNewtypeDeriving, DeriveFoldable, DeriveTraversable, GADTs #-}-{-# LANGUAGE FlexibleInstances, FlexibleContexts, UndecidableInstances, MultiParamTypeClasses #-}-module NumHask.Data.LogField - (- -- * @LogField@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++module NumHask.Data.LogField+ ( -- * @LogField@ LogField()- -- ** Isomorphism to normal-domain- , logField- , fromLogField+ , logField+ , fromLogField -- ** Isomorphism to log-domain- , logToLogField- , logFromLogField+ , logToLogField+ , logFromLogField -- ** Additional operations- , accurateSum, accurateProduct- , pow- )where--import GHC.Generics ( Generic- , Generic1- )-import Data.Data ( Data )--import NumHask.Algebra.Additive-import NumHask.Algebra.Multiplicative-import NumHask.Algebra.Distribution-import NumHask.Algebra.Field-import NumHask.Algebra.Integral-import NumHask.Algebra.Rational-import NumHask.Algebra.Metric+ , accurateSum+ , accurateProduct+ , pow+ )+where -import Prelude hiding ( Num(..)- , negate- , sin- , cos- , sqrt- , (/)- , atan- , pi- , exp- , log- , recip- , (**)- , toInteger- )-import qualified Data.Foldable as F+import Data.Data (Data)+import GHC.Generics (Generic, Generic1)+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Lattice+import NumHask.Analysis.Metric+import NumHask.Data.Integral+import NumHask.Data.Rational+import Prelude hiding (Num(..), exp, log, negate, toInteger, isNaN)+import qualified Data.Foldable as F -- LogField is adapted from LogFloat ----------------------------------------------------------------@@ -56,7 +46,6 @@ -- Portability : portable (with CPP, FFI) -- Link : https://hackage.haskell.org/package/logfloat ----------------------------------------------------------------- ---------------------------------------------------------------- -- -- | A @LogField@ is just a 'Field' with a special interpretation.@@ -98,8 +87,18 @@ -- -- [1] That is, true up-to underflow and floating point fuzziness. -- Which is, of course, the whole point of this module.-newtype LogField a = LogField a- deriving (Eq, Ord, Read, Data, Generic, Generic1, Functor, Foldable, Traversable)+newtype LogField a =+ LogField a+ deriving ( Eq+ , Ord+ , Read+ , Data+ , Generic+ , Generic1+ , Functor+ , Foldable+ , Traversable+ ) ---------------------------------------------------------------- -- To show it, we want to show the normal-domain value rather than@@ -110,14 +109,10 @@ -- underflow\/overflow in the same places as normal doubles since -- we underflow at the @exp@. Perhaps this means we should show the -- log-domain value instead.- instance (ExpField a, Show a) => Show (LogField a) where- showsPrec p (LogField x) =- let y = exp x in y `seq`- showParen (p > 9)- ( showString "LogField "- . showsPrec 11 y- )+ showsPrec p (LogField x) =+ let y = exp x+ in y `seq` showParen (p > 9) (showString "LogField " . showsPrec 11 y) ---------------------------------------------------------------- -- | Constructor which does semantic conversion from normal-domain@@ -129,14 +124,12 @@ {-# INLINE [0] logField #-} logField = LogField . log - -- TODO: figure out what to do here, removed guards -- | Constructor which assumes the argument is already in the -- log-domain. logToLogField :: a -> LogField a logToLogField = LogField - -- | Semantically convert our log-domain value back into the -- normal-domain. Beware of overflow\/underflow. The following -- equivalence holds (without qualification):@@ -147,125 +140,116 @@ {-# INLINE [0] fromLogField #-} fromLogField (LogField x) = exp x - -- | Return the log-domain value itself without conversion. logFromLogField :: LogField a -> a logFromLogField (LogField x) = x - -- These are our module-specific versions of "log\/exp" and "exp\/log"; -- They do the same things but also have a @LogField@ in between -- the logarithm and exponentiation. In order to ensure these rules -- fire, we have to delay the inlining on two of the four -- con-\/destructors.- {-# RULES--- Out of log-domain and back in-"log/fromLogField" forall x. log (fromLogField x) = logFromLogField x--- TODO: Rewrite-rule too complicated-"LogField/fromLogField" forall x. LogField (fromLogField x) = x---- Into log-domain and back out-"fromLogField/LogField" forall x. fromLogField (LogField x) = x- #-}-+"log/fromLogField" forall x . log (fromLogField x) =+ logFromLogField x+"fromLogField/LogField" forall x . fromLogField (LogField x) = x+ #-} log1p :: ExpField a => a -> a {-# INLINE [0] log1p #-} log1p x = log (one + x) -expm1 :: ExpField a => a -> a+expm1 :: (ExpField a, Subtractive a) => a -> a {-# INLINE [0] expm1 #-} expm1 x = exp x - one {-# RULES--- Into log-domain and back out-"expm1/log1p" forall x. expm1 (log1p x) = x+"expm1/log1p" forall x . expm1 (log1p x) = x+"log1p/expm1" forall x . log1p (expm1 x) = x+ #-} --- Out of log-domain and back in-"log1p/expm1" forall x. log1p (expm1 x) = x- #-}+instance (ExpField a, LowerBoundedField a, Ord a) =>+ Additive (LogField a) where+ x@(LogField x') + y@(LogField y')+ | x == zero && y == zero = zero+ | x == zero = y+ | y == zero = x+ | x >= y = LogField (x' + log1p (exp (y' - x')))+ | otherwise = LogField (y' + log1p (exp (x' - y'))) -instance (ExpField a, LowerBoundedField a, Ord a) => AdditiveMagma (LogField a) where- x@(LogField x') `plus` y@(LogField y')- | x == zero && y == zero = zero- | x == zero = y- | y == zero = x- | x >= y = LogField (x' + log1p (exp (y' - x')))- | otherwise = LogField (y' + log1p (exp (x' - y')))+ zero = LogField negInfinity -instance (LowerBoundedField a, ExpField a, Ord a) => AdditiveUnital (LogField a) where- zero = LogField negInfinity+instance (ExpField a, Ord a, LowerBoundedField a, UpperBoundedField a) =>+ Subtractive (LogField a) where+ negate x+ | x == zero = zero+ | otherwise = nan -instance (LowerBoundedField a, ExpField a, Ord a) => AdditiveAssociative (LogField a)+instance (LowerBoundedField a, Eq a) =>+ Multiplicative (LogField a) where+ (LogField x) * (LogField y)+ | x == negInfinity || y == negInfinity = LogField negInfinity+ | otherwise = LogField (x + y) -instance (LowerBoundedField a,ExpField a, Ord a) => AdditiveCommutative (LogField a)+ one = LogField zero -instance (LowerBoundedField a, ExpField a, Ord a) => Additive (LogField a)+instance (LowerBoundedField a, Eq a) =>+ Divisive (LogField a) where+ recip (LogField x) = LogField $ negate x -instance (AdditiveMagma a, LowerBoundedField a, Eq a) => MultiplicativeMagma (LogField a) where- (LogField x) `times ` (LogField y)- | x == negInfinity || y == negInfinity = LogField negInfinity- | otherwise = LogField (x `plus` y)+instance (Ord a, LowerBoundedField a, ExpField a) =>+ Distributive (LogField a) -instance (AdditiveUnital a, LowerBoundedField a, Eq a) => MultiplicativeUnital (LogField a) where- one = LogField zero+instance (Field (LogField a), ExpField a, LowerBoundedField a, Ord a) => ExpField (LogField a) where+ exp (LogField x) = LogField $ exp x+ log (LogField x) = LogField $ log x+ (**) x (LogField y) = pow x $ exp y -instance (AdditiveAssociative a, LowerBoundedField a, Eq a) => MultiplicativeAssociative (LogField a)+instance (FromInteger a, ExpField a) => FromInteger (LogField a) where+ fromInteger = logField . fromInteger -instance (AdditiveCommutative a, LowerBoundedField a, Eq a) => MultiplicativeCommutative (LogField a)+instance (ToInteger a, ExpField a) => ToInteger (LogField a) where+ toInteger = toInteger . fromLogField -instance (AdditiveInvertible a, LowerBoundedField a, Eq a) => MultiplicativeInvertible (LogField a) where- recip (LogField x) = LogField $ negate x+instance (FromRatio a, ExpField a) => FromRatio (LogField a) where+ fromRatio = logField . fromRatio -instance (AdditiveUnital a- , AdditiveAssociative a- , AdditiveCommutative a- , Additive a- , LowerBoundedField a- , Eq a) => Multiplicative (LogField a)+instance (ToRatio a, ExpField a) => ToRatio (LogField a) where+ toRatio = toRatio . fromLogField -instance (AdditiveUnital a- , AdditiveAssociative a- , AdditiveInvertible a- , AdditiveLeftCancellative a- , LowerBoundedField a- , Eq a) => MultiplicativeLeftCancellative (LogField a)+instance (Ord a) => JoinSemiLattice (LogField a) where+ (\/) = min -instance (AdditiveUnital a- , AdditiveAssociative a- , AdditiveInvertible a- , AdditiveRightCancellative a- , LowerBoundedField a- , Eq a) => MultiplicativeRightCancellative (LogField a)+instance (Ord a) => MeetSemiLattice (LogField a) where+ (/\) = max -instance (Multiplicative (LogField a), AdditiveInvertible a, AdditiveGroup a, LowerBoundedField a, Eq a) => MultiplicativeGroup (LogField a)+instance (Epsilon a, ExpField a, LowerBoundedField a, UpperBoundedField a, Ord a) =>+ Epsilon (LogField a) where+ epsilon = logField epsilon+ nearZero (LogField x) = nearZero $ exp x+ aboutEqual (LogField x) (LogField y) = aboutEqual (exp x) (exp y) -instance (LowerBoundedField a, ExpField a, Ord a, AdditiveMagma a) => Distribution (LogField a)+instance (Ord a, ExpField a, LowerBoundedField a) => Field (LogField a) --- unable to provide this instance because there is no Field (LogField a) instance--- instance (Field (LogField a), ExpField a, LowerBoundedField a, Ord a) => ExpField (LogField a) where--- exp (LogField x) = (LogField $ exp x)--- log (LogField x) = (LogField $ log x)--- (**) x (LogField y) = pow x $ exp y+instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>+ LowerBoundedField (LogField a) -instance (FromInteger a, ExpField a) => FromInteger (LogField a) where- fromInteger = logField . fromInteger+instance (Ord a, ExpField a, LowerBoundedField a) =>+ IntegralDomain (LogField a) where -instance (ToInteger a, ExpField a) => ToInteger (LogField a) where- toInteger = toInteger . fromLogField+instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>+ UpperBoundedField (LogField a) where+ isNaN (LogField a) = isNaN a -instance (FromRatio a, ExpField a) => FromRatio (LogField a) where- fromRatio = logField . fromRatio+instance (Ord a, LowerBoundedField a, UpperBoundedField a, ExpField a) =>+ Signed (LogField a) where+ sign a+ | a == negInfinity = zero+ | otherwise = one+ abs = id -instance (ToRatio a, ExpField a) => ToRatio (LogField a) where- toRatio = toRatio . fromLogField -instance (Epsilon a, ExpField a, LowerBoundedField a, Ord a) => Epsilon (LogField a) where- nearZero (LogField x) = nearZero $ exp x- aboutEqual (LogField x) (LogField y) = aboutEqual (exp x) (exp y) - ---------------------------------------------------------------- -- | /O(1)/. Compute powers in the log-domain; that is, the following -- equivalence holds (modulo underflow and all that):@@ -276,11 +260,11 @@ pow :: (ExpField a, LowerBoundedField a, Ord a) => LogField a -> a -> LogField a {-# INLINE pow #-} infixr 8 `pow`-pow x@(LogField x') m - | x == zero && m == zero = LogField zero- | x == zero = x- | otherwise = LogField $ m * x' +pow x@(LogField x') m+ | x == zero && m == zero = LogField zero+ | x == zero = x+ | otherwise = LogField $ m * x' -- Some good test cases: -- for @logsumexp == log . accurateSum . map exp@:@@ -299,13 +283,12 @@ -- it is not amenable to list fusion, and hence will use a lot of -- memory when summing long lists. {-# INLINE accurateSum #-}-accurateSum :: (ExpField a, Foldable f, Ord a) => f (LogField a) -> LogField a+accurateSum :: (ExpField a, Subtractive a, Foldable f, Ord a) => f (LogField a) -> LogField a accurateSum xs = LogField (theMax + log theSum)- where- LogField theMax = maximum xs-- -- compute @\log \sum_{x \in xs} \exp(x - theMax)@- theSum = F.foldl' (\acc (LogField x) -> acc + exp (x - theMax)) zero xs+ where+ LogField theMax = maximum xs+-- compute @\log \sum_{x \in xs} \exp(x - theMax)@+ theSum = F.foldl' (\acc (LogField x) -> acc + exp (x - theMax)) zero xs -- | /O(n)/. Compute the product of a finite list of 'LogField's, -- being careful to avoid numerical error due to loss of precision.@@ -314,15 +297,15 @@ -- -- > LogField . accurateProduct == accurateProduct . map LogField {-# INLINE accurateProduct #-}-accurateProduct :: (ExpField a, Foldable f) => f (LogField a) -> LogField a+accurateProduct :: (ExpField a, Subtractive a, Foldable f) => f (LogField a) -> LogField a accurateProduct = LogField . fst . F.foldr kahanPlus (zero, zero)- where- kahanPlus (LogField x) (t, c) =- let y = x - c- t' = t + y- c' = (t' - t) - y- in (t', c')-+ where+ kahanPlus (LogField x) (t, c) =+ let+ y = x - c+ t' = t + y+ c' = (t' - t) - y+ in (t', c') -- This version *completely* eliminates rounding errors and loss -- of significance due to catastrophic cancellation during summation. -- <http://code.activestate.com/recipes/393090/> Also see the other
+ src/NumHask/Data/Pair.hs view
@@ -0,0 +1,217 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall #-}++-- | A Pair is *the* classical higher-kinded number but there is no canon.+module NumHask.Data.Pair+ ( Pair(..)+ , pattern Pair+ ) where++import qualified Prelude as P+import Prelude (Foldable, Traversable, Applicative, Monad, Functor(..), Semigroup(..), Monoid(..), Bounded(..), Eq(..), (<$>), (<*>), (&&), (||))+import GHC.Generics (Generic)+import Data.Functor.Classes+import NumHask.Algebra.Abstract+import NumHask.Data.Integral+import NumHask.Analysis.Metric+import NumHask.Data.Rational+import Text.Show++-- $setup+-- >>> :set -XNoImplicitPrelude+-- >>> :set -XFlexibleContexts+--++-- | A pair of a's, implemented as a tuple, but api represented as a Pair of a's.+--+-- >>> fmap (+1) (Pair 1 2)+-- Pair 2 3+-- >>> pure one :: Pair Int+-- Pair 1 1+-- >>> (*) <$> Pair 1 2 <*> pure 2+-- Pair 2 4+-- >>> foldr (++) [] (Pair [1,2] [3])+-- [1,2,3]+-- >>> Pair "a" "pair" `mappend` pure " " `mappend` Pair "string" "mappended"+-- Pair "a string" "pair mappended"+--+-- As a Ring and Field class+-- +-- >>> Pair 0 1 + zero+-- Pair 0 1+-- >>> Pair 0 1 + Pair 2 3+-- Pair 2 4+-- >>> Pair 1 1 - one+-- Pair 0 0+-- >>> Pair 0 1 * one+-- Pair 0 1+-- >>> Pair 0.0 1.0 / one+-- Pair 0.0 1.0+-- >>> Pair 11 12 `mod` (pure 6)+-- Pair 5 0+--+-- As an action+--+-- >>> Pair 1 2 .+ 3+-- Pair 4 5+--+newtype Pair a =+ Pair' (a, a)+ deriving (Eq, Generic)++-- | the preferred pattern+pattern Pair :: a -> a -> Pair a+pattern Pair a b = Pair' (a,b)+{-# COMPLETE Pair#-}++instance (Show a) => Show (Pair a) where+ show (Pair a b) = "Pair " <> Text.Show.show a <> " " <> Text.Show.show b++instance Functor Pair where+ fmap f (Pair a b) = Pair (f a) (f b)++instance Eq1 Pair where+ liftEq f (Pair a b) (Pair c d) = f a c && f b d++instance Show1 Pair where+ liftShowsPrec sp _ d (Pair' (a, b)) = showsBinaryWith sp sp "Pair" d a b++instance Applicative Pair where+ pure a = Pair a a+ (Pair fa fb) <*> Pair a b = Pair (fa a) (fb b)++instance Monad Pair where+ Pair a b >>= f = Pair a' b'+ where+ Pair a' _ = f a+ Pair _ b' = f b++instance Foldable Pair where+ foldMap f (Pair a b) = f a `mappend` f b++instance Traversable Pair where+ traverse f (Pair a b) = Pair <$> f a <*> f b++instance (Semigroup a) => Semigroup (Pair a) where+ (Pair a0 b0) <> (Pair a1 b1) = Pair (a0 <> a1) (b0 <> b1)++instance (Semigroup a, Monoid a) => Monoid (Pair a) where+ mempty = Pair mempty mempty+ mappend = (<>)++instance (Bounded a) => Bounded (Pair a) where+ minBound = Pair minBound minBound+ maxBound = Pair maxBound maxBound++unaryOp :: (a -> a) -> (Pair a -> Pair a)+unaryOp f (Pair a b) = Pair (f a) (f b)++binOp :: (a -> a -> a) -> (Pair a -> Pair a -> Pair a)+binOp (#) (Pair a0 b0) (Pair a1 b1) = Pair (a0 # a1) (b0 # b1)++-- numeric heirarchy+instance (Additive a) => Additive (Pair a) where+ (Pair a0 b0) + (Pair a1 b1) = Pair (a0 + a1) (b0 + b1)+ zero = Pair zero zero++instance (Subtractive a) => Subtractive (Pair a) where+ negate = unaryOp negate++instance (Multiplicative a) => Multiplicative (Pair a) where+ (Pair a0 b0) * (Pair a1 b1) = Pair (a0 * a1) (b0 * b1)+ one = Pair one one++instance (Divisive a) => Divisive (Pair a) where+ recip = unaryOp recip++instance (Integral a) => Integral (Pair a) where+ (Pair a0 b0) `divMod` (Pair a1 b1) = (Pair da db, Pair ma mb)+ where+ (da, ma) = a0 `divMod` a1+ (db, mb) = b0 `divMod` b1+ (Pair a0 b0) `quotRem` (Pair a1 b1) = (Pair da db, Pair ma mb)+ where+ (da, ma) = a0 `quotRem` a1+ (db, mb) = b0 `quotRem` b1++instance (Signed a) => Signed (Pair a) where+ sign = unaryOp sign+ abs = unaryOp abs++instance (ExpField a, Normed a a) =>+ Normed (Pair a) a where+ normL1 (Pair a b) = normL1 a + normL1 b+ normL2 (Pair a b) = sqrt (a ** (one + one) + b ** (one + one))++instance (Subtractive a, Epsilon a) => Epsilon (Pair a) where+ epsilon = Pair epsilon epsilon+ nearZero (Pair a b) = nearZero a && nearZero b++instance (ExpField a, Subtractive a, Normed a a) => Metric (Pair a) a where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance (Distributive a) => Distributive (Pair a)++instance (Field a) => Field (Pair a)+instance (IntegralDomain a) => IntegralDomain (Pair a)++instance (ExpField a) => ExpField (Pair a) where+ exp = unaryOp exp+ log = unaryOp log++instance (UpperBoundedField a) => UpperBoundedField (Pair a)+ where+ isNaN (Pair a b) = isNaN a || isNaN b++instance (LowerBoundedField a) => LowerBoundedField (Pair a)++type instance Actor (Pair a) = a++instance (Additive a) => AdditiveAction (Pair a) where+ (.+) r s = fmap (s+) r+ (+.) s r = fmap (s+) r+instance (Subtractive a) => SubtractiveAction (Pair a) where+ (.-) r s = fmap (\x -> x - s) r+ (-.) s r = fmap (\x -> x - s) r+instance (Multiplicative a) => MultiplicativeAction (Pair a) where+ (.*) r s = fmap (s*) r+ (*.) s r = fmap (s*) r+instance (Divisive a) => DivisiveAction (Pair a) where+ (./) r s = fmap (/ s) r+ (/.) s r = fmap (/ s) r++instance (JoinSemiLattice a) => JoinSemiLattice (Pair a) where+ (\/) = binOp (\/)++instance (MeetSemiLattice a) => MeetSemiLattice (Pair a) where+ (/\) = binOp (/\)++instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (Pair a) where+ bottom = Pair bottom bottom++instance (BoundedMeetSemiLattice a) => BoundedMeetSemiLattice (Pair a) where+ top = Pair top top++instance (FromInteger a) => FromInteger (Pair a) where+ fromInteger x = P.pure (fromInteger x)++instance (FromRatio a) => FromRatio (Pair a) where+ fromRatio x = P.pure (fromRatio x)++instance (Normed a a) =>+ Normed (Pair a) (Pair a) where+ normL1 = fmap normL1+ normL2 = fmap normL2++instance (Subtractive a, Normed a a) =>+ Metric (Pair a) (Pair a) where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)
+ src/NumHask/Data/Positive.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RoleAnnotations #-}+{-# OPTIONS_GHC -Wall #-}++module NumHask.Data.Positive where++import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Lattice+import NumHask.Analysis.Metric+import NumHask.Data.Integral+import NumHask.Exception+import qualified Prelude as P++newtype Positive a = Positive { unPositive :: a }+ deriving+ ( P.Show+ , P.Eq+ , P.Ord+ , Additive+ , Multiplicative+ , Divisive+ , Distributive+ , IntegralDomain+ , Field+ , ExpField+ , TrigField+ , Integral+ , Signed+ , JoinSemiLattice+ , MeetSemiLattice+ , Epsilon+ )++-- not sure if this is correct or needed+type role Positive representational++positive :: (P.Ord a, Additive a) => a -> P.Maybe (Positive a)+positive a+ | a P.< zero = P.Nothing+ | P.otherwise = P.Just (Positive a)++positive_ :: (P.Ord a, Additive a) => a -> Positive a+positive_ a+ | a P.< zero = throw (NumHaskException "positive number less than zero")+ | P.otherwise = Positive a++instance (P.Ord a, Subtractive a) => Subtractive (Positive a) where+ negate (Positive a)+ | a P.== zero = Positive zero+ | P.otherwise = throw (NumHaskException "negating a positive number")++ (Positive a) - (Positive b)+ | a P.>= b = Positive (a - b)+ | P.otherwise = throw (NumHaskException "subtracting a larger positive")++instance (P.Ord a, QuotientField a P.Integer) =>+ QuotientField (Positive a) (Positive P.Integer) where+ properFraction (Positive a) = let (i,r) = properFraction a in (Positive i, Positive r)++instance (UpperBoundedField a) =>+ UpperBoundedField (Positive a) where+ infinity = Positive infinity+ isNaN (Positive a) = isNaN a++instance (UpperBoundedField a) => P.Bounded (Positive a) where+ minBound = zero+ maxBound = infinity++-- Metric+instance (Normed a a) =>+ Normed a (Positive a) where+ normL1 a = Positive (normL1 a)+ normL2 a = Positive (normL2 a)++instance (Subtractive a, Normed a a) => Metric a (Positive a) where+ distanceL1 a b = Positive P.$ normL1 (a - b)+ distanceL2 a b = Positive P.$ normL2 (a - b)
+ src/NumHask/Data/Rational.hs view
@@ -0,0 +1,232 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# OPTIONS_GHC -Wall #-}++-- | Integral classes+module NumHask.Data.Rational+ ( Ratio(..)+ , Rational+ , ToRatio(..)+ , FromRatio(..)+ , fromRational+ -- * $integral_functionality+ , reduce+ , gcd+ )+where++import Data.Int (Int8, Int16, Int32, Int64)+import Data.Word (Word, Word8, Word16, Word32, Word64)+import Data.Bool (bool)+import GHC.Float+import GHC.Natural (Natural(..))+import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Lattice+import NumHask.Analysis.Metric+import NumHask.Data.Integral+import Prelude (Double, Float, Int, Integer, (.))+import qualified GHC.Real+import qualified Prelude as P++data Ratio a = !a :% !a deriving (P.Show)++instance (P.Eq a, Additive a) => P.Eq (Ratio a) where+ a == b+ | isRNaN a P.|| isRNaN b = P.False+ | P.otherwise = (x P.== x') P.&& (y P.== y')+ where+ (x:%y) = a+ (x':%y') = b++isRNaN :: (P.Eq a, Additive a) => Ratio a -> P.Bool+isRNaN (x :% y)+ | x P.== zero P.&& y P.== zero = P.True+ | P.otherwise = P.False+++type Rational = Ratio Integer++instance (P.Ord a, Multiplicative a, Integral a) => P.Ord (Ratio a) where+ (x:%y) <= (x':%y') = x * y' P.<= x' * y+ (x:%y) < (x':%y') = x * y' P.< x' * y++-- | These common constraints over the Ratio instances are due to the gcd algorithm. Subtractive is somewhat problematic with obtaining a `Ratio (Positive Integer)` which should be made possible.+type GCDConstraints a = (P.Ord a, Signed a, Integral a, Subtractive a)++instance (GCDConstraints a) => Additive (Ratio a) where+ (x :% y) + (x' :% y')+ | y P.== zero P.&& y' P.== zero = bool one (negate one) (x + x' P.< zero) :% zero+ | y P.== zero = x :% y+ | y' P.== zero = x' :% y'+ | P.otherwise = reduce ((x * y') + (x' * y)) (y * y')++ zero = zero :% one++instance (GCDConstraints a) => Subtractive (Ratio a) where+ negate (x :% y) = negate x :% y++instance (GCDConstraints a) => Multiplicative (Ratio a) where+ (x:%y) * (x':%y') = reduce (x * x') (y * y')++ one = one :% one++instance (GCDConstraints a) =>+ Divisive (Ratio a) where+ recip (x :% y)+ | sign x P.== negate one = negate y :% negate x+ | P.otherwise = y :% x++instance (GCDConstraints a) => Distributive (Ratio a)++instance (GCDConstraints a) => IntegralDomain (Ratio a)++instance (GCDConstraints a) => Field (Ratio a)++instance (GCDConstraints a, GCDConstraints b, ToInteger a, Field a, FromInteger b) => QuotientField (Ratio a) b where+ properFraction (n :% d) = let (w,r) = quotRem n d in (fromIntegral w,r:%d)++instance (GCDConstraints a, Distributive a, IntegralDomain a) =>+ UpperBoundedField (Ratio a) where+ isNaN (a :% b) = (a P.== zero) P.&& (b P.== zero)++instance (GCDConstraints a, Field a) => LowerBoundedField (Ratio a)++instance (GCDConstraints a) => Signed (Ratio a) where+ sign (n :% _)+ | n P.== zero = zero+ | n P.> zero = one+ | P.otherwise = negate one+ abs (n :% d) = abs n :% abs d++instance (GCDConstraints a) => Normed (Ratio a) (Ratio a) where+ normL1 = abs+ normL2 = abs++instance (GCDConstraints a) => Metric (Ratio a) (Ratio a) where+ distanceL1 a b = normL1 (a - b)+ distanceL2 a b = normL2 (a - b)++instance (GCDConstraints a, MeetSemiLattice a) => Epsilon (Ratio a)++instance (FromInteger a, Multiplicative a) => FromInteger (Ratio a) where+ fromInteger x = fromInteger x :% one++-- | toRatio is equivalent to `Real` in base.+class ToRatio a where+ toRatio :: a -> Ratio Integer++instance (ToInteger a) => ToRatio (Ratio a) where+ toRatio (n :% d) = toInteger n :% toInteger d++-- | `Fractional` in base splits into fromRatio and Field+class FromRatio a where+ fromRatio :: Ratio Integer -> a++instance (FromInteger a) => FromRatio (Ratio a) where+ fromRatio (n :% d) = fromInteger n :% fromInteger d++-- | coercion of 'Rational's+--+-- > fromRational a == a+fromRational :: (ToRatio a, FromRatio b) => a -> b+fromRational = fromRatio . toRatio++-- | fixme: use coerce+fromBaseRational :: P.Rational -> Ratio Integer+fromBaseRational (n GHC.Real.:% d) = n :% d++instance FromRatio Double where+ fromRatio (n:%d)= rationalToDouble n d++instance FromRatio Float where+ fromRatio (n:%d)= rationalToFloat n d++instance ToRatio Double where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Float where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Int where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Integer where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Natural where+ toRatio = fromBaseRational . P.toRational++instance ToRatio P.Rational where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Int8 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Int16 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Int32 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Int64 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Word where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Word8 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Word16 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Word32 where+ toRatio = fromBaseRational . P.toRational++instance ToRatio Word64 where+ toRatio = fromBaseRational . P.toRational++instance (GCDConstraints a) => JoinSemiLattice (Ratio a) where+ (\/) = P.min++instance (GCDConstraints a) => MeetSemiLattice (Ratio a) where+ (/\) = P.max+++-- * $integral_functions+-- integral functionality is largely based on GHC.Real+--+-- | 'reduce' is a subsidiary function used only in this module.+-- It normalises a ratio by dividing both numerator and denominator by+-- their greatest common divisor.+reduce+ :: (P.Eq a, Subtractive a, Signed a, Integral a) => a -> a -> Ratio a+reduce x y+ | x P.== zero P.&& y P.== zero = zero :% zero+ | z P.== zero = one :% zero+ | P.otherwise = (x `quot` z) % (y `quot` z)+ where+ z = gcd x y+ n % d+ | sign d P.== negate one = negate n :% negate d+ | P.otherwise = n :% d++-- | @'gcd' x y@ is the non-negative factor of both @x@ and @y@ of which+-- every common factor of @x@ and @y@ is also a factor; for example+-- @'gcd' 4 2 = 2@, @'gcd' (-4) 6 = 2@, @'gcd' 0 4@ = @4@. @'gcd' 0 0@ = @0@.+-- (That is, the common divisor that is \"greatest\" in the divisibility+-- preordering.)+--+-- Note: Since for signed fixed-width integer types, @'abs' 'minBound' < 0@,+-- the result may be negative if one of the arguments is @'minBound'@ (and+-- necessarily is if the other is @0@ or @'minBound'@) for such types.+gcd :: (P.Eq a, Signed a, Integral a) => a -> a -> a+gcd x y = gcd' (abs x) (abs y)+ where+ gcd' a b+ | b P.== zero = a+ | P.otherwise = gcd' b (a `rem` b)
+ src/NumHask/Data/Wrapped.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RoleAnnotations #-}+{-# OPTIONS_GHC -Wall #-}++module NumHask.Data.Wrapped where++import NumHask.Algebra.Abstract.Additive+import NumHask.Algebra.Abstract.Field+import NumHask.Algebra.Abstract.Multiplicative+import NumHask.Algebra.Abstract.Ring+import NumHask.Algebra.Abstract.Lattice+import NumHask.Analysis.Metric+import NumHask.Data.Integral+import NumHask.Data.Rational+import qualified Prelude as P++newtype Wrapped a = Wrapped { unWrapped :: a }+ deriving+ ( P.Show+ , P.Eq+ , P.Ord+ , Additive+ , Subtractive+ , Multiplicative+ , Divisive+ , Distributive+ , IntegralDomain+ , Field+ , ExpField+ , TrigField+ , Integral+ , Signed+ , JoinSemiLattice+ , MeetSemiLattice+ , Epsilon+ , UpperBoundedField+ , LowerBoundedField+ , ToInteger+ , FromInteger+ , FromRatio+ , ToRatio+ )++-- not sure if this is correct or needed+type role Wrapped representational++instance (P.Ord a, QuotientField a P.Integer) =>+ QuotientField (Wrapped a) (Wrapped P.Integer) where+ properFraction (Wrapped a) = let (i,r) = properFraction a in (Wrapped i, Wrapped r)+
+ src/NumHask/Exception.hs view
@@ -0,0 +1,15 @@+{-# OPTIONS_GHC -Wall #-}++module NumHask.Exception+ ( NumHaskException(..)+ , throw+ ) where++import qualified Prelude as P+import Control.Exception+import Data.Typeable (Typeable)++newtype NumHaskException = NumHaskException { errorMessage :: P.String }+ deriving (P.Show, Typeable)++instance Exception NumHaskException
− stack.yaml
@@ -1,3 +0,0 @@-resolver: nightly-2018-05-06--extra-deps: []