packages feed

numhask 0.5.0 → 0.13.3.0

raw patch · 40 files changed

Files

+ ChangeLog.md view
@@ -0,0 +1,121 @@+0.13.3.0+===++- Added `Read` instance for `Polar` in `NumHask.Algebra.Metric`.+- Added `NumHask.Algebra.Tropical` with the `MinPlus` tropical semiring.+- Added `StarSemiring` and `KleeneAlgebra` instances for `Bool`.+- Added `Magma`, `Unital` and `Idempotent` instances for `Bool`.+- Documented `StarSemiring` and `KleeneAlgebra` laws with the Conway equations.++0.13.2.1+===++- removed doctest-parallel test suite, use cabal-docspec in CI instead+- updated CI to use cabal-docspec 0.0.0.20250606++0.13.2+===++- GHC 9.14.1 support+- simplified Cabal stanzas to best practice template+- fixed asinh bug in Field module++0.13.1+===++- added Data instances+++0.13+===++- added modF, divF and divModF as field versions of modulo and diviso Integral functions.+- fixed bug in EuclideanPair log function.+- BoundedJoinSemiLattice becomes LowerBounded+- BoundedMeetSemiLattice becomes UpperBounded+- switch to GHC2024++0.12.1+===++- added doctests++0.12+===++- added SemiField, and bumped QuotientField to default for Subtraction.++- moved infinity & nqn to SemiField, from Field.++- introduced NumHask.Data.Positive++- introduced NumHask.Data.Wrapped++- Monus & Addus++- hiding Prelude.Rational++0.11.1.0+===+* Added Sum (..)+* Added Product (..)++0.11.0.0+===++* TypeFamilies introduced replacing FunDep usage for QuotientField, AdditiveAction, MultiplicativeAction, Basis. Classes go from Multi-parameter to single.+* EuclideanPair introduced as an intended DerivingVia support for 2 dimensional Basis & Direction instances. +* Complex modified to use EuclideanPair. Underlying representation changed to tuple and (+:) constructor as a top-level function.+* Action class operators changed from (.\*) to (|\*), and (\*.) to (\*|) etc.+* Ring, Field, Distributive & Module become type synonyms (were classes).+* Added Basis class replacing Norm & Signed+* extra type synonyms added for Basis specialisations: Absolute, Sign, EndoBased.+* abs becomes top-level function (previously method of Norm).+* sign removed and replaced with signum, mirroring Num.+* aboutEqual & nearZero moved outside Epsilon class definition.+* rationalised Language pragmas around GHC2021+* introduced QuotientField instance for Complex & EuclideanPair without Ord constraint.++0.10.0+===+* Moved operators back in.+* added doctests and properties+* added accsum & accproduct+* fixed Ratio Eq instance++0.9.0+===+* Removed bounded classes.+* Moved operators outside of class definitions where possible. ++0.8.0+=====++* GHC 9.0.1 support+* Removed protolude and replaced it with prelude+* Removed NumHask.Data.Positive, NumHask.Data.LogFloat, NumHask.Data.Wrapper+* modified project build to cabal+* removed NegativeLiterals recommendation.++0.7.0+=====++* GHC 8.10.2 support+* Modules `NumHask.Algebra.Abstract.*` renamed to `NumHask.Algebra.*`+* Renamed `Normed` to `Norm` and added `basis`+* Removed `Metric` and added `distance`+* Added `Direction`, `Polar`, `polar`, `coord`; streamlined `Complex`+* Removed `NumHask.Data.Pair`+* Fixed `FromIntegral` and `FromRational` to work in well with rebindable syntax.+* Added fundeps to `Norm`, `Direction`+* Integrated `NumHask.Algebra.Action` into `NumHask.Algebra.Module`+* Added `atan2`+* Added doctests and laws+* Improved haddocks+* Made (^) a monomorphic `a -> Int -> a` and accept negative Ints+++0.6.0+=====++* GHC 8.10.1 support
LICENSE view
@@ -1,4 +1,4 @@-Copyright Tony Day (c) 2016+Copyright (c) 2016, Tony Day  All rights reserved. 
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
numhask.cabal view
@@ -1,73 +1,77 @@ cabal-version: 3.0 name: numhask-version: 0.5.0-synopsis:-  numeric classes+version: 0.13.3.0+license: BSD-3-Clause+license-file: LICENSE+copyright: Tony Day (c) 2016+category: math+author: Tony Day+maintainer: tonyday567@gmail.com+homepage: https://github.com/tonyday567/numhask#readme+bug-reports: https://github.com/tonyday567/numhask/issues+synopsis: A numeric class hierarchy. 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:-  BSD-3-Clause-license-file:-  LICENSE-build-type:-  Simple+  This package provides alternative numeric classes over Prelude. +  The numeric class constellation looks somewhat like:++  ![nh](docs/other/nh12.svg)++  == Usage++  >>> {-# LANGUAGE GHC2024 #-}+  >>> {-# LANGUAGE RebindableSyntax #-}+  >>> import NumHask.Prelude++  See "NumHask" for a detailed overview.++build-type: Simple+tested-with:+  ghc ==9.10.3+  ghc ==9.12.2+  ghc ==9.14.1+ extra-doc-files:+  ChangeLog.md   other/*.svg+  readme.md  source-repository head-  type:-    git-  location:-    https://github.com/tonyday567/numhask-  subdir:-    numhask-library-  hs-source-dirs:-    src-  default-extensions:-    NegativeLiterals-    OverloadedStrings-    UnicodeSyntax+  type: git+  location: https://github.com/tonyday567/numhask++common ghc-options-stanza   ghc-options:     -Wall     -Wcompat     -Wincomplete-record-updates     -Wincomplete-uni-patterns     -Wredundant-constraints-  build-depends:-    base >=4.7 && <5++library+  import: ghc-options-stanza+  default-language: GHC2024+  hs-source-dirs: src+  build-depends: base >=4.14 && <5   exposed-modules:-    NumHask.Algebra.Abstract-    NumHask.Algebra.Abstract.Action-    NumHask.Algebra.Abstract.Additive-    NumHask.Algebra.Abstract.Field-    NumHask.Algebra.Abstract.Group-    NumHask.Algebra.Abstract.Lattice-    NumHask.Algebra.Abstract.Module-    NumHask.Algebra.Abstract.Multiplicative-    NumHask.Algebra.Abstract.Ring-    NumHask.Algebra.Linear.Hadamard-    NumHask.Analysis.Metric+    NumHask+    NumHask.Algebra.Action+    NumHask.Algebra.Additive+    NumHask.Algebra.Field+    NumHask.Algebra.Group+    NumHask.Algebra.Lattice+    NumHask.Algebra.Metric+    NumHask.Algebra.Multiplicative+    NumHask.Algebra.Patterns+    NumHask.Algebra.Ring+    NumHask.Algebra.Tropical     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+    NumHask.Prelude++  default-extensions: RebindableSyntax+
− other/field.svg
@@ -1,3 +0,0 @@-<?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="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,384.0401,580.7247)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 422.5906,600.0000 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,348.5736,467.2675)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,486.5428 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,263.7625,353.8165)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 302.3130,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,431.8427,353.8165)" stroke="none" text-anchor="middle">Divisive</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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 470.3932,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,348.5736,241.3261)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,348.5736,353.8165)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 387.1241,373.0918 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,265.3045,241.3261)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 303.8551,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,168.1573,241.3261)" stroke="none" text-anchor="middle">Absorbing</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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 206.7078,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,431.8427,241.3261)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 470.3932,260.6014 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,376.3300,130.3007)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 414.8805,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,293.0609,130.3007)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 331.6114,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,209.7918,130.3007)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 248.3423,149.5759 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="7.710100231303007px" stroke="rgb(0,0,0)" stroke-width="1.8087425826099444" 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,293.0609,19.2753)" 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 331.6114,38.5505 l -0.0000,-38.5505 h -77.1010 l -0.0000,38.5505 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.6045,38.5505 l -49.5562,66.0749 "/></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.2483,111.0254 l 7.8036,-5.4906 l -3.2889,-0.5290 l -1.4288,-3.0092 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.7630,105.0058 l 0.2853,-0.3804 l 0.7235,0.5426 l -1.0088,-0.1623 l 0.2853,-0.3804 l -0.7235,-0.5426 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 293.0609,38.5505 l 0.0000,64.4749 "/></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 293.0609,111.0254 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 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 293.0609,103.5009 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 307.5173,38.5505 l 49.5562,66.0749 "/></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 361.8736,111.0254 l -3.0860,-9.0289 l -1.4288,3.0092 l -3.2889,0.5290 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 357.3588,105.0058 l -0.2853,-0.3804 l 0.7235,-0.5426 l -0.4382,0.9230 l -0.2853,-0.3804 l -0.7235,0.5426 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 305.1079,38.5505 l 110.4477,176.7164 "/></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 419.7957,222.0509 l -2.3092,-9.2580 l -1.6788,2.8772 l -3.3219,0.2482 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 415.8077,215.6701 l -0.2520,-0.4032 l 0.7669,-0.4793 l -0.5149,0.8825 l -0.2520,-0.4032 l -0.7669,0.4793 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.2186,38.5505 l -99.2969,176.5278 "/></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 178.9996,222.0509 l 7.0188,-6.4637 l -3.3299,-0.0945 l -1.8099,-2.7966 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 182.6886,215.4927 l 0.2331,-0.4144 l 0.7882,0.4434 l -1.0213,-0.0290 l 0.2331,-0.4144 l -0.7882,-0.4434 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 357.0547,149.5759 l -66.8181,66.8181 "/></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 284.5798,222.0509 l 8.5017,-4.3318 l -3.1811,-0.9888 l -0.9888,-3.1811 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 289.9005,216.7302 l 0.3362,-0.3362 l 0.6395,0.6395 l -0.9757,-0.3033 l 0.3362,-0.3362 l -0.6395,-0.6395 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.4295,149.5759 l 32.6598,65.3195 "/></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 255.6669,222.0509 l -1.4211,-9.4353 l -1.9440,2.7051 l -3.3305,-0.0679 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 252.3018,215.3207 l -0.2126,-0.4253 l 0.8089,-0.4044 l -0.5963,0.8297 l -0.2126,-0.4253 l -0.8089,0.4044 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 288.2421,149.5759 l -16.1785,64.7138 "/></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 270.1234,222.0509 l 5.0614,-8.0886 l -3.2365,0.7887 l -2.4845,-2.2190 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.9483,214.7510 l 0.1153,-0.4613 l 0.8774,0.2193 l -0.9927,0.2419 l 0.1153,-0.4613 l -0.8774,-0.2193 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 417.5745,260.6014 l -49.9730,67.5098 "/></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 362.8418,334.5412 l 7.7690,-5.5395 l -3.2922,-0.5083 l -1.4476,-3.0002 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.3186,328.4934 l 0.2829,-0.3821 l 0.7269,0.5381 l -1.0098,-0.1559 l 0.2829,-0.3821 l -0.7269,-0.5381 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 279.5727,260.6014 l 49.9730,67.5098 "/></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 334.3055,334.5412 l -3.0292,-9.0481 l -1.4476,3.0002 l -3.2922,0.5083 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 329.8286,328.4934 l -0.2829,-0.3821 l 0.7269,-0.5381 l -0.4440,0.9202 l -0.2829,-0.3821 l -0.7269,0.5381 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 233.8859,149.5759 l 84.3467,67.4774 "/></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 324.4796,222.0509 l -5.2442,-7.9713 l -0.6315,3.2708 l -3.0524,1.3341 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 318.6039,217.3503 l -0.3713,-0.2970 l 0.5650,-0.7062 l -0.1937,1.0032 l -0.3713,-0.2970 l -0.5650,0.7062 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 302.6985,149.5759 l 32.6598,65.3195 "/></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 338.9360,222.0509 l -1.4211,-9.4353 l -1.9440,2.7051 l -3.3305,-0.0679 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 335.5709,215.3207 l -0.2126,-0.4253 l 0.8089,-0.4044 l -0.5963,0.8297 l -0.2126,-0.4253 l -0.8089,0.4044 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 371.5112,149.5759 l -16.1785,64.7138 "/></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 353.3924,222.0509 l 5.0614,-8.0886 l -3.2365,0.7887 l -2.4845,-2.2190 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 355.2174,214.7510 l 0.1153,-0.4613 l 0.8774,0.2193 l -0.9927,0.2419 l 0.1153,-0.4613 l -0.8774,-0.2193 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 431.8427,260.6014 l 0.0000,65.9399 "/></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 431.8427,334.5412 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 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 431.8427,327.0167 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 362.8418,260.6014 l 49.9730,67.5098 "/></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 417.5745,334.5412 l -3.0292,-9.0481 l -1.4476,3.0002 l -3.2922,0.5083 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 413.0977,328.4934 l -0.2829,-0.3821 l 0.7269,-0.5381 l -0.4440,0.9202 l -0.2829,-0.3821 l -0.7269,0.5381 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 265.0403,260.6014 l -0.9039,65.9406 "/></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 264.0268,334.5412 l 3.0727,-9.0334 l -2.9695,1.5096 l -2.9270,-1.5904 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 264.1299,327.0174 l 0.0065,-0.4754 l 0.9043,0.0124 l -0.9108,0.4630 l 0.0065,-0.4754 l -0.9043,-0.0124 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.0412,260.6014 l -50.9302,67.5520 "/></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 278.2949,334.5412 l 7.8174,-5.4710 l -3.2876,-0.5373 l -1.4212,-3.0128 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 282.8248,328.5330 l 0.2862,-0.3796 l 0.7221,0.5444 l -1.0084,-0.1648 l 0.2862,-0.3796 l -0.7221,-0.5444 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 184.5393,260.6014 l 57.6605,67.8440 "/></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 247.3805,334.5412 l -3.6301,-8.8242 l -1.2428,3.0907 l -3.2506,0.7283 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 242.5076,328.8077 l -0.3079,-0.3623 l 0.6891,-0.5857 l -0.3812,0.9480 l -0.3079,-0.3623 l -0.6891,0.5857 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 278.1719,373.0918 l 51.2024,68.4930 "/></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.1643,447.9923 l -3.0718,-9.0337 l -1.4335,3.0070 l -3.2897,0.5239 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.6590,441.9656 l -0.2847,-0.3808 l 0.7243,-0.5415 l -0.4397,0.9223 l -0.2847,-0.3808 l -0.7243,0.5415 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 348.5736,373.0918 l 0.0000,66.9005 "/></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 348.5736,447.9923 l 2.9485,-9.0747 l -2.9485,1.5501 l -2.9485,-1.5501 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 348.5736,440.4677 l -0.0000,-0.4755 l 0.9044,-0.0000 l -0.9044,0.4755 l -0.0000,-0.4755 l -0.9044,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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 354.5990,486.5428 l 21.0288,67.2711 "/></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 378.0147,561.4495 l 0.1067,-9.5411 l -2.3517,2.3593 l -3.2767,-0.5998 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 375.7697,554.2677 l -0.1419,-0.4538 l 0.8632,-0.2698 l -0.7213,0.7236 l -0.1419,-0.4538 l -0.8632,0.2698 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.8087425826099444" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 427.7820,373.0918 l -38.0321,180.5296 "/></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 388.1008,561.4495 l 4.7559,-8.2719 l -3.2048,0.9090 l -2.5657,-2.1247 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 389.6519,554.0866 l 0.0980,-0.4652 l 0.8849,0.1864 l -0.9830,0.2788 l 0.0980,-0.4652 l -0.8849,-0.1864 Z"/></g></svg>
+ other/nh11.svg view
@@ -0,0 +1,25 @@+<svg height="500" width="500" viewBox="-50 -350 500 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>svg {+  color-scheme: light dark;+}+{+  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {+    fill: rgb(5%, 5%, 5%);+  }+  .ticklines g, .tickglyph g, .legendBorder g {+    stroke: rgb(5%, 5%, 5%);+  }+  .legendBorder g {+    fill: rgb(94%, 94%, 94%);+  }+}+@media (prefers-color-scheme:dark) {+  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {+    fill: rgb(94%, 94%, 94%);+  }+  .ticklines g, .tickglyph g, .legendBorder g {+    stroke: rgb(94%, 94%, 94%);+  }+  .legendBorder g {+    fill: rgb(5%, 5%, 5%);+  }+}</style><g class="chart"><g class="edges"><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 226.67,-180.3000 C 218.42,-189.6300 208.1400,-201.23 199.34,-211.1700 L 195.15,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 170.21,-180.3000 C 171.85,-189.1200 173.87,-199.97 175.64,-209.5300 L 176.82,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 110.74,-180.3000 C 123.2400,-189.81 138.84,-201.6800 152.07,-211.7500 L 157.2,-215.65"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 192.3600,-252.3000 C 198.9,-261.46 207.0,-272.81 214.02,-282.62 L 217.78,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 162.7,-252.3000 C 153.29,-261.7100 141.56,-273.44 131.56,-283.4400 L 127.1,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 76.124,-252.3000 C 82.0090,-261.46 89.304,-272.81 95.6150,-282.62 L 99.004,-287.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 181.36,-36.303 C 176.31,-45.3740 170.05,-56.5960 164.62,-66.35 L 161.53,-71.896"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 124.56,-96.119 C 98.982,-102.5 62.272,-116.1700 45.0,-144.0 C 32.513,-164.12 41.437,-191.1 51.02,-210.0600 L 53.992,-215.6700"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 179.35,-101.76 C 205.58,-112.2 246.22,-128.66 281.0,-144.0 C 281.87,-144.38 282.75,-144.78 283.64,-145.17 L 289.5500,-147.86"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 338.83,-108.3 C 335.11,-117.29 330.51,-128.39 326.5,-138.08 L 324.09,-143.9"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 254.03,-36.4830 C 232.89,-47.366 205.83,-61.292 184.89,-72.069 L 179.16,-75.02"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 291.56,-36.4120 C 296.76,-61.887 306.46,-109.37 312.26,-137.79 L 313.51,-143.89"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 122.6400,-36.303 C 127.6900,-45.3740 133.95,-56.5960 139.38,-66.35 L 142.47,-71.896"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 289.61,-177.0 C 269.5900,-187.22 242.1500,-201.2400 219.7400,-212.7 L 214.1500,-215.55"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 313.79,-180.3000 C 312.15,-189.1200 310.13,-199.97 308.36,-209.5300 L 307.18,-215.9000"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 285.71,-252.3000 C 275.84,-261.6400 263.55,-273.26 253.03,-283.21 L 248.34,-287.65"/></g><g fill="rgb(0%, 0%, 0%)" fill-opacity="0" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><path d="M 63.4720,-36.4830 C 80.423,-46.539 101.75,-59.193 119.2300,-69.561 L 124.5200,-72.699"/></g></g><g class="shapes"><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="58.9997" x="212.5002" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="64.0001" x="198.0000" y="-324.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="140.0" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="67.9997" x="54.0002" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="81.0" x="139.5" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="61.9999" x="34.0000" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="66.0002" x="157.9999" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="125.0" y="-108.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="58.9997" x="316.5002" y="-108.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="94.0032" x="62.9984" y="-324.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="92.0016" x="241.9992" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="86.0" y="-36.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="54.0" x="290.0" y="-180.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="77.9976" x="265.0012" y="-252.0"/></g><g fill="rgb(2%, 29%, 48%)" fill-opacity="0.1" stroke="rgb(33%, -22%, 26%)" stroke-opacity="1.0" stroke-width="1.0"><rect height="36.0" width="67.9997" x="0.0002" y="-36.0"/></g></g><g class="labels"><g fill="rgb(33%, -22%, 26%)" fill-opacity="1.0" font-size="14.0" stroke="none" stroke-width="0.0" text-anchor="middle"><text x="242.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Action.html#t:AdditiveAction">Actions</a></text><text x="230.0" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Additive">Additive</a></text><text x="167.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Basis">Basis</a></text><text x="88.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Direction">Direction</a></text><text x="180.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Distributive.html#t:Distributive">Distributive</a></text><text x="65.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Divisive">Divisive</a></text><text x="191.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:ExpField">ExpField</a></text><text x="152.0" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:Field">Field</a></text><text x="346.0" y="-86.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Integral.html#t:Integral">Integral</a></text><text x="110.0" y="-302.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Multiplicative">Multiplicative</a></text><text x="288.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:QuotientField">QuotientField</a></text><text x="113.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Rational.html#t:Ratio">Ratio</a></text><text x="317.0" y="-158.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Ring.html#t:Ring">Ring</a></text><text x="304.0" y="-230.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Subtractive">Subtractive</a></text><text x="34.0" y="-14.3"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:TrigField">TrigField</a></text></g></g></g><g class="hud"/></svg>
+ other/nh12.svg view
@@ -0,0 +1,32 @@+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1931" height="500" viewBox="-1.9314 -0.5000 3.8628 1.0"><style>svg {+  color-scheme: light dark;+}+{+  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {+    fill: rgb(5%, 5%, 5%);+  }+  .ticklines g, .tickglyph g, .legendBorder g {+    stroke: rgb(5%, 5%, 5%);+  }+  .legendBorder g {+    fill: rgb(94%, 94%, 94%);+  }+}+@media (prefers-color-scheme:dark) {+  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {+    fill: rgb(94%, 94%, 94%);+  }+  .ticklines g, .tickglyph g, .legendBorder g {+    stroke: rgb(94%, 94%, 94%);+  }+  .legendBorder g {+    fill: rgb(5%, 5%, 5%);+  }+}+svg { font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";+}++ticktext { font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;+}++</style><g class="chart"><g class="edges"><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.4258,-0.0563 C 0.3930,-0.0853 0.3522,-0.1214 0.3175,-0.1522 L 0.3030,-0.1651"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.2428,-0.0563 C 0.2428,-0.0834 0.2428,-0.1168 0.2428,-0.1462 L 0.2428,-0.1658"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.2793,-0.2778 C 0.2986,-0.3060 0.3225,-0.3410 0.3433,-0.3711 L 0.3544,-0.3874"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.1804,-0.2778 C 0.1464,-0.3069 0.1041,-0.3430 0.0680,-0.3738 L 0.0530,-0.3866"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.1995,-0.2778 C -0.1655,-0.3069 -0.1232,-0.3430 -0.0871,-0.3738 L -0.0721,-0.3866"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.2781,0.3868 C -0.3104,0.3578 -0.3507,0.3216 -0.3850,0.2908 L -0.3993,0.2780"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.4552,0.1655 C -0.4496,0.1084 -0.4355,0.0162 -0.4003,-0.0554 C -0.3828,-0.0909 -0.3559,-0.1251 -0.3305,-0.1529 L -0.3181,-0.1661"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.3752,0.1756 C -0.3662,0.1720 -0.3570,0.1687 -0.3480,0.1662 C 0.0584,0.0498 0.1902,0.1718 0.5966,0.0554 C 0.5994,0.0546 0.6022,0.0537 0.6051,0.0528 L 0.6238,0.0460"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.0551,-0.0563 C 0.0887,-0.0853 0.1305,-0.1214 0.1662,-0.1522 L 0.1810,-0.1651"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.1993,0.1652 C -0.2100,0.1376 -0.2231,0.1034 -0.2346,0.0736 L -0.2415,0.0557"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.4588,0.3868 C -0.4588,0.3596 -0.4588,0.3263 -0.4588,0.2968 L -0.4588,0.2772"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.6240,-0.0426 C 0.6147,-0.0469 0.6055,-0.0513 0.5966,-0.0554 C 0.5246,-0.0890 0.4442,-0.1261 0.3782,-0.1564 L 0.3600,-0.1647"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.6869,-0.0563 C 0.6762,-0.0840 0.6630,-0.1181 0.6515,-0.1479 L 0.6446,-0.1658"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.1498,-0.0509 C -0.0762,-0.0823 0.0210,-0.1238 0.1002,-0.1576 L 0.1178,-0.1651"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.2618,-0.0563 C -0.2618,-0.0834 -0.2618,-0.1168 -0.2618,-0.1462 L -0.2618,-0.1658"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M 0.5665,-0.2778 C 0.5350,-0.3069 0.4958,-0.3430 0.4623,-0.3738 L 0.4484,-0.3866"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(0%, 0%, 0%)" fill-opacity="0"><path d="M -0.6418,0.3868 C -0.6090,0.3578 -0.5682,0.3216 -0.5335,0.2908 L -0.5190,0.2780"/></g></g><g class="shapes"><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1946" height="0.1108" x="0.2932" y="-0.4985"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1662" height="0.1108" x="0.4028" y="-0.0554"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2062" height="0.1108" x="0.1397" y="-0.0554"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2477" height="0.1108" x="0.1189" y="-0.2769"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1900" height="0.1108" x="-0.3568" y="-0.2769"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2015" height="0.1108" x="-0.3195" y="0.3877"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1662" height="0.1108" x="-0.5418" y="0.1662"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1785" height="0.1108" x="-0.0957" y="-0.0554"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2869" height="0.1108" x="-0.1530" y="-0.4985"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2800" height="0.1108" x="-0.3188" y="0.1662"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1662" height="0.1108" x="-0.5418" y="0.3877"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.1662" height="0.1108" x="0.6243" y="-0.0554"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2223" height="0.1108" x="-0.3730" y="-0.0554"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2385" height="0.1108" x="0.5051" y="-0.2769"/></g><g stroke-width="0.0031" stroke="rgb(40%, 40%, 40%)" stroke-opacity="0.8" fill="rgb(50%, 50%, 50%)" fill-opacity="0.2"><rect width="0.2062" height="0.1108" x="-0.8049" y="0.3877"/></g></g><g class="labels"><g stroke-width="0.0" stroke="none" fill="rgb(40%, 40%, 40%)" fill-opacity="0.8" font-size="0.0369" text-anchor="middle"><text x="0.3905" y="-0.4308"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Additive">Additive</a></text><text x="0.4858" y="0.0123"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Basis">Basis</a></text><text x="0.2428" y="0.0123"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Metric.html#t:Direction">Direction</a></text><text x="0.2428" y="-0.2092"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Ring.html#t:Distributive">Distributive</a></text><text x="-0.2618" y="-0.2092"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Divisive">Divisive</a></text><text x="-0.2188" y="0.4554"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:ExpField">ExpField</a></text><text x="-0.4588" y="0.2338"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:Field">Field</a></text><text x="-0.0065" y="0.0123"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Integral.html#t:Integral">Integral</a></text><text x="-0.0095" y="-0.4308"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Multiplicative.html#t:Multiplicative">Multiplicative</a></text><text x="-0.1788" y="0.2338"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:QuotientField">QuotientField</a></text><text x="-0.4588" y="0.4554"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Data-Rational.html#t:Ratio">Ratio</a></text><text x="0.7074" y="0.0123"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Ring.html#t:Ring">Ring</a></text><text x="-0.2618" y="0.0123"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:SemiField">SemiField</a></text><text x="0.6243" y="-0.2092"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Additive.html#t:Subtractive">Subtractive</a></text><text x="-0.7018" y="0.4554"><a href="https://hackage.haskell.org/package/numhask/docs/NumHask-Algebra-Field.html#t:TrigField">TrigField</a></text></g></g></g><g class="hud"></g></svg>
− other/numhask.svg
@@ -1,3 +0,0 @@-<?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="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,387.8981,369.2436)" stroke="none" text-anchor="middle">Epsilon</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 411.7834,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,184.3949,298.6385)" stroke="none" text-anchor="middle">Signed</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 208.2803,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,342.9936,298.6385)" stroke="none" text-anchor="middle">Normed</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 366.8790,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,495.8599,369.2436)" stroke="none" text-anchor="middle">BoundedLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 519.7452,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,469.1083,298.6385)" stroke="none" text-anchor="middle">BoundedMeetSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 492.9936,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,522.6115,298.6385)" stroke="none" text-anchor="middle">BoundedJoinSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 546.4968,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,576.1146,298.6385)" stroke="none" text-anchor="middle">Lattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 600.0000,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,469.1083,228.0334)" stroke="none" text-anchor="middle">MeetSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 492.9936,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,522.6115,228.0334)" stroke="none" text-anchor="middle">JoinSemiLattice</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 546.4968,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,167.1975,369.2436)" stroke="none" text-anchor="middle">Module</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 191.0828,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,130.8917,298.6385)" stroke="none" text-anchor="middle">MultiplicativeAction</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,184.3949,510.4538)" stroke="none" text-anchor="middle">TrigField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 208.2803,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,130.8917,510.4538)" stroke="none" text-anchor="middle">LowerBoundedField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,77.3885,510.4538)" stroke="none" text-anchor="middle">UpperBoundedField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 101.2739,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,237.8981,510.4538)" stroke="none" text-anchor="middle">QuotientField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,23.8854,510.4538)" stroke="none" text-anchor="middle">ExpField</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 47.7707,522.3965 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,130.8917,439.8478)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,451.7904 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,237.8981,369.2436)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,381.1863 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,237.8981,298.6385)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 261.7834,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,77.3885,298.6385)" stroke="none" text-anchor="middle">Divisive</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 101.2739,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,291.4013,228.0334)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 315.2866,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,290.4459,298.6385)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 314.3312,310.5812 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,343.9490,228.0334)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,238.8535,228.0334)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 262.7389,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,187.2611,228.0334)" stroke="none" text-anchor="middle">Group</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 211.1465,239.9761 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,121.3376,158.3360)" stroke="none" text-anchor="middle">Absorbing</text></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 145.2229,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,187.2611,158.3360)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 211.1465,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,343.9490,158.3360)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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,292.3567,158.3360)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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.7643,158.3360)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,170.2787 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="1.0" font-size="4.777070063694268px" stroke="rgb(0,0,0)" stroke-width="2.06640091435653" 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.7643,89.5462)" 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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,101.4889 l -0.0000,-23.8854 h -47.7707 l -0.0000,23.8854 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.7643,101.4889 l 0.0000,36.9045 "/></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.7643,146.3933 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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.7643,138.9365 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 249.7213,101.4889 l 28.8783,38.5045 "/></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 283.3997,146.3933 l -3.0582,-8.9476 l -1.4159,2.9822 l -3.2593,0.5243 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 278.9256,140.4279 l -0.3259,-0.4345 l 0.8266,-0.6199 l -0.5006,1.0545 l -0.3259,-0.4345 l -0.8266,0.6199 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 258.6783,101.4889 l 60.7003,40.4669 "/></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 326.0350,146.3933 l -5.8618,-7.4197 l -0.3427,3.2834 l -2.8990,1.5791 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 319.8306,142.2570 l -0.4520,-0.3013 l 0.5731,-0.8597 l -0.1212,1.1610 l -0.4520,-0.3013 l -0.5731,0.8597 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 231.4756,101.4889 l -30.0142,38.5896 "/></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 196.5499,146.3933 l 7.8277,-5.3047 l -3.2496,-0.5813 l -1.3634,-3.0065 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 201.1279,140.5073 l 0.3335,-0.4288 l 0.8156,0.6343 l -1.1490,-0.2056 l 0.3335,-0.4288 l -0.8156,-0.6343 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 220.0305,101.4889 l -71.0269,40.9115 "/></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 142.0714,146.3933 l 9.2512,-1.9566 l -2.7896,-1.7653 l -0.1273,-3.2988 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 148.5330,142.6715 l 0.4707,-0.2711 l 0.5157,0.8953 l -0.9864,-0.6242 l 0.4707,-0.2711 l -0.5157,-0.8953 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 231.5965,170.2787 l -30.2962,39.4663 "/></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 196.4289,216.0908 l 7.7939,-5.3542 l -3.2532,-0.5607 l -1.3824,-2.9978 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 200.9696,210.1758 l 0.3308,-0.4309 l 0.8196,0.6291 l -1.1503,-0.1983 l 0.3308,-0.4309 l -0.8196,-0.6291 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 187.2611,170.2787 l 0.0000,37.8121 "/></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 187.2611,216.0908 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 187.2611,208.6339 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 274.3485,170.2787 l -62.4121,41.3906 "/></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 205.2693,216.0908 l 9.1096,-2.5352 l -2.8952,-1.5861 l -0.3347,-3.2842 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 211.4837,211.9695 l 0.4527,-0.3002 l 0.5710,0.8611 l -1.0237,-0.5608 l 0.4527,-0.3002 l -0.5710,-0.8611 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 240.4369,170.2787 l -1.0367,37.8151 "/></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 239.1809,216.0908 l 3.1674,-8.9095 l -2.9630,1.4555 l -2.8788,-1.6157 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 239.3853,208.6368 l 0.0149,-0.5430 l 1.0328,0.0283 l -1.0477,0.5147 l 0.0149,-0.5430 l -1.0328,-0.0283 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.1015,170.2787 l 29.1519,39.3821 "/></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 230.0131,216.0908 l -3.0019,-8.9666 l -1.4346,2.9732 l -3.2625,0.5038 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 225.5766,210.0973 l -0.3232,-0.4366 l 0.8304,-0.6147 l -0.5073,1.0513 l -0.3232,-0.4366 l -0.8304,0.6147 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 283.1889,170.2787 l -30.2962,39.4663 "/></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 248.0213,216.0908 l 7.7939,-5.3542 l -3.2532,-0.5607 l -1.3824,-2.9978 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 252.5619,210.1758 l 0.3308,-0.4309 l 0.8196,0.6291 l -1.1503,-0.1983 l 0.3308,-0.4309 l -0.8196,-0.6291 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 325.9409,170.2787 l -62.4121,41.3906 "/></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 256.8616,216.0908 l 9.1096,-2.5352 l -2.8952,-1.5861 l -0.3347,-3.2842 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 263.0761,211.9695 l 0.4527,-0.3002 l 0.5710,0.8611 l -1.0237,-0.5608 l 0.4527,-0.3002 l -0.5710,-0.8611 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.9490,170.2787 l 0.0000,37.8121 "/></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 343.9490,216.0908 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 343.9490,208.6339 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 258.4451,170.2787 l 61.1939,41.3342 "/></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 326.2683,216.0908 l -5.8167,-7.4551 l -0.3626,3.2812 l -2.9085,1.5615 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.0891,211.9169 l -0.4501,-0.3040 l 0.5783,-0.8562 l -0.1282,1.1602 l -0.4501,-0.3040 l -0.5783,0.8562 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 301.1971,170.2787 l 29.1519,39.3821 "/></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 335.1087,216.0908 l -3.0019,-8.9666 l -1.4346,2.9732 l -3.2625,0.5038 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 330.6721,210.0973 l -0.3232,-0.4366 l 0.8304,-0.6147 l -0.5073,1.0513 l -0.3232,-0.4366 l -0.8304,0.6147 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 196.0443,170.2787 l 80.8786,109.9725 "/></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.6627,286.6959 l -2.9741,-8.9759 l -1.4438,2.9687 l -3.2641,0.4937 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 277.2448,280.6887 l -0.3218,-0.4376 l 0.8323,-0.6121 l -0.5105,1.0497 l -0.3218,-0.4376 l -0.8323,0.6121 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.8991,239.9761 l -30.5716,40.3436 "/></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 299.4958,286.6959 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 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 303.9994,280.7527 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 249.4410,170.2787 l 28.5814,39.3399 "/></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 282.7246,216.0908 l -2.9219,-8.9930 l -1.4610,2.9603 l -3.2669,0.4747 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 278.3417,210.0580 l -0.3193,-0.4395 l 0.8359,-0.6073 l -0.5166,1.0467 l -0.3193,-0.4395 l -0.8359,0.6073 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 292.1930,170.2787 l -0.5183,37.8129 "/></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 291.5650,216.0908 l 3.0450,-8.9521 l -2.9428,1.4960 l -2.9007,-1.5761 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 291.6672,208.6347 l 0.0074,-0.5431 l 1.0331,0.0142 l -1.0405,0.5290 l 0.0074,-0.5431 l -1.0331,-0.0142 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 334.9450,170.2787 l -29.7235,39.4242 "/></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.4053,216.0908 l 7.7471,-5.4217 l -3.2580,-0.5325 l -1.4084,-2.9857 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 304.8944,210.1366 l 0.3270,-0.4337 l 0.8250,0.6220 l -1.1520,-0.1883 l 0.3270,-0.4337 l -0.8250,-0.6220 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 177.9087,170.2787 l -86.2353,110.1187 "/></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 86.7410,286.6959 l 7.8452,-5.2787 l -3.2477,-0.5921 l -1.3534,-3.0110 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 91.3385,280.8250 l 0.3349,-0.4277 l 0.8135,0.6370 l -1.1484,-0.2094 l 0.3349,-0.4277 l -0.8135,-0.6370 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 267.5159,235.9135 l -158.6448,52.3386 "/></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 101.2739,290.7585 l 9.4557,-0.0426 l -2.3743,-2.2936 l 0.5434,-3.2562 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 108.3553,288.4223 l 0.5158,-0.1702 l 0.3237,0.9812 l -0.8395,-0.8110 l 0.5158,-0.1702 l -0.3237,-0.9812 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(255,0,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 326.0108,239.9761 l -63.5153,42.2863 "/></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 255.8363,286.6959 l 9.1051,-2.5515 l -2.8980,-1.5809 l -0.3406,-3.2836 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.0434,282.5634 l 0.4521,-0.3010 l 0.5726,0.8600 l -1.0247,-0.5590 l 0.4521,-0.3010 l -0.5726,-0.8600 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 282.3513,239.9761 l -30.5716,40.3436 "/></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 246.9480,286.6959 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 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 251.4516,280.7527 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 131.2593,170.2787 l 91.6048,110.2637 "/></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 227.9764,286.6959 l -3.4992,-8.7845 l -1.2659,3.0488 l -3.2292,0.6856 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 223.2113,280.9602 l -0.3471,-0.4178 l 0.7947,-0.6602 l -0.4476,1.0781 l -0.3471,-0.4178 l -0.7947,0.6602 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,310.5812 l 0.0000,38.7197 "/></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 237.8981,357.3010 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 237.8981,349.8441 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 281.5575,310.5812 l -29.9948,40.3021 "/></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.7864,357.3010 l 7.7133,-5.4697 l -3.2612,-0.5122 l -1.4269,-2.9769 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 251.2385,351.3190 l 0.3243,-0.4357 l 0.8288,0.6169 l -1.1531,-0.1811 l 0.3243,-0.4357 l -0.8288,-0.6169 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 219.7980,381.1863 l -64.1287,42.3129 "/></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 148.9918,427.9051 l 9.1155,-2.5138 l -2.8915,-1.5929 l -0.3270,-3.2850 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 155.2159,423.7984 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,0,255)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 81.9135,310.5812 l 41.6187,109.8429 "/></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 126.3667,427.9051 l -0.4539,-9.4449 l -2.1882,2.4718 l -3.2767,-0.4012 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 123.7247,420.9320 l -0.1925,-0.5079 l 0.9662,-0.3661 l -0.7737,0.8740 l -0.1925,-0.5079 l -0.9662,0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 112.7921,451.7904 l -64.1297,42.3148 "/></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 41.9850,498.5111 l 9.1155,-2.5139 l -2.8915,-1.5929 l -0.3271,-3.2850 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 48.2090,494.4044 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 148.9913,451.7904 l 64.1297,42.3148 "/></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 219.7985,498.5111 l -5.8970,-7.3918 l -0.3271,3.2850 l -2.8915,1.5929 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 213.5745,494.4044 l -0.4534,-0.2992 l 0.5690,-0.8624 l -0.1156,1.1615 l -0.4534,-0.2992 l -0.5690,0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 237.8981,381.1863 l 0.0000,109.3248 "/></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 237.8981,498.5111 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 237.8981,491.0543 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 139.9415,451.7904 l 30.5719,40.3446 "/></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 175.3451,498.5111 l -3.1025,-8.9323 l -1.4011,2.9891 l -3.2567,0.5404 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 170.8415,492.5679 l -0.3281,-0.4329 l 0.8235,-0.6240 l -0.4954,1.0569 l -0.3281,-0.4329 l -0.8235,0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 121.8419,451.7904 l -30.5719,40.3446 "/></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 86.4383,498.5111 l 7.7603,-5.4028 l -3.2567,-0.5404 l -1.4011,-2.9891 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 90.9419,492.5679 l 0.3281,-0.4329 l 0.8235,0.6240 l -1.1515,-0.1911 l 0.3281,-0.4329 l -0.8235,-0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 130.8917,451.7904 l 0.0000,38.7207 "/></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 130.8917,498.5111 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 130.8917,491.0543 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,0.0000 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,128,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 267.5159,238.5402 l -105.4160,46.3705 "/></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,128,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,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 154.7771,288.1318 l 9.4083,-0.9463 l -2.5827,-2.0561 l 0.2296,-3.2932 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,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 161.6027,285.1294 l 0.4972,-0.2187 l 0.4160,0.9457 l -0.9132,-0.7270 l 0.4972,-0.2187 l -0.4160,-0.9457 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.5" stroke="rgb(0,128,0)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 225.9393,310.5812 l -41.1223,41.0667 "/></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,128,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,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 179.1563,357.3010 l 8.4281,-4.2871 l -3.1518,-0.9821 l -0.9778,-3.1531 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,128,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 184.4326,352.0318 l 0.3843,-0.3838 l 0.7301,0.7311 l -1.1144,-0.3472 l 0.3843,-0.3838 l -0.7301,-0.7311 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 137.0327,310.5812 l 20.3653,39.6052 "/></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 161.0564,357.3010 l -1.5139,-9.3338 l -1.8961,2.7024 l -3.3011,-0.0299 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 157.6465,350.6695 l -0.2484,-0.4831 l 0.9188,-0.4725 l -0.6704,0.9555 l -0.2484,-0.4831 l -0.9188,0.4725 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,165.5660 l 174.8272,52.9197 "/></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 498.7261,220.8034 l -7.7608,-5.4021 l 0.6238,3.2417 l -2.3169,2.3516 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 491.5891,218.6431 l -0.5199,-0.1574 l 0.2993,-0.9889 l 0.2206,1.1463 l -0.5199,-0.1574 l -0.2993,0.9889 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 367.8344,167.6538 l 123.4388,48.1543 "/></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 498.7261,218.7156 l -7.3161,-5.9905 l 0.3692,3.2805 l -2.4931,2.1639 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 491.7792,216.0056 l -0.5060,-0.1974 l 0.3755,-0.9626 l 0.1305,1.1600 l -0.5060,-0.1974 l -0.3755,0.9626 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 316.2420,167.7546 l 121.5386,47.9256 "/></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 445.2229,218.6149 l -7.2942,-6.0172 l 0.3572,3.2818 l -2.5010,2.1548 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 438.2860,215.8794 l -0.5053,-0.1993 l 0.3790,-0.9612 l 0.1263,1.1604 l -0.5053,-0.1993 l -0.3790,0.9612 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 365.3951,170.2787 l 75.2778,41.9199 "/></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 447.6622,216.0908 l -6.4353,-6.9281 l -0.0795,3.3003 l -2.7637,1.8055 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 441.1474,212.4629 l -0.4746,-0.2643 l 0.5027,-0.9027 l -0.0281,1.1669 l -0.4746,-0.2643 l -0.5027,0.9027 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 531.6614,239.9761 l 30.5716,40.3436 "/></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 567.0647,286.6959 l -3.1026,-8.9323 l -1.4011,2.9891 l -3.2567,0.5404 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 562.5611,280.7527 l -0.3281,-0.4329 l 0.8235,-0.6240 l -0.4954,1.0569 l -0.3281,-0.4329 l -0.8235,0.6240 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 487.2081,239.9761 l 64.1292,42.3138 "/></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 558.0148,286.6959 l -5.8970,-7.3917 l -0.3270,3.2850 l -2.8915,1.5929 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 551.7908,282.5891 l -0.4534,-0.2992 l 0.5690,-0.8624 l -0.1156,1.1615 l -0.4534,-0.2992 l -0.5690,0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 522.6115,239.9761 l 0.0000,38.7197 "/></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 522.6115,286.6959 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 522.6115,279.2390 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 264.6497,170.2260 l 226.9147,112.9574 "/></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 498.7261,286.7485 l -6.7485,-6.6234 l 0.0731,3.3004 l -2.6774,1.9312 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 492.0507,283.4255 l -0.4863,-0.2421 l 0.4604,-0.9249 l 0.0258,1.1670 l -0.4863,-0.2421 l -0.4604,0.9249 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 469.1083,239.9761 l 0.0000,38.7197 "/></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 469.1083,286.6959 l 2.9220,-8.9930 l -2.9220,1.5362 l -2.9220,-1.5362 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 469.1083,279.2390 l -0.0000,-0.5432 l 1.0332,-0.0000 l -1.0332,0.5432 l -0.0000,-0.5432 l -1.0332,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="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 260.2012,170.2787 l 182.6541,112.2291 "/></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 449.6714,286.6959 l -6.1325,-7.1975 l -0.2208,3.2938 l -2.8386,1.6854 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 443.3181,282.7921 l -0.4628,-0.2844 l 0.5409,-0.8803 l -0.0781,1.1647 l -0.4628,-0.2844 l -0.5409,0.8803 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 518.0865,310.5812 l -14.8672,39.2387 "/></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 500.3848,357.3010 l 5.9188,-7.3743 l -3.2767,0.4012 l -2.1882,-2.4718 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 503.0269,350.3279 l 0.1925,-0.5079 l 0.9662,0.3661 l -1.1586,0.1419 l 0.1925,-0.5079 l -0.9662,-0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 473.6332,310.5812 l 14.8672,39.2387 "/></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 491.3349,357.3010 l -0.4539,-9.4449 l -2.1882,2.4718 l -3.2767,-0.4012 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 488.6929,350.3279 l -0.1925,-0.5079 l 0.9662,-0.3661 l -0.7737,0.8740 l -0.1925,-0.5079 l -0.9662,0.3661 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 273.3014,239.9761 l -64.1292,42.3138 "/></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 202.4948,286.6959 l 9.1155,-2.5139 l -2.8915,-1.5929 l -0.3270,-3.2850 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 208.7188,282.5891 l 0.4534,-0.2992 l 0.5690,0.8624 l -1.0224,-0.5632 l 0.4534,-0.2992 l -0.5690,-0.8624 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 343.7874,239.9761 l -0.5240,38.7205 "/></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 343.1552,286.6959 l 3.0434,-8.9526 l -2.9425,1.4965 l -2.9010,-1.5756 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 343.2561,279.2397 l 0.0073,-0.5431 l 1.0331,0.0140 l -1.0405,0.5292 l 0.0073,-0.5431 l -1.0331,-0.0140 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 347.6660,239.9761 l 34.1378,109.6862 "/></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 384.1812,357.3010 l 0.1175,-9.4551 l -2.3335,2.3351 l -3.2465,-0.5985 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 381.9652,350.1810 l -0.1614,-0.5186 l 0.9865,-0.3070 l -0.8251,0.8257 l -0.1614,-0.5186 l -0.9865,0.3070 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 306.9297,310.5812 l 58.0062,42.0261 "/></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 371.4143,357.3010 l -5.5682,-7.6425 l -0.4704,3.2675 l -2.9584,1.4649 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 365.3758,352.9260 l -0.4399,-0.3187 l 0.6062,-0.8367 l -0.1663,1.1554 l -0.4399,-0.3187 l -0.6062,0.8367 Z"/></g><g stroke-linejoin="miter" stroke-opacity="1.0" fill-opacity="0.0" opacity="0.3" stroke="rgb(84,84,84)" stroke-width="2.06640091435653" fill="rgb(0,0,0)" stroke-linecap="butt" stroke-miterlimit="10.0"><path d="M 462.2400,239.9761 l -63.4854,110.3899 "/></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 394.7663,357.3010 l 7.0163,-6.3390 l -3.2988,-0.1251 l -1.7671,-2.7884 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 398.4838,350.8369 l 0.2708,-0.4709 l 0.8956,0.5151 l -1.1664,-0.0442 l 0.2708,-0.4709 l -0.8956,-0.5151 Z"/></g></svg>
+ readme.md view
@@ -0,0 +1,152 @@+numhask+===++[![Hackage](https://img.shields.io/hackage/v/numhask.svg)](https://hackage.haskell.org/package/numhask)+[![build](https://github.com/tonyday567/numhask/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/tonyday567/numhask/actions/workflows/haskell-ci.yml)++![](other/nh12.svg)++Usage+===++``` haskell+{-# LANGUAGE RebindableSyntax #-}+import NumHask.Prelude+```+See the documentation in the NumHask module for a detailed overview.++v0.12 notes+===++SemiField+---++Compared to previous library versions, Ring and Field have been removed as super classes of QuotientField, and SemiField introduced as the new constraint.++Old version:++![](other/nh11.svg)++```+type SemiField a = (Distributive a, Divisive a)++class (SemiField a) => QuotientField a where+  type Whole a :: Type+  properFraction :: a -> (Whole a, a)+```++The notion of a quotient is now that which distributes and divides.++Subtractive originally slipped in as a super class due to the notion of rounding down (or, specifically, towards zero). By using DefaultSignatures, a default for Subtractive-type numbers can be provided and still allow non-Subtractive (SemiField) things to be quotient fields.++Infinity and nan move from a Field to a SemiField constraint - subtraction is not needed to come up with an infinity or silly compute.++Positive+---++A motivation for SemiField was to introduce NumHask.Data.Positive into the library. Positive has no sane Subtractive instance (but should be able to be rounded).++Out of the many approaches that can be taken in defining a positive number, the definition relies on a notion of truncated subtraction; that subtraction can be performed on positive numbers but, for answers outside the typed range, the lower bound should be returned.++Specifically, the positive constructor needs to be supplied with a number that has a MeetSemiLattice instance, so that complex numbers and other geometries are correctly handled:++``` haskell+ghci> 2 +: (-2)+Complex {complexPair = (2,-2)}+ghci> positive (2 +: (-2))+UnsafePositive {unPositive = Complex {complexPair = (2,0)}}+```++Truncated Arithmetic+---++Truncated subtraction can be generalised to a notion of truncated arithmetic on a number with a typed range. This may be a direction explored further in the library including:++- [epsilon, +infinity): A positive number type which is a safe divisor.+- /= zero, non-zero arithmetic (x - x returns epsilon, say)+- [0,1]: probability and weight arithmetic+- [-1,1]: correlation math++magnitudes are positive+---++The current Basis instance of Double:++``` haskell+instance Basis Double where+  type Mag Double = Double+  type Base Double = Double+  magnitude = P.abs+  basis = P.signum+```++is probably more correctly written as:++``` haskell+instance Basis Double where+  type Mag Double = Positive Double+  type Base Double = Sign Double+  magnitude = Positive . P.abs+  basis = Sign . P.signum+```++where Sign is a future-imagined type representing {-1,0,1} or {-1,1}++In Haskell, there is a basic choice between using multiple parameters for a type or embedding types using type families. Using multiple parameters would, in practice, force users to have to chose and write 'Basis Double Double Double' or 'Basis Positive Sign Double'.++On balance, a computational chain involving magnitude is likely to be a single, underlying type, so that providing a Basis instance returning a Positive would result in a lot of unwrapping.++``` haskell+-- endo-based+x == basis x * magnitude x++-- if hetero-typed ...+x == (unSign $ basis x) * (unPositive $ magnitude x)+```++The library awaits real-world feedback on safety versus ergonomics.++Monus+---++Truncated subtraction is encapsulated within the Monus class and supplied operator:++``` haskell+ghci> 4 ∸ 7 :: Positive Int+UnsafePositive {unPositive = 0}+ghci> unPositive (4 ∸ 7 :: Positive Int)+0+ghci> unPositive (7 ∸ 4 :: Positive Int)+3+```++NumHask.Data.Wrapped+---++The introduction of Positive provoked including a wrapper type for most numhask types. This type can be used with derivingvia:++``` haskell+newtype Positive a = UnsafePositive {unPositive :: a}+  deriving stock+    (Eq, Ord, Show)+  deriving+    ( Additive,+      Multiplicative,+      Divisive,+      Integral,+      FromInteger,+      FromRational,+      Basis,+      Direction,+      Epsilon,+      AdditiveAction,+      SubtractiveAction,+      MultiplicativeAction,+      DivisiveAction,+      JoinSemiLattice,+      MeetSemiLattice,+      UpperBounded+    )+    via (Wrapped a)+```+
+ src/NumHask.hs view
@@ -0,0 +1,384 @@+{-# LANGUAGE RebindableSyntax #-}+{-# OPTIONS_HADDOCK prune #-}++-- | Numeric classes.+module NumHask+  ( -- * Usage+    -- $setup++    -- * Overview+    -- $overview+    -- $pictures++    -- * Prelude Mappings+    -- $mapping++    -- * Extensions+    -- $extensions++    -- * Additive+    Additive (..),+    sum,+    accsum,+    Subtractive (..),++    -- * Multiplicative+    Multiplicative (..),+    product,+    accproduct,+    Divisive (..),++    -- * Ring+    Distributive,+    Ring,+    StarSemiring (..),+    KleeneAlgebra,+    InvolutiveRing (..),+    two,++    -- * Tropical+    MinPlus (..),++    -- * Field+    Field,+    ExpField (..),+    QuotientField (..),+    TrigField (..),+    infinity,+    negInfinity,+    nan,+    half,+    modF,+    divF,+    divModF,++    -- * Lattice+    JoinSemiLattice (..),+    joinLeq,+    (<\),+    MeetSemiLattice (..),+    meetLeq,+    (</),+    LowerBounded (..),+    UpperBounded (..),++    -- * Action+    AdditiveAction (..),+    (+|),+    SubtractiveAction (..),+    (-|),+    MultiplicativeAction (..),+    (*|),+    DivisiveAction (..),+    (/|),+    Module,+    TrivialAction (..),++    -- * Metric+    Basis (..),+    Absolute,+    Sign,+    EndoBased,+    abs,+    signum,+    distance,+    Direction (..),+    Polar (..),+    polar,+    coord,+    Epsilon (..),+    aboutEqual,+    nearZero,+    (~=),++    -- * Complex+    Complex (..),+    (+:),+    realPart,+    imagPart,+    normSquared,++    -- * Integral+    Integral (..),+    ToIntegral (..),+    ToInt,+    FromIntegral (..),+    FromInteger (..),+    FromInt,+    even,+    odd,+    (^^),+    (^),+    (^+),++    -- * Rational+    Ratio (..),+    Rational,+    ToRatio (..),+    FromRatio (..),+    FromRational (..),+    reduce,+    gcd,+    numerator,+    denominator,++    -- * Exceptions+    NumHaskException (..),+    throw,+  )+where++import NumHask.Algebra.Action+  ( AdditiveAction (..),+    DivisiveAction (..),+    Module,+    MultiplicativeAction (..),+    SubtractiveAction (..),+    TrivialAction (..),+    (*|),+    (+|),+    (-|),+    (/|),+  )+import NumHask.Algebra.Additive+  ( Additive (..),+    Subtractive (..),+    accsum,+    sum,+  )+import NumHask.Algebra.Field+  ( ExpField (..),+    Field,+    QuotientField (..),+    TrigField (..),+    divF,+    divModF,+    half,+    infinity,+    modF,+    nan,+    negInfinity,+  )+import NumHask.Algebra.Lattice+  ( JoinSemiLattice (..),+    LowerBounded (..),+    MeetSemiLattice (..),+    UpperBounded (..),+    joinLeq,+    meetLeq,+    (</),+    (<\),+  )+import NumHask.Algebra.Metric+  ( Absolute,+    Basis (..),+    Direction (..),+    EndoBased,+    Epsilon (..),+    Polar (..),+    Sign,+    aboutEqual,+    abs,+    coord,+    distance,+    nearZero,+    polar,+    signum,+    (~=),+  )+import NumHask.Algebra.Multiplicative+  ( Divisive (..),+    Multiplicative (..),+    accproduct,+    product,+  )+import NumHask.Algebra.Ring+  ( Distributive,+    InvolutiveRing (..),+    KleeneAlgebra,+    Ring,+    StarSemiring (..),+    two,+  )+import NumHask.Algebra.Tropical (MinPlus (..))+import NumHask.Data.Complex+  ( Complex (..),+    imagPart,+    normSquared,+    realPart,+    (+:),+  )+import NumHask.Data.Integral+  ( FromInt,+    FromInteger (..),+    FromIntegral (..),+    Integral (..),+    ToInt,+    ToIntegral (..),+    even,+    odd,+    (^),+    (^+),+    (^^),+  )+import NumHask.Data.Rational+  ( FromRatio (..),+    FromRational (..),+    Ratio (..),+    Rational,+    ToRatio (..),+    denominator,+    gcd,+    numerator,+    reduce,+  )+import NumHask.Exception (NumHaskException (..), throw)++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude+-- >>> 1+1+-- 2++-- $extensions+--+-- [RebindableSyntax](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/rebindable_syntax.html)+-- is recommended for use with numhask.+--+-- As a replacement for the numerical classes, numhask clashes significantly with an+-- unqualified import of the @Prelude@. Either numhask modules should be qualified,+-- or prelude turned off with the NoImplicitPrelude extension, or with RebindableSyntax,+-- which implies NoImplicitPrelude.+--+-- == defaulting+--+-- Without RebindableSyntax, numeric literals default as follows:+--+-- >>> :set -XNoRebindableSyntax+-- >>> :t 1+-- 1 :: Num a => a+--+-- >>> :t 1.0+-- 1.0 :: Fractional a => a+--+-- With RebindableSyntax (which also switches NoImplicitPrelude on) literal numbers change to the numhask types, 'FromInteger' and 'FromRational':+--+-- >>> :set -XRebindableSyntax+-- >>> :t 1+-- 1 :: FromInteger a => a+--+-- >>> :t 1.0+-- 1.0 :: FromRational a => a+--+-- >>> 1+-- 1+--+-- >>> 1.0+-- 1.0+--+-- RebindableSyntax is a tradeoff, however, and usage comes attached with other non-numeric changes+-- that "NumHask.Prelude" attempts to counteract.+--+-- See [haskell2010 Section 4.3.4](https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3) for the nuts and bolts to defaulting.+--+-- The effect of [ExtendedDefaultRules](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/ghci.html#extension-ExtendedDefaultRules)+-- in ghci or switched on as an extension also need to be understood.+-- It can lead to unusual interactions with numerics and strange error messages at times because+-- it adds @()@ and @[]@ to the start of the type defaulting list.++-- $overview+-- numhask is largely a set of classes that can replace the 'GHC.Num.Num' class and it's descendents.+-- Principles that have guided design include:+--+-- - __/balanced class density/__. The numeric hierarchy begins with addition and multiplication,+--   choosing not to build from a Magma base. Whilst not being as principled as other approaches, this circumvents the instance explosion problems of Haskell whilst maintaining clarity of class purpose.+--+-- - __/operator-first/__. In all cases, a class exists to define useful operators.+--   Major class groupings, such as 'Distributive', 'Ring' and 'Field' are type synonyms.+--+-- - __/lawful/__. All classes have laws associated with them that serve to relate class operators together in a meaningful way.+--+-- - __/low-impact/__. The library attempts to fit in with the rest of the Haskell ecosystem.+--   It provides instances for common numbers: 'GHC.Num.Int', 'GHC.Num.Integer', 'GHC.Float.Double',+--   'GHC.Float.Float', 'GHC.Natural.Natural', and the Word classes. It avoids name (or idea) clashes with other popular libraries+--   and adopts conventions in the <https://hackage.haskell.org/package/base/docs/Prelude.html current prelude>+--   where they make sense.+--+-- - __/proof-of-concept/__. The library may be below industrial-strength depending on a definition+--   of this term. At the same time, correspondence around improving the library is most welcome.++-- $pictures+--+-- The class heirarchy looks somewhat like this:+--+-- ![classes](other/nh.svg)++-- $mapping+--+-- 'GHC.Num' is a very old part of haskell, and is virtually unchanged since its specification in+-- [haskell98](https://www.haskell.org/onlinereport/standard-prelude.html).+--+-- A deconstruction of 'GHC.Num.Num' and mapping to numhask.+--+-- > -- | Basic numeric class.+-- > class  Num a  where+-- >    {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}+-- >+-- >    (+), (-), (*)       :: a -> a -> a+-- >    -- | Unary negation.+-- >    negate              :: a -> a+--+-- '(+)' is an operator of the 'Additive' class+--+-- '(-)' & 'negate' are functions in the 'Subtractive' class, and+--+-- '(*)' is an operator of the 'Multiplicative' class.+--+-- 'zero' and 'one' are also introduced to the numeric hierarchy.+--+-- >    -- | 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+--+-- The concept of an absolute value and the sign of a number can include situations where the domain type is different to the absolute and sign codomain types.+--+-- A new class, 'Basis' is supplied to handle these situations:+--+-- - the 'magnitude' method is a generalisation of 'abs'+--+-- - the 'basis' method is a generalisation of 'signum'+--+-- 'NumHask.Algebra.Metric.abs' and 'NumHask.Algebra.Metric.signum' are specialisations of these methods.+--+-- >    -- | 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' becomes its own class and 'FromIntegral' is introduced to polymorphise the covariant.+--+-- Mappings from other areas of prelude include:+--+-- - 'GHC.Real.Integral' becomes 'Integral' and a polymorphic 'ToIntegral' is introduced.+--+-- - 'GHC.Real.Fractional' is roughly synonymous to 'Field' together with a polymorphic 'FromRatio'.+--+-- - 'GHC.Real.RealFrac' becomes 'QuotientField' with a polymorphic 'Whole' type using Type Families.+--+-- - 'GHC.Float.Floating' is split into 'ExpField' and 'TrigField'+--+-- - 'GHC.Float.RealFloat' is not attempted. Life is too short.+--+-- - Complex is resupplied in 'NumHask.Data.Complex' but with some functionality deriving via 'NumHask.Algebra.Metric.EuclideanPair'. The underlying representation has also been switched to a newtype-wrapped tuple.+--+-- In addition to base changes, alternatives to 'sum' and 'product' from 'Data.Foldable' are also supplied.
− src/NumHask/Algebra/Abstract.hs
@@ -1,72 +0,0 @@-{-# 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-  )-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---- $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.------ ![ring example](other/ring.svg)------ 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
@@ -1,49 +0,0 @@-{-# 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 elements of 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
@@ -1,158 +0,0 @@-{-# 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---- | For practical reasons, 'Additive' has no super classes. Using `Associative` and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.------ > zero + a == a--- > a + zero == a--- > (a + b) + c == a + (b + c)--- > a + b == b + a------ By convention, (+) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative multiplication seems a bit dogmatic.-class Additive a where-  infixl 6 +-  (+) :: a -> a -> a--  zero :: a---- | Compute the sum of a 'Foldable'.-sum :: (Additive a, P.Foldable f) => f a -> a-sum = P.foldr (+) zero---- |--- > a - a = zero--- > negate a = zero - a--- > negate a + a = zero--- > a + negate a = 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
@@ -1,248 +0,0 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE FlexibleInstances #-}-{-# 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-import Prelude ((.))---- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set---   on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.------ A summary of the rules thus 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 (Distributive a, Subtractive a, Divisive 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---- > a - one < floor a <= a <= ceiling a < a + one--- > round a == floor (a + one/(one+one))----class (Field a, Subtractive a, Multiplicative b, Additive b) => QuotientField a b where-  properFraction :: a -> (b, a)--  round :: a -> b-  default round ::(P.Ord a, P.Ord b, Subtractive b, Integral 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 = (P.fst . frac, P.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 (Field a) =>-      UpperBoundedField a where--  infinity :: a-  infinity = one / zero--  nan :: a-  nan = zero / zero--instance UpperBoundedField P.Float--instance UpperBoundedField P.Double--instance UpperBoundedField b => UpperBoundedField (a -> b) where-  infinity _ = infinity-  nan _ = nan--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---- | 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---- | A 'half' is a 'Field' because it requires addition, multiplication and division to be computed.-half :: (Field a) => a-half = one / two
− src/NumHask/Algebra/Abstract/Group.hs
@@ -1,122 +0,0 @@-{-# 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/Lattice.hs
@@ -1,248 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}--module NumHask.Algebra.Abstract.Lattice where--import Data.Int (Int8, Int16, Int32, Int64)-import Data.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
@@ -1,22 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# OPTIONS_GHC -Wall #-}---- | Algebra for Modules-module NumHask.Algebra.Abstract.Module-  ( Module-  ) where--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 a scalar multiplier (.*, *.) 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), MultiplicativeAction h) => Module h
− src/NumHask/Algebra/Abstract/Multiplicative.hs
@@ -1,119 +0,0 @@-{-# 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---- | For practical reasons, 'Multiplicative' has no super classes. Using 'Associative' and 'Unital' from this library, or using 'Semigroup' and 'Monoid' from base tends to complexify the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.------ > one * a == a--- > a * one == a--- > (a * b) * c == a * (b * c)--- > a * b == b * a------ By convention, (*) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative multiplication seems a bit dogmatic.-class Multiplicative a where--  infixl 7 *-  (*) :: a -> a -> a--  one :: a---- | Compute the product of a 'Foldable'.-product :: (Multiplicative a, P.Foldable f) => f a -> a-product = P.foldr (*) one---- |------ > a / a = one--- > recip a = one / a--- > recip a * a = one--- > a * recip a = 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
@@ -1,137 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}---- | Ring-module NumHask.Algebra.Abstract.Ring-  ( Distributive-  , Semiring-  , Ring-  , 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--- > zero * a == zero--- > a * zero == zero------ The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element annihilation> laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.-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 commutative monoidal under addition, has a monoidal multiplication operator (not necessarily commutative), and where multiplication distributes over addition.-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 monoidal under multiplication, and where multiplication---   distributes over addition.-class (Distributive a, Subtractive a) =>-  Ring a-instance (Distributive a, Subtractive a) =>-  Ring 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.----class (Distributive 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)---- | Defining 'two' requires adding the multiplicative unital to itself.-two :: (Multiplicative a, Additive a) => a-two = one + one
+ src/NumHask/Algebra/Action.hs view
@@ -0,0 +1,133 @@+{-# LANGUAGE TypeFamilies #-}++-- | Algebra for Actions+--+-- Convention: the |'s in the operators point towards the higher-kinded number, representing an operator or action __into__ a structure.+module NumHask.Algebra.Action+  ( AdditiveAction (..),+    (+|),+    SubtractiveAction (..),+    (-|),+    MultiplicativeAction (..),+    (*|),+    DivisiveAction (..),+    (/|),+    Module,+    TrivialAction (..),+  )+where++import Data.Kind (Type)+import NumHask.Algebra.Additive (Additive (..), Subtractive (..))+import NumHask.Algebra.Multiplicative (Divisive (..), Multiplicative (..))+import NumHask.Algebra.Ring (Distributive)+import Prelude (Eq, Ord, flip)++-- | Additive Action+--+-- > m |+ zero == m+class+  (Additive (AdditiveScalar m)) =>+  AdditiveAction m+  where+  type AdditiveScalar m :: Type++  infixl 6 |++  (|+) :: m -> AdditiveScalar m -> m++infixl 6 +|++-- | flipped additive action+--+-- > (+|) == flip (|+)+-- > zero +| m = m+(+|) :: (AdditiveAction m) => AdditiveScalar m -> m -> m+(+|) = flip (|+)++-- | Subtractive Action+--+-- > m |- zero = m+class+  (AdditiveAction m, Subtractive (AdditiveScalar m)) =>+  SubtractiveAction m+  where+  infixl 6 |-+  (|-) :: m -> AdditiveScalar m -> m++infixl 6 -|++-- | Subtraction with the scalar on the left+--+-- > (-|) == (+|) . negate+-- > zero -| m = negate m+(-|) :: (AdditiveAction m, Subtractive m) => AdditiveScalar m -> m -> m+a -| b = a +| negate b++-- | Multiplicative Action+--+-- > m |* one = m+-- > m |* zero = zero+class+  (Multiplicative (Scalar m)) =>+  MultiplicativeAction m+  where+  type Scalar m :: Type++  infixl 7 |*+  (|*) :: m -> Scalar m -> m++infixl 7 *|++-- | flipped multiplicative action+--+-- > (*|) == flip (|*)+-- > one *| m = one+-- > zero *| m = zero+(*|) :: (MultiplicativeAction m) => Scalar m -> m -> m+(*|) = flip (|*)++-- | Divisive Action+--+-- > m |/ one = m+class+  (Divisive (Scalar m), MultiplicativeAction m) =>+  DivisiveAction m+  where+  infixl 7 |/+  (|/) :: m -> Scalar m -> m++-- | left scalar division+--+-- > (/|) == (*|) . recip+-- > one |/ m = recip m+(/|) :: (MultiplicativeAction m, Divisive m) => Scalar m -> m -> m+a /| b = a *| recip b++-- | A <https://en.wikipedia.org/wiki/Module_(mathematics) Module>+--+-- > a *| one == a+-- > (a + b) *| c == (a *| c) + (b *| c)+-- > c |* (a + b) == (c |* a) + (c |* b)+-- > a *| zero == zero+-- > a *| b == b |* a+type Module m = (Distributive (Scalar m), MultiplicativeAction m)++-- | An action of a set of numbers on itself+newtype TrivialAction a = TrivialAction+  { getTrivialAction :: a+  }+  deriving (Eq, Ord, Additive, Subtractive, Multiplicative, Divisive)++instance (Additive a) => AdditiveAction (TrivialAction a) where+  type AdditiveScalar (TrivialAction a) = a+  TrivialAction a |+ b = TrivialAction (a + b)++instance (Subtractive a) => SubtractiveAction (TrivialAction a) where+  TrivialAction a |- b = TrivialAction (a - b)++instance (Multiplicative a) => MultiplicativeAction (TrivialAction a) where+  type Scalar (TrivialAction a) = a+  TrivialAction a |* b = TrivialAction (a * b)++instance (Divisive a) => DivisiveAction (TrivialAction a) where+  TrivialAction a |/ b = TrivialAction (a / b)
+ src/NumHask/Algebra/Additive.hs view
@@ -0,0 +1,222 @@+-- | Additive classes+module NumHask.Algebra.Additive+  ( Additive (..),+    Sum (..),+    sum,+    accsum,+    Subtractive (..),+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Semigroup (Semigroup (..))+import Data.Traversable (mapAccumL)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Bool, Double, Eq, Float, Int, Integer, Ord, Show, fromInteger)+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | or [Addition](https://en.wikipedia.org/wiki/Addition)+--+-- For practical reasons, we begin the class tree with 'NumHask.Algebra.Additive.Additive'.  Starting with  'NumHask.Algebra.Group.Associative' and 'NumHask.Algebra.Group.Unital', or using 'Data.Semigroup.Semigroup' and 'Data.Monoid.Monoid' from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.+--+-- prop> \a -> zero + a == a+-- prop> \a -> a + zero == a+-- prop> \a b c -> (a + b) + c == a + (b + c)+-- prop> \a b -> a + b == b + a+--+-- By convention, (+) is regarded as commutative, but this is not universal, and the introduction of another symbol which means non-commutative addition seems a bit dogmatic.+--+-- >>> zero + 1+-- 1+--+-- >>> 1 + 1+-- 2+class Additive a where+  infixl 6 ++  (+) :: a -> a -> a++  zero :: a++-- | A wrapper for an Additive which distinguishes the additive structure+--+-- @since 0.11.1+newtype Sum a = Sum+  { getSum :: a+  }+  deriving (Eq, Ord, Show)++instance (Additive a) => P.Semigroup (Sum a) where+  Sum a <> Sum b = Sum (a + b)++instance (Additive a) => P.Monoid (Sum a) where+  mempty = Sum zero++deriving instance (Additive a) => Additive (Sum a)++-- | Compute the sum of a 'Data.Foldable.Foldable'.+--+-- >>> sum [0..10]+-- 55+sum :: (Additive a, P.Foldable f) => f a -> a+sum = getSum P.. P.foldMap Sum++-- | Compute the accumulating sum of a 'Data.Traversable.Traversable'.+--+-- >>> accsum [0..10]+-- [0,1,3,6,10,15,21,28,36,45,55]+accsum :: (Additive a, P.Traversable f) => f a -> f a+accsum = P.snd P.. mapAccumL (\a b -> (a + b, a + b)) zero++-- | or [Subtraction](https://en.wikipedia.org/wiki/Subtraction)+--+-- prop> \a -> a - a == zero+-- prop> \a -> negate a == zero - a+-- prop> \a -> negate a + a == zero+-- prop> \a -> a + negate a == zero+--+--+-- >>> negate 1+-- -1+--+-- >>> 1 - 2+-- -1+class (Additive a) => Subtractive a where+  {-# MINIMAL (-) | negate #-}++  negate :: a -> a+  negate a = zero - a++  infixl 6 -+  (-) :: a -> a -> a+  a - b = a + negate b++instance Additive Double where+  (+) = (P.+)+  zero = 0++instance Subtractive Double where+  (-) = (P.-)+  negate = P.negate++instance Additive Float where+  (+) = (P.+)+  zero = 0++instance Subtractive Float where+  (-) = (P.-)+  negate = P.negate++instance Additive Int where+  (+) = (P.+)+  zero = 0++instance Subtractive Int where+  (-) = (P.-)+  negate = P.negate++instance Additive Integer where+  (+) = (P.+)+  zero = 0++instance Subtractive Integer where+  (-) = (P.-)+  negate = P.negate++instance Additive Bool where+  (+) = (P.||)+  zero = P.False++instance Additive Natural where+  (+) = (P.+)+  zero = 0++instance Subtractive Natural where+  (-) = (P.-)+  negate = P.negate++instance Additive Int8 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int8 where+  (-) = (P.-)+  negate = P.negate++instance Additive Int16 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int16 where+  (-) = (P.-)+  negate = P.negate++instance Additive Int32 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int32 where+  (-) = (P.-)+  negate = P.negate++instance Additive Int64 where+  (+) = (P.+)+  zero = 0++instance Subtractive Int64 where+  (-) = (P.-)+  negate = P.negate++instance Additive Word where+  (+) = (P.+)+  zero = 0++instance Subtractive Word where+  (-) = (P.-)+  negate = P.negate++instance Additive Word8 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word8 where+  (-) = (P.-)+  negate = P.negate++instance Additive Word16 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word16 where+  (-) = (P.-)+  negate = P.negate++instance Additive Word32 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word32 where+  (-) = (P.-)+  negate = P.negate++instance Additive Word64 where+  (+) = (P.+)+  zero = 0++instance Subtractive Word64 where+  (-) = (P.-)+  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+  f - f' = \a -> f a - f' a+  negate f = negate P.. f
+ src/NumHask/Algebra/Field.hs view
@@ -0,0 +1,322 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE TypeFamilies #-}++-- | [field](https://en.wikipedia.org/wiki/Field_(mathematics\)) classes+module NumHask.Algebra.Field+  ( SemiField,+    Field,+    ExpField (..),+    QuotientField (..),+    infinity,+    negInfinity,+    nan,+    TrigField (..),+    half,+    modF,+    divF,+    divModF,+  )+where++import Data.Bool (bool)+import Data.Kind+import NumHask.Algebra.Additive (Additive (..), Subtractive (..), (-))+import NumHask.Algebra.Multiplicative+  ( Divisive (..),+    Multiplicative (..),+    (/),+  )+import NumHask.Algebra.Ring (Distributive, Ring, two)+import NumHask.Data.Integral (FromIntegral (..), Integral, even)+import Prelude (Eq (..), (.))+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> :set -XScopedTypeVariables+-- >>> import NumHask.Prelude++-- | A <https://en.wikipedia.org/wiki/Semifield Semifield> is a field with no subtraction.+--+-- @since 0.12+type SemiField a = (Distributive a, Divisive a)++-- | A <https://en.wikipedia.org/wiki/Field_(mathematics) Field> is a set+--   on which addition, subtraction, multiplication, and division are defined. It is also assumed that multiplication is distributive over addition.+--+-- 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 / a == one || a == zero+-- > recip a == one / a || a == zero+-- > recip a * a == one || a == zero+-- > a * recip a == one || a == zero+type Field a = (Ring a, Divisive a)++-- | A hyperbolic field class+--+-- prop> \(a::Double) -> a < zero || (sqrt . (**2)) a == a+-- prop> \(a::Double) -> a < zero || (log . exp) a ~= a+-- prop> \(a::Double) (b::Double) -> (b < zero) || a <= zero || a == 1 || abs (a ** logBase a b - b) < 10 * epsilon+class+  (Field a) =>+  ExpField a+  where+  exp :: a -> a+  log :: a -> a+  (**) :: a -> a -> a+  (**) a b = exp (log a * b)++  -- | log to the base of+  --+  -- >>> logBase 2 8+  -- 2.9999999999999996+  logBase :: a -> a -> a+  logBase a b = log b / log a++  -- | square root+  --+  -- >>> sqrt 4+  -- 2.0+  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++-- | Quotienting of a 'Field' into a 'NumHask.Algebra.Ring'+--+-- See [Field of fractions](https://en.wikipedia.org/wiki/Field_of_fractions)+--+-- > \a -> a - one < floor a <= a <= ceiling a < a + one+class (SemiField a) => QuotientField a where+  type Whole a :: Type+  properFraction :: a -> (Whole a, a)++  -- | round to the nearest Int+  --+  -- Exact ties are managed by rounding down ties if the whole component is even.+  --+  -- >>> round (1.5 :: Double)+  -- 2+  --+  -- >>> round (2.5 :: Double)+  -- 2+  round :: a -> Whole a+  default round :: (Subtractive a, Integral (Whole a), P.Eq (Whole a), P.Ord a, Subtractive (Whole a)) => a -> Whole a+  round x = case properFraction x of+    (n, r) ->+      let m = bool (n + one) (n - one) (r P.< zero)+          half_up = abs' r + half+          abs' a+            | a P.< zero = negate a+            | P.otherwise = a+       in case P.compare half_up one of+            P.LT -> n+            P.EQ -> bool m n (even n)+            P.GT -> m++  -- | supply the next upper whole component+  --+  -- >>> ceiling (1.001 :: Double)+  -- 2+  ceiling :: a -> Whole a+  default ceiling :: (P.Ord a, Distributive (Whole a)) => a -> Whole a+  ceiling x = bool n (n + one) (r P.> zero)+    where+      (n, r) = properFraction x++  -- | supply the previous lower whole component+  --+  -- >>> floor (1.001 :: Double)+  -- 1+  floor :: a -> Whole a+  default floor :: (P.Ord a, Subtractive (Whole a), Distributive (Whole a)) => a -> Whole a+  floor x = bool n (n - one) (r P.< zero)+    where+      (n, r) = properFraction x++  -- | supply the whole component closest to zero+  --+  -- >>> floor (-1.001 :: Double)+  -- -2+  --+  -- >>> truncate (-1.001 :: Double)+  -- -1+  truncate :: a -> Whole a+  default truncate :: (P.Ord a) => a -> Whole a+  truncate x = bool (ceiling x) (floor x) (x P.> zero)++instance QuotientField P.Float where+  type Whole P.Float = P.Int+  properFraction = P.properFraction++instance QuotientField P.Double where+  type Whole P.Double = P.Int+  properFraction = P.properFraction++-- | infinity is defined for any 'Field'.+--+-- >>> one / zero + infinity+-- Infinity+--+-- >>> infinity + 1+-- Infinity+infinity :: (SemiField a) => a+infinity = one / zero++-- | nan is defined as zero/zero+--+-- but note the (social) law:+--+-- >>> nan == zero / zero+-- False+nan :: (SemiField a) => a+nan = zero / zero++-- | negative infinity+--+-- >>> negInfinity + infinity+-- NaN+negInfinity :: (Field a) => a+negInfinity = negate infinity++-- | Trigonometric Field+--+-- The list of laws is quite long: <https://en.wikipedia.org/wiki/List_of_trigonometric_identities trigonometric identities>+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+  atan2 :: a -> 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+  atan2 = P.atan2+  sinh = P.sinh+  cosh = P.cosh+  asinh = P.asinh+  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+  atan2 = P.atan2+  sinh = P.sinh+  cosh = P.cosh+  asinh = P.asinh+  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+  atan2 f g x = atan2 (f x) (g x)+  sinh f = sinh . f+  cosh f = cosh . f+  asinh f = asinh . f+  acosh f = acosh . f+  atanh f = atanh . f++-- | A half of 'one'+--+-- >>> half :: Double+-- 0.5+half :: (Additive a, Divisive a) => a+half = one / two++-- | Approximate modulo for fields+--+-- @since 0.13+--+-- >>> modF 1.5 1.2+-- 0.30000000000000004+modF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> a+modF n d+  | d == infinity = n+  | d == zero = nan+  | P.True = n - d * fromIntegral (floor (n / d))++-- | Approximate diviso for fields.+--+-- Compared with 'NumHask.Algebra.Field.div', divF returns the original type rather than the 'Whole' type.+--+-- @since 0.13+--+-- >>> divF 1.5 1.2+-- 1.0+divF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> a+divF n d+  | d == infinity = zero+  | d == zero = infinity+  | P.True = fromIntegral (floor (n / d))++-- | Approximate `NumHask.Algebra.Field.divMod` for fields.+--+-- @since 0.13+--+-- >>> divModF 1.5 1.2+-- (1.0,0.30000000000000004)+divModF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> (a, a)+divModF n d+  | d == infinity = (zero, n)+  | d == zero = (infinity, nan)+  | P.True = (div', n - d * div')+  where+    div' = fromIntegral (floor (n / d))
+ src/NumHask/Algebra/Group.hs view
@@ -0,0 +1,130 @@+-- | The Group hierarchy+module NumHask.Algebra.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 ⊕ b ∈ T+--+-- These laws are true by construction in haskell: the type signature of '⊕' and the above mathematical laws are synonyms.+class Magma a where+  infix 3 ⊕+  (⊕) :: a -> a -> a++instance (Magma b) => Magma (a -> b) where+  f ⊕ g = \a -> f a ⊕ g a++instance Magma Bool where+  a ⊕ b = a || b++instance Unital Bool where+  unit = False++-- | A Unital Magma is a magma with an+--   <https://en.wikipedia.org/wiki/Identity_element identity element> (the+--   unit).+--+-- > unit ⊕ a = a+-- > a ⊕ 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 ⊕ b) ⊕ c = a ⊕ (b ⊕ 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 ⊕ b = b ⊕ a+class+  (Magma a) =>+  Commutative a++instance (Commutative b) => Commutative (a -> b)++-- | An Invertible Magma+--+-- > ∀ a,b ∈ T: inv a ⊕ (a ⊕ b) = b = (b ⊕ a) ⊕ 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.+type Group a = (Associative a, Unital a, Invertible a)++-- | An Absorbing is a Magma with an+--   <https://en.wikipedia.org/wiki/Absorbing_element Absorbing Element>+--+-- > a ⊕ 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 ⊕ a = a+class+  (Magma a) =>+  Idempotent a++instance (Idempotent b) => Idempotent (a -> b)++instance Idempotent Bool++-- | 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+type AbelianGroup a = (Associative a, Unital a, Invertible a, Commutative a)
+ src/NumHask/Algebra/Lattice.hs view
@@ -0,0 +1,264 @@+-- | [Lattices](https://en.wikipedia.org/wiki/Lattice_(order\))+module NumHask.Algebra.Lattice+  ( JoinSemiLattice (..),+    joinLeq,+    (<\),+    MeetSemiLattice (..),+    meetLeq,+    (</),+    LowerBounded (..),+    UpperBounded (..),+    Lattice,+    BoundedLattice,+  )+where++import Data.Bool (Bool (..), (&&), (||))+import Data.Eq (Eq ((==)))+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Ord (Ord (..))+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Enum (Bounded (..))+import GHC.Float (Double, Float)+import GHC.Int (Int)+import GHC.Natural (Natural (..))+import GHC.Num (Integer)+import GHC.Word (Word)+import NumHask.Algebra.Additive (zero)+import NumHask.Algebra.Field+  ( infinity,+    negInfinity,+  )++-- | A algebraic structure with element joins: See [Semilattice](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++infixr 6 <\++-- | The partial ordering induced by the join-semilattice structure+(<\) :: (JoinSemiLattice a) => a -> a -> Bool+(<\) = joinLeq++-- | A algebraic structure with element meets: See [Semilattice](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++infixr 6 </++-- | The partial ordering induced by the meet-semilattice structure+(</) :: (MeetSemiLattice a) => a -> a -> Bool+(</) = meetLeq++-- | The combination of two semi lattices makes a lattice if the absorption law holds:+-- see [Absorption Law](http://en.wikipedia.org/wiki/Absorption_law) and [Lattice](http://en.wikipedia.org/wiki/Lattice_(order\))+--+-- > Absorption: a \/ (a /\ b) == a /\ (a \/ b) == a+type Lattice a = (JoinSemiLattice a, MeetSemiLattice a)++-- | A join-semilattice with an identity element 'bottom' for '\/'.+--+-- > x \/ bottom == x+class (JoinSemiLattice a) => LowerBounded a where+  bottom :: a++-- | A meet-semilattice with an identity element 'top' for '/\'.+--+-- > x /\ top == x+class (MeetSemiLattice a) => UpperBounded a where+  top :: a++-- | Lattices with both bounds+--+-- > x /\ bottom == bottom+-- > x \/ top == top+type BoundedLattice a = (JoinSemiLattice a, MeetSemiLattice a, LowerBounded a, UpperBounded a)++instance JoinSemiLattice Float where+  (\/) = max++instance MeetSemiLattice Float where+  (/\) = min++instance JoinSemiLattice Double where+  (\/) = max++instance MeetSemiLattice Double where+  (/\) = min++instance JoinSemiLattice Int where+  (\/) = max++instance MeetSemiLattice Int where+  (/\) = min++instance JoinSemiLattice Integer where+  (\/) = max++instance MeetSemiLattice Integer where+  (/\) = min++instance JoinSemiLattice Bool where+  (\/) = (||)++instance MeetSemiLattice Bool where+  (/\) = (&&)++instance JoinSemiLattice Natural where+  (\/) = max++instance MeetSemiLattice Natural where+  (/\) = min++instance JoinSemiLattice Int8 where+  (\/) = max++instance MeetSemiLattice Int8 where+  (/\) = min++instance JoinSemiLattice Int16 where+  (\/) = max++instance MeetSemiLattice Int16 where+  (/\) = min++instance JoinSemiLattice Int32 where+  (\/) = max++instance MeetSemiLattice Int32 where+  (/\) = min++instance JoinSemiLattice Int64 where+  (\/) = max++instance MeetSemiLattice Int64 where+  (/\) = min++instance JoinSemiLattice Word where+  (\/) = max++instance MeetSemiLattice Word where+  (/\) = min++instance JoinSemiLattice Word8 where+  (\/) = max++instance MeetSemiLattice Word8 where+  (/\) = min++instance JoinSemiLattice Word16 where+  (\/) = max++instance MeetSemiLattice Word16 where+  (/\) = min++instance JoinSemiLattice Word32 where+  (\/) = max++instance MeetSemiLattice Word32 where+  (/\) = min++instance JoinSemiLattice Word64 where+  (\/) = max++instance MeetSemiLattice Word64 where+  (/\) = min++instance LowerBounded Float where+  bottom = negInfinity++instance UpperBounded Float where+  top = infinity++instance LowerBounded Double where+  bottom = negInfinity++instance UpperBounded Double where+  top = infinity++instance LowerBounded Int where+  bottom = minBound++instance UpperBounded Int where+  top = maxBound++instance LowerBounded Bool where+  bottom = False++instance UpperBounded Bool where+  top = True++instance LowerBounded Natural where+  bottom = zero++instance LowerBounded Int8 where+  bottom = minBound++instance UpperBounded Int8 where+  top = maxBound++instance LowerBounded Int16 where+  bottom = minBound++instance UpperBounded Int16 where+  top = maxBound++instance LowerBounded Int32 where+  bottom = minBound++instance UpperBounded Int32 where+  top = maxBound++instance LowerBounded Int64 where+  bottom = minBound++instance UpperBounded Int64 where+  top = maxBound++instance LowerBounded Word where+  bottom = minBound++instance UpperBounded Word where+  top = maxBound++instance LowerBounded Word8 where+  bottom = minBound++instance UpperBounded Word8 where+  top = maxBound++instance LowerBounded Word16 where+  bottom = minBound++instance UpperBounded Word16 where+  top = maxBound++instance LowerBounded Word32 where+  bottom = minBound++instance UpperBounded Word32 where+  top = maxBound++instance LowerBounded Word64 where+  bottom = minBound++instance UpperBounded Word64 where+  top = maxBound
− src/NumHask/Algebra/Linear/Hadamard.hs
@@ -1,39 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# OPTIONS_GHC -Wall #-}---- | Element-by-element operations-module NumHask.Algebra.Linear.Hadamard-  ( HadamardMultiplication(..)-  , HadamardDivision(..)-  , Hadamard-  )-where--import NumHask.Algebra.Abstract.Multiplicative---- | element by element multiplication------ > (a .*. b) .*. c == a .*. (b .*. c)--- > singleton one .*. a = a--- > a .*. singleton one = a--- > a .*. b == b .*. a-class (Multiplicative a) =>-  HadamardMultiplication m a where-  infixl 7 .*.-  (.*.) :: m a -> m a -> 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--class (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a-instance (HadamardMultiplication m a, HadamardDivision m a) => Hadamard m a-
+ src/NumHask/Algebra/Metric.hs view
@@ -0,0 +1,401 @@+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Metric classes+module NumHask.Algebra.Metric+  ( Basis (..),+    Absolute,+    Sign,+    EndoBased,+    abs,+    signum,+    distance,+    Direction (..),+    Polar (..),+    polar,+    coord,+    Epsilon (..),+    nearZero,+    aboutEqual,+    (~=),+    EuclideanPair (..),+  )+where++import Control.Applicative+import Data.Bool+import Data.Data+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Kind+import Data.Type.Equality+import Data.Word (Word16, Word32, Word64, Word8)+import GHC.Generics+import GHC.Natural (Natural (..))+import NumHask.Algebra.Action+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import Prelude (Double, Eq (..), Float, Functor (..), Int, Integer, Read, Show, Word, fromRational)+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | 'Basis' encapsulates the notion of magnitude (intuitively the quotienting of a higher-kinded number to a scalar one) and the basis on which the magnitude quotienting was performed. An instance needs to satisfy these laws:+--+-- @since 0.11+--+-- > \a -> magnitude a >= zero+-- > \a -> magnitude zero == zero+-- > \a -> a == magnitude a *| basis a+-- > \a -> magnitude (basis a) == one+--+-- The names chosen are meant to represent the spiritual idea of a basis rather than a specific mathematics. See https://en.wikipedia.org/wiki/Basis_(linear_algebra) & https://en.wikipedia.org/wiki/Norm_(mathematics) for some mathematical motivations.+--+-- >>> magnitude (-0.5 :: Double)+-- 0.5+--+-- >>> basis (-0.5 :: Double)+-- -1.0+class (Distributive (Mag a)) => Basis a where+  type Mag a :: Type+  type Base a :: Type++  -- | or length, or ||v||+  magnitude :: a -> Mag a++  -- | or direction, or v-hat+  basis :: a -> Base a++-- | Basis where the domain and magnitude codomain are the same.+--+-- @since 0.11+type Absolute a = (Basis a, Mag a ~ a)++-- | Basis where the domain and basis codomain are the same.+--+-- @since 0.11+type Sign a = (Basis a, Base a ~ a)++-- | Basis where the domain, magnitude codomain and basis codomain are the same.+--+-- @since 0.11+type EndoBased a = (Basis a, Mag a ~ a, Base a ~ a)++-- | The absolute value of a number.+--+-- prop> \a -> abs a * signum a ~= a+--+--+-- >>> abs (-1)+-- 1+abs :: (Absolute a) => a -> a+abs = magnitude++-- | The sign of a number.+--+-- @since 0.11+--+-- >>> signum (-1)+-- -1+--+-- @abs zero == zero@, so any value for @signum zero@ is ok.  We choose lawful neutral:+--+-- >>> signum zero == zero+-- True+signum :: (Sign a) => a -> a+signum = basis++instance Basis Double where+  type Mag Double = Double+  type Base Double = Double+  magnitude = P.abs+  basis = P.signum++instance Basis Float where+  type Mag Float = Float+  type Base Float = Float+  magnitude = P.abs+  basis = P.signum++instance Basis Int where+  type Mag Int = Int+  type Base Int = Int+  magnitude = P.abs+  basis = P.signum++instance Basis Integer where+  type Mag Integer = Integer+  type Base Integer = Integer+  magnitude = P.abs+  basis = P.signum++instance Basis Natural where+  type Mag Natural = Natural+  type Base Natural = Natural+  magnitude = P.abs+  basis = P.signum++instance Basis Int8 where+  type Mag Int8 = Int8+  type Base Int8 = Int8+  magnitude = P.abs+  basis = P.signum++instance Basis Int16 where+  type Mag Int16 = Int16+  type Base Int16 = Int16+  magnitude = P.abs+  basis = P.signum++instance Basis Int32 where+  type Mag Int32 = Int32+  type Base Int32 = Int32+  magnitude = P.abs+  basis = P.signum++instance Basis Int64 where+  type Mag Int64 = Int64+  type Base Int64 = Int64+  magnitude = P.abs+  basis = P.signum++instance Basis Word where+  type Mag Word = Word+  type Base Word = Word+  magnitude = P.abs+  basis = P.signum++instance Basis Word8 where+  type Mag Word8 = Word8+  type Base Word8 = Word8+  magnitude = P.abs+  basis = P.signum++instance Basis Word16 where+  type Mag Word16 = Word16+  type Base Word16 = Word16+  magnitude = P.abs+  basis = P.signum++instance Basis Word32 where+  type Mag Word32 = Word32+  type Base Word32 = Word32+  magnitude = P.abs+  basis = P.signum++instance Basis Word64 where+  type Mag Word64 = Word64+  type Base Word64 = Word64+  magnitude = P.abs+  basis = P.signum++-- | Distance, which combines the Subtractive notion of difference, with Basis.+--+-- > distance a b >= zero+-- > distance a a == zero+-- > distance a b *| basis (a - b) == a - b+distance :: (Basis a, Subtractive a) => a -> a -> Mag a+distance a b = magnitude (a - b)++-- | Convert between a "co-ordinated" or "higher-kinded" number and a direction.+--+-- @since 0.7+--+-- > ray . angle == basis+-- > magnitude (ray x) == one+class (Distributive coord, Distributive (Dir coord)) => Direction coord where+  type Dir coord :: Type+  angle :: coord -> Dir coord+  ray :: Dir coord -> coord++-- | Something that has a magnitude and a direction, with both expressed as the same type.+--+-- @since 0.7+--+-- See [Polar coordinate system](https://en.wikipedia.org/wiki/Polar_coordinate_system)+data Polar a = Polar {radial :: a, azimuth :: a}+  deriving (Eq, Show, Read, Generic, Data)++instance (Additive a, Multiplicative a) => Basis (Polar a) where+  type Mag (Polar a) = a+  type Base (Polar a) = a+  magnitude = radial+  basis = azimuth++-- | Convert a higher-kinded number that has direction, to a 'Polar'+--+-- @since 0.7+polar :: (Dir (Base a) ~ Mag a, Basis a, Direction (Base a)) => a -> Polar (Mag a)+polar x = Polar (magnitude x) (angle (basis x))++-- | Convert a Polar to a (higher-kinded) number that has a direction.+--+-- @since 0.07+coord :: (Scalar m ~ Dir m, MultiplicativeAction m, Direction m) => Polar (Scalar m) -> m+coord x = radial x *| ray (azimuth x)++-- | A small number, especially useful for approximate equality.+class+  (Eq a, Additive a) =>+  Epsilon a+  where+  epsilon :: a+  epsilon = zero++-- | Note that the constraint is Lattice rather than Ord allowing broader usage.+--+-- >>> nearZero (epsilon :: Double)+-- True+--+-- >>> nearZero (epsilon :: EuclideanPair Double)+-- True+nearZero :: (Epsilon a, Lattice a, Subtractive a) => a -> Bool+nearZero a = a /\ epsilon == a && negate a /\ epsilon == negate a++-- | Approximate equality+--+-- >>> aboutEqual zero (epsilon :: Double)+-- True+aboutEqual :: (Epsilon a, Lattice a, Subtractive a) => a -> a -> Bool+aboutEqual a b = nearZero (a - b)++infixl 4 ~=++-- | About equal operator.+--+-- >>> (1.0 + epsilon) ~= (1.0 :: Double)+-- True+(~=) :: (Epsilon a) => (Lattice a, Subtractive a) => a -> a -> Bool+(~=) = aboutEqual++-- | 1e-14+instance Epsilon Double where+  epsilon = 1e-14++-- | 1e-6+instance Epsilon Float where+  epsilon = 1e-6++-- | 0+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++-- | Two dimensional cartesian coordinates.+--+-- @since 0.11+newtype EuclideanPair a = EuclideanPair {euclidPair :: (a, a)}+  deriving stock+    (Eq, Show, Generic, Data)++instance Functor EuclideanPair where+  fmap f (EuclideanPair (x, y)) = EuclideanPair (f x, f y)++instance Applicative EuclideanPair where+  pure x = EuclideanPair (x, x)+  EuclideanPair (fx, fy) <*> EuclideanPair (x, y) = EuclideanPair (fx x, fy y)+  liftA2 f (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (f x x', f y y')++instance (Additive a) => Additive (EuclideanPair a) where+  (+) = liftA2 (+)+  zero = pure zero++instance (Subtractive a) => Subtractive (EuclideanPair a) where+  (-) = liftA2 (-)+  negate = fmap negate++instance+  (Multiplicative a) =>+  Multiplicative (EuclideanPair a)+  where+  (*) = liftA2 (*)+  one = pure one++instance+  (Divisive a) =>+  Divisive (EuclideanPair a)+  where+  recip = fmap recip++instance (TrigField a) => Direction (EuclideanPair a) where+  type Dir (EuclideanPair a) = a+  angle (EuclideanPair (x, y)) = atan2 y x+  ray x = EuclideanPair (cos x, sin x)++instance+  (ExpField a, Eq a) =>+  Basis (EuclideanPair a)+  where+  type Mag (EuclideanPair a) = a+  type Base (EuclideanPair a) = EuclideanPair a++  magnitude (EuclideanPair (x, y)) = sqrt (x * x + y * y)+  basis p = let m = magnitude p in bool (p |/ m) zero (m == zero)++instance+  (Epsilon a) =>+  Epsilon (EuclideanPair a)+  where+  epsilon = pure epsilon++instance (JoinSemiLattice a) => JoinSemiLattice (EuclideanPair a) where+  (\/) (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (x \/ x', y \/ y')++instance (MeetSemiLattice a) => MeetSemiLattice (EuclideanPair a) where+  (/\) (EuclideanPair (x, y)) (EuclideanPair (x', y')) = EuclideanPair (x /\ x', y /\ y')++instance (LowerBounded a) => LowerBounded (EuclideanPair a) where+  bottom = pure bottom++instance (UpperBounded a) => UpperBounded (EuclideanPair a) where+  top = pure top++instance (Multiplicative a) => MultiplicativeAction (EuclideanPair a) where+  type Scalar (EuclideanPair a) = a+  (|*) (EuclideanPair (x, y)) s = EuclideanPair (s * x, s * y)++instance (Divisive a) => DivisiveAction (EuclideanPair a) where+  (|/) e s = fmap (/ s) e++instance (TrigField a, ExpField a) => ExpField (EuclideanPair a) where+  exp (EuclideanPair (x, y)) = EuclideanPair (exp x * cos y, exp x * sin y)+  log (EuclideanPair (x, y)) = EuclideanPair (log (sqrt (x * x + y * y)), atan2 y x)++instance (QuotientField a) => QuotientField (EuclideanPair a) where+  type Whole (EuclideanPair a) = EuclideanPair (Whole a)++  properFraction (EuclideanPair (x, y)) =+    (EuclideanPair (xwhole, ywhole), EuclideanPair (xfrac, yfrac))+    where+      (xwhole, xfrac) = properFraction x+      (ywhole, yfrac) = properFraction y++  round (EuclideanPair (x, y)) = EuclideanPair (round x, round y)+  ceiling (EuclideanPair (x, y)) = EuclideanPair (ceiling x, ceiling y)+  floor (EuclideanPair (x, y)) = EuclideanPair (floor x, floor y)+  truncate (EuclideanPair (x, y)) = EuclideanPair (truncate x, truncate y)
+ src/NumHask/Algebra/Multiplicative.hs view
@@ -0,0 +1,170 @@+-- | Multiplicative classes+module NumHask.Algebra.Multiplicative+  ( Multiplicative (..),+    Product (..),+    product,+    accproduct,+    Divisive (..),+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Traversable (mapAccumL)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import Prelude (Double, Eq, Float, Int, Integer, Ord, Show, fromInteger, fromRational)+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | or [Multiplication](https://en.wikipedia.org/wiki/Multiplication)+--+-- For practical reasons, we begin the class tree with 'NumHask.Algebra.Additive.Additive' and 'Multiplicative'.  Starting with  'NumHask.Algebra.Group.Associative' and 'NumHask.Algebra.Group.Unital', or using 'Data.Semigroup.Semigroup' and 'Data.Monoid.Monoid' from base tends to confuse the interface once you start having to disinguish between (say) monoidal addition and monoidal multiplication.+--+--+-- prop> \a -> one * a == a+-- prop> \a -> a * one == a+-- prop> \a b c -> (a * b) * c == a * (b * c)+--+-- By convention, (*) is regarded as not necessarily commutative, but this is not universal, and the introduction of another symbol which means commutative multiplication seems a bit dogmatic.+--+-- >>> one * 2+-- 2+--+-- >>> 2 * 3+-- 6+class Multiplicative a where+  infixl 7 *+  (*) :: a -> a -> a++  one :: a++-- | A wrapper for an Multiplicative which distinguishes the multiplicative structure+--+-- @since 0.11.1+newtype Product a = Product+  { getProduct :: a+  }+  deriving (Eq, Ord, Show)++instance (Multiplicative a) => P.Semigroup (Product a) where+  Product a <> Product b = Product (a * b)++instance (Multiplicative a) => P.Monoid (Product a) where+  mempty = Product one++-- | Compute the product of a 'Data.Foldable.Foldable'.+--+-- >>> product [1..5]+-- 120+product :: (Multiplicative a, P.Foldable f) => f a -> a+product = getProduct P.. P.foldMap Product++-- | Compute the accumulating product of a 'Data.Traversable.Traversable'.+--+-- >>> accproduct [1..5]+-- [1,2,6,24,120]+accproduct :: (Multiplicative a, P.Traversable f) => f a -> f a+accproduct = P.snd P.. mapAccumL (\a b -> (a * b, a * b)) one++-- | or [Division](https://en.wikipedia.org/wiki/Division_(mathematics\))+--+-- Though unusual, the term Divisive usefully fits in with the grammer of other classes and avoids name clashes that occur with some popular libraries.+--+-- prop> \(a :: Double) -> a / a ~= one || a == zero+-- prop> \(a :: Double) -> recip a ~= one / a || a == zero+-- prop> \(a :: Double) -> recip a * a ~= one || a == zero+-- prop> \(a :: Double) -> a * recip a ~= one || a == zero+--+-- >>> recip 2.0+-- 0.5+--+-- >>> 1 / 2+-- 0.5+class (Multiplicative a) => Divisive a where+  {-# MINIMAL (/) | recip #-}++  recip :: a -> a+  recip a = one / 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/Patterns.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ViewPatterns #-}++-- | Patterns for common tests+module NumHask.Algebra.Patterns+  ( pattern Zero,+    pattern One,+    pattern MinusOne,+  )+where++import NumHask.Algebra.Additive+import NumHask.Algebra.Multiplicative+import Prelude (Bool (..), Eq (..), (.))++-- | Enabling pattern matching on zero:+--+-- > isItZero Zero = True+-- > isItZero _    = False+pattern Zero :: forall a. (Eq a, Additive a) => a+pattern Zero <- ((== zero) -> True)++-- | Enabling pattern matching on one:+--+-- > isItOne One = True+-- > isItOne _   = False+pattern One :: forall a. (Eq a, Multiplicative a) => a+pattern One <- ((== one) -> True)++-- | Enabling pattern matching on minus one:+--+-- > isItMinusOne MinusOne = True+-- > isItMinusOne _        = False+--+-- The means of testing (that is, add one, and check if it equals+-- zero) might be surprising. Other, more obvious, methods would+-- result in underflow errors. (For example, we could negate and test+-- if it's equal to one, but that would fail on any nonzero+-- 'Natural'. Similarly, we could test for equality with the negation of+-- one, but that would fail on any 'Natural' whatsoever, since 'negate+-- one' underflows.)+pattern MinusOne :: forall a. (Eq a, Additive a, Multiplicative a) => a+pattern MinusOne <- ((== zero) . (+ one) -> True)
+ src/NumHask/Algebra/Ring.hs view
@@ -0,0 +1,139 @@+-- | Ring classes+module NumHask.Algebra.Ring+  ( Distributive,+    Ring,+    StarSemiring (..),+    KleeneAlgebra,+    InvolutiveRing (..),+    two,+  )+where++import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..))+import NumHask.Algebra.Additive (Additive ((+)), Subtractive)+import NumHask.Algebra.Group (Idempotent)+import NumHask.Algebra.Multiplicative (Multiplicative (..))+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | <https://en.wikipedia.org/wiki/Distributive_property Distributive>+--+-- prop> \a b c -> a * (b + c) == a * b + a * c+-- prop> \a b c -> (a + b) * c == a * c + b * c+-- prop> \a -> zero * a == zero+-- prop> \a -> a * zero == zero+--+-- The sneaking in of the <https://en.wikipedia.org/wiki/Absorbing_element Absorption> laws here glosses over the possibility that the multiplicative zero element does not have to correspond with the additive unital zero.+type Distributive a = (Additive a, Multiplicative a)++-- | A <https://en.wikipedia.org/wiki/Ring_(mathematics) Ring> is an abelian group under addition ('NumHask.Algebra.Unital', 'NumHask.Algebra.Associative', 'NumHask.Algebra.Commutative', 'NumHask.Algebra.Invertible') and monoidal under multiplication ('NumHask.Algebra.Unital', 'NumHask.Algebra.Associative'), and where multiplication distributes over addition.+--+-- > \a -> zero + a == a+-- > \a -> a + zero == a+-- > \a b c -> (a + b) + c == a + (b + c)+-- > \a b -> a + b == b + a+-- > \a -> a - a == zero+-- > \a -> negate a == zero - a+-- > \a -> negate a + a == zero+-- > \a -> a + negate a == zero+-- > \a -> one * a == a+-- > \a -> a * one == a+-- > \a b c -> (a * b) * c == a * (b * c)+-- > \a b c -> a * (b + c) == a * b + a * c+-- > \a b c -> (a + b) * c == a * c + b * c+-- > \a -> zero * a == zero+-- > \a -> a * zero == zero+type Ring a = (Distributive a, Subtractive a)++-- | A <https://en.wikipedia.org/wiki/Semiring#Star_semirings StarSemiring> is a semiring with a unary star operator satisfying the Conway equations:+--+-- > \a -> star a == one + a * star a                                  -- fixpoint+-- > \a b -> star (a * b) == one + a * star (b * a) * b                -- product-star (sliding)+-- > \a b -> star (a + b) == star (star a * b) * star a                -- sum-star (vanishing)+--+-- These three equations are the doctestable core; they are exactly the sliding and vanishing axioms of a traced category in semiring clothing.+class (Distributive a) => StarSemiring a where+  {-# MINIMAL star | plus #-}++  star :: a -> a+  star a = one + plus a++  plus :: a -> a+  plus a = a * star a++-- | A <https://en.wikipedia.org/wiki/Kleene_algebra Kleene Algebra> is a Star Semiring with idempotent addition.+--+-- Idempotent addition gives a natural order @a <= b ⟺ a + b == b@. In that order, Kozen's induction laws hold as derived facts:+--+-- > a * x + x <= x  ==>  star a * x + x <= x+-- > x * a + x <= x  ==>  x * star a + x <= x+--+-- They are stated here as prose rather than class laws because they involve a partial order and Horn clauses, which do not fit the equational/doctest style of the Conway core.+class (StarSemiring a, Idempotent a) => KleeneAlgebra a++instance StarSemiring P.Bool where+  star _ = P.True++instance KleeneAlgebra P.Bool++-- | Conway equations for 'Bool'.+--+-- >>> let a = False; b = True in star (a * b) == one + a * star (b * a) * b+-- True+--+-- >>> let a = False; b = True in star (a + b) == star (star a * b) * star a+-- True++-- | 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++-- | Defining 'two' requires adding the multiplicative unital to itself. In other words, the concept of 'two' is a Ring one.+--+-- >>> two+-- 2+two :: (Multiplicative a, Additive a) => a+two = one + one
+ src/NumHask/Algebra/Tropical.hs view
@@ -0,0 +1,65 @@+-- | Tropical semirings.+module NumHask.Algebra.Tropical+  ( MinPlus (..),+  )+where++import NumHask.Algebra.Additive (Additive (..))+import NumHask.Algebra.Group (Idempotent, Magma (..))+import NumHask.Algebra.Multiplicative (Multiplicative (..))+import NumHask.Algebra.Ring (KleeneAlgebra, StarSemiring (..))+import Prelude (Double, Eq, Ord, Show, fromInteger)+import Prelude qualified as P++-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude+-- >>> import NumHask.Algebra.Tropical++-- | The min-plus tropical semiring.+--+-- Addition is 'min', multiplication is ordinary addition, the additive unit+-- is positive infinity, and the multiplicative unit is zero.+--+-- >>> MinPlus 3 + MinPlus 2 :: MinPlus Double+-- MinPlus {getMinPlus = 2.0}+--+-- >>> MinPlus 3 * MinPlus 2 :: MinPlus Double+-- MinPlus {getMinPlus = 5.0}+newtype MinPlus a = MinPlus+  { getMinPlus :: a+  }+  deriving (Eq, Ord, Show)++instance Additive (MinPlus Double) where+  MinPlus a + MinPlus b = MinPlus (P.min a b)+  zero = MinPlus (1 P./ 0)++instance Multiplicative (MinPlus Double) where+  MinPlus a * MinPlus b = MinPlus (a P.+ b)+  one = MinPlus 0++instance Magma (MinPlus Double) where+  a ⊕ b = a + b++instance Idempotent (MinPlus Double)++-- | Star is zero in a min-plus semiring: the cheapest repeated traversal is+-- to stay put.+--+-- >>> star (MinPlus 2 :: MinPlus Double)+-- MinPlus {getMinPlus = 0.0}+--+-- Conway equations for 'MinPlus Double'.+--+-- >>> let a = MinPlus 2 :: MinPlus Double; b = MinPlus 3 :: MinPlus Double in star (a * b) == one + a * star (b * a) * b+-- True+--+-- >>> let a = MinPlus 2 :: MinPlus Double; b = MinPlus 3 :: MinPlus Double in star (a + b) == star (star a * b) * star a+-- True+instance StarSemiring (MinPlus Double) where+  star _ = one++instance KleeneAlgebra (MinPlus Double)
− src/NumHask/Analysis/Metric.hs
@@ -1,312 +0,0 @@-{-# 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 (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' 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 = epsilon `meetLeq` a && epsilon `meetLeq` negate a--  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/Complex.hs view
@@ -1,175 +1,139 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} -module NumHask.Data.Complex where+-- | Complex numbers.+module NumHask.Data.Complex+  ( Complex (..),+    (+:),+    realPart,+    imagPart,+    normSquared,+  )+where  import Data.Data (Data)-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 GHC.Generics+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Metric+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Data.Integral-import Prelude-  hiding (Num(..), (/), atan, cos, exp, log, negate, pi, recip, sin, sqrt)-import qualified Prelude as P (Ord(..), (&&), (<), (<=), (==), (>), otherwise)+import Prelude hiding+  ( Num (..),+    atan,+    atan2,+    ceiling,+    cos,+    exp,+    floor,+    fromIntegral,+    log,+    negate,+    pi,+    properFraction,+    recip,+    round,+    sin,+    sqrt,+    truncate,+    (/),+  ) --- -------------------------------------------------------------------------------- The Complex type-infix 6 :++-- $setup+--+-- >>> import NumHask.Prelude+-- >>> :m -Prelude --- | Complex numbers are an algebraic type.+-- | The underlying representation is a newtype-wrapped tuple, compared with the base datatype. This was chosen to facilitate the use of DerivingVia.+newtype Complex a = Complex {complexPair :: (a, a)}+  deriving stock+    ( Eq,+      Show,+      Read,+      Generic,+      Data,+      Functor+    )+  deriving+    ( Additive,+      Subtractive,+      Basis,+      Direction,+      Epsilon,+      JoinSemiLattice,+      MeetSemiLattice,+      LowerBounded,+      UpperBounded,+      ExpField+    )+    via (EuclideanPair a)++infixl 6 +:++-- | Complex number constructor. ----- For a complex number @z@, @'abs' z@ is a number with the magnitude of @z@,--- but oriented in the positive real direction, whereas @'sign' z@--- has the phase of @z@, but unit magnitude.+-- Internally, Complex derives most instances via EuclideanPair. For instance, ----- The 'Foldable' and 'Traversable' instances traverse the real part first.-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-           )+-- >>> sqrt (1.0 +: (-1.0)) :: Complex Double+-- Complex {complexPair = (1.0986841134678098,-0.45508986056222733)}+--+-- >>> sqrt ((-1.0) +: 0.0) :: Complex Double+-- Complex {complexPair = (6.123233995736766e-17,1.0)}+(+:) :: a -> a -> Complex a+(+:) r i = Complex (r, i)  -- | Extracts the real part of a complex number. realPart :: Complex a -> a-realPart (x :+ _) = x+realPart (Complex (x, _)) = x  -- | Extracts the imaginary part of a complex number. imagPart :: Complex a -> a-imagPart (_ :+ y) = y--instance (Additive a) => Additive (Complex a) where-  (rx :+ ix) + (ry :+ iy) = (rx + ry) :+ (ix + iy)-  zero = zero :+ zero--instance (Subtractive a) => Subtractive (Complex a) where-  negate (rx :+ ix) = negate rx :+ negate ix--instance (Distributive a, Subtractive a) =>-  Distributive (Complex a)+imagPart (Complex (_, y)) = y -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+  (Subtractive a, Multiplicative a) =>+  Multiplicative (Complex a)+  where+  (Complex (r, i)) * (Complex (r', i')) =+    Complex (r * r' - i * i', i * r' + i' * r)+  one = one +: zero -instance (Subtractive a, Divisive a) =>-  Divisive (Complex a) where-  recip (rx :+ ix) = (rx * d) :+ (negate ix * d)+instance+  (Subtractive a, Divisive a) =>+  Divisive (Complex a)+  where+  recip (Complex (r, i)) = (r * d) +: (negate i * d)     where-      d = recip ((rx * rx) + (ix * ix))--instance (Additive a, FromIntegral a b) =>-  FromIntegral (Complex a) b where-  fromIntegral_ x = fromIntegral_ x :+ zero--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)--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)--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)--instance (Field a, Subtractive a) => Field (Complex a)+      d = recip ((r * r) + (i * i)) -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-        | 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 +)+instance+  (Additive a, FromIntegral a b) =>+  FromIntegral (Complex a) b+  where+  fromIntegral x = fromIntegral x +: zero  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)--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)--instance (BoundedJoinSemiLattice a) => BoundedJoinSemiLattice (Complex a) where-  bottom = bottom :+ bottom--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---- | 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)+  adj (Complex (r, i)) = r +: negate i --- | The nonnegative magnitude of a complex number.-{-# SPECIALISE magnitude :: Complex Double -> Double #-}+-- Can't use DerivingVia due to extra Whole constraints+instance (Subtractive a, QuotientField a) => QuotientField (Complex a) where+  type Whole (Complex a) = Complex (Whole a) -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+  properFraction (Complex (x, y)) =+    (Complex (xwhole, ywhole), Complex (xfrac, yfrac))+    where+      (xwhole, xfrac) = properFraction x+      (ywhole, yfrac) = properFraction y --- | 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 #-}+  round (Complex (x, y)) = Complex (round x, round y)+  ceiling (Complex (x, y)) = Complex (ceiling x, ceiling y)+  floor (Complex (x, y)) = Complex (floor x, floor y)+  truncate (Complex (x, y)) = Complex (truncate x, truncate y) -phase :: (RealFloat a) => Complex a -> a-phase (0 :+ 0) = 0 -- SLPJ July 97 from John Peterson-phase (x :+ y) = atan2 y x+-- | The squared norm: frequently useful, and doesn't require the+-- ability to take square roots.+normSquared :: (Distributive a) => Complex a -> a+normSquared (Complex (x, y)) = x * x + y * y
src/NumHask/Data/Integral.hs view
@@ -1,42 +1,51 @@-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeFamilies #-}-{-# OPTIONS_GHC -Wall #-}- -- | Integral classes module NumHask.Data.Integral-  ( Integral(..)-  , ToIntegral(..)-  , ToInteger-  , toInteger-  , FromIntegral(..)-  , FromInteger(..)-  , fromIntegral-  , even-  , odd-  , (^)-  , (^^)+  ( Integral (..),+    ToIntegral (..),+    ToInt,+    FromIntegral (..),+    FromInt,+    FromInteger (..),+    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+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Ord+import Data.Word (Word, Word16, Word32, Word64, Word8)+import GHC.Natural (Natural (..), naturalFromInteger)+import NumHask.Algebra.Additive+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import Prelude (Double, Float, Int, Integer, fst, snd, (.))+import Prelude qualified as P --- | Integral laws+-- $setup ----- > b == zero || b * (a `div` b) + (a `mod` b) == a-class (Distributive a) =>-  Integral a where+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | An Integral is anything that satisfies the law:+--+-- prop> \a b -> b == zero || b * (a `div` b) + (a `mod` b) == a+--+-- >>> 3 `divMod` 2+-- (1,1)+--+-- >>> (-3) `divMod` 2+-- (-2,1)+--+-- >>> (-3) `quotRem` 2+-- (-1,-1)+class+  (Distributive a) =>+  Integral a+  where   infixl 7 `div`, `mod`   div :: a -> a -> a   div a1 a2 = fst (divMod a1 a2)@@ -100,7 +109,7 @@   divMod = P.divMod   quotRem = P.quotRem -instance Integral b => Integral (a -> b) where+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))@@ -108,18 +117,28 @@   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)) +-- |+-- >>> even 2+-- True+even :: (P.Eq a, Integral a) => a -> P.Bool+even n = n `rem` (one + one) P.== zero++-- |+-- >>> odd 3+-- True+odd :: (P.Eq a, Integral a) => a -> P.Bool+odd = P.not . even+ -- | toIntegral is kept separate from Integral to help with compatability issues.+-- -- > toIntegral a == a class ToIntegral a b where-  toIntegral :: a -> b-  default toIntegral :: (a ~ b) => a -> b-  toIntegral = P.id+  {-# MINIMAL toIntegral #-} -type ToInteger a = ToIntegral a Integer+  toIntegral :: a -> b --- fitting in with legacy naming conventions.-toInteger :: (ToInteger a) => a -> Integer-toInteger = toIntegral+-- | Convert to an 'Int'+type ToInt a = ToIntegral a Int  instance ToIntegral Integer Integer where   toIntegral = P.id@@ -160,6 +179,39 @@ instance ToIntegral Int Int where   toIntegral = P.id +instance ToIntegral Integer Int where+  toIntegral = P.fromIntegral++instance ToIntegral Natural Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int8 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int16 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int32 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Int64 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word8 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word16 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word32 Int where+  toIntegral = P.fromIntegral++instance ToIntegral Word64 Int where+  toIntegral = P.fromIntegral+ instance ToIntegral Natural Natural where   toIntegral = P.id @@ -190,153 +242,259 @@ instance ToIntegral Word64 Word64 where   toIntegral = P.id --- | fromIntegral abstracts the codomain type, compared with the preludes Integral type.--- > fromIntegral_ a == a+-- | Polymorphic version of fromInteger ----- fromIntegral is widely used as general coercion, hence the underscore for the operator.+-- > fromIntegral a == a class FromIntegral a b where-  fromIntegral_ :: b -> a-  default fromIntegral_ :: (a ~ b) => b -> a-  fromIntegral_ = P.id+  {-# MINIMAL fromIntegral #-} --- | general coercion via Integer-fromIntegral :: (FromInteger b, ToInteger a) => a -> b-fromIntegral = fromInteger . toInteger+  fromIntegral :: b -> a +-- | Convert from an 'Int'+type FromInt a = FromIntegral a Int+ instance (FromIntegral a b) => FromIntegral (c -> a) b where-  fromIntegral_ i _ = fromIntegral_ i+  fromIntegral i _ = fromIntegral i  instance FromIntegral Double Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Float Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Integer Integer where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Natural Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = naturalFromInteger  instance FromIntegral Int8 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int16 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int32 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Int64 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word8 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word16 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word32 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger  instance FromIntegral Word64 Integer where-  fromIntegral_ = P.fromInteger+  fromIntegral = P.fromInteger +instance FromIntegral Double Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Float Int where+  fromIntegral = P.fromIntegral+ instance FromIntegral Int Int where-  fromIntegral_ = P.id+  fromIntegral = P.id +instance FromIntegral Integer Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Natural Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int8 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int16 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int32 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Int64 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word8 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word16 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word32 Int where+  fromIntegral = P.fromIntegral++instance FromIntegral Word64 Int where+  fromIntegral = P.fromIntegral+ instance FromIntegral Natural Natural where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int8 Int8 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int16 Int16 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int32 Int32 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Int64 Int64 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word Word where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word8 Word8 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word16 Word16 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word32 Word32 where-  fromIntegral_ = P.id+  fromIntegral = P.id  instance FromIntegral Word64 Word64 where-  fromIntegral_ = P.id+  fromIntegral = P.id --- | ghc defaulting rules and, it seems, -XExtendedDefaultRules do not permit multiple parameter typeclasses to be in the mix when types are resolved, hence the simpler `type FromInteger a = FromIntegral a Integer` does not suffice.+-- | 'fromInteger' is special in two ways:+--+-- - numeric integral literals (like "42") are interpreted specifically as "fromInteger (42 :: GHC.Num.Integer)". The prelude version is used as default (or whatever fromInteger is in scope if RebindableSyntax is set).+--+-- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that constraints on 'fromInteger' need to be in a form @C v@, where v is a Num or a subclass of Num.+--+-- So a type synonym such as @type FromInteger a = FromIntegral a Integer@ doesn't work well with type defaulting; hence the need for a separate class. class FromInteger a where   fromInteger :: Integer -> a-  default fromInteger :: (FromIntegral a Integer) => Integer -> a-  fromInteger = fromIntegral_ -instance FromInteger Integer-instance FromInteger Int-instance FromInteger Double-instance FromInteger Float-instance FromInteger Natural-instance FromInteger Int8-instance FromInteger Int16-instance FromInteger Int32-instance FromInteger Int64-instance FromInteger Word-instance FromInteger Word8-instance FromInteger Word16-instance FromInteger Word32-instance FromInteger Word64+instance FromInteger Double where+  fromInteger = P.fromInteger --- $operators+instance FromInteger Float where+  fromInteger = P.fromInteger -even :: (P.Eq a, Integral a) => a -> P.Bool-even n = n `rem` (one + one) P.== zero+instance FromInteger Int where+  fromInteger = P.fromInteger -odd :: (P.Eq a, Integral a) => a -> P.Bool-odd = P.not . even+instance FromInteger Integer where+  fromInteger = P.id ----------------------------------------------------------- | 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+instance FromInteger Natural where+  fromInteger = naturalFromInteger++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++deriving instance (FromInteger a) => FromInteger (Sum a)++deriving instance (FromInteger a) => FromInteger (Product a)++infixr 8 ^^++-- | raise a number to an 'Integral' power+--+-- >>> 2 ^^ 3+-- 8.0+--+-- >>> 2 ^^ (-2)+-- 0.25+(^^) ::+  (P.Ord b, Divisive a, Subtractive b, Integral b) =>+  a ->+  b ->+  a+x0 ^^ y0 =+  case compare y0 zero of+    EQ -> one+    GT -> f x0 y0+    LT -> recip (x0 ^^ negate y0)   where+    f x y+      | even y = f (x * x) (y `quot` two)+      | y P.== one = x+      | P.otherwise = g (x * x) (y `quot` two) x+    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) -  -- 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]+infixr 8 ^ -(^^)-  :: (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)+-- | raise a number to an 'Int' power+--+-- Note: This differs from (^) found in prelude which is a partial function (it errors on negative integrals). This is a monomorphic version of '(^^)' provided to help reduce ambiguous type noise in common usages.+--+-- >>> 2 ^ 3+-- 8.0+--+-- >>> 2 ^ (-2)+-- 0.25+(^) ::+  (Divisive a) => a -> Int -> a+(^) x n = x ^^ n++infixr 8 ^+++-- | raise a number to a non-negative 'Natural' power.+--+-- Unlike '(^^)' and '(^)', this does not require 'Divisive' or 'Subtractive'+-- constraints, so it works for unsigned types such as 'Natural' and 'Word64'.+--+-- >>> 2 ^+ 3+-- 8+--+-- >>> 2 ^+ 0+-- 1+(^+) ::+  (Multiplicative a) => a -> Natural -> a+x0 ^+ y0 =+  case compare y0 zero of+    EQ -> one+    GT -> f x0 y0+    LT -> P.error "(^+): negative exponent"+  where+    f x y+      | even y = f (x * x) (y `quot` two)+      | y P.== one = x+      | P.otherwise = g (x * x) (y `quot` two) x+    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)
− src/NumHask/Data/LogField.hs
@@ -1,306 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveFoldable #-}-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-}--module NumHask.Data.LogField-  ( -- * @LogField@-    LogField()-  , logField-  , fromLogField-    -- ** Isomorphism to log-domain-  , logToLogField-  , logFromLogField-    -- ** Additional operations-  , accurateSum-  , accurateProduct-  , pow-  )-where--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)-import qualified Data.Foldable as F---- LogField is adapted from LogFloat--------------------------------------------------------------------                                                  ~ 2015.08.06--- |--- Module      :  Data.Number.LogFloat--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  portable (with CPP, FFI)--- Link        :  https://hackage.haskell.org/package/logfloat---------------------------------------------------------------------------------------------------------------------------------------- | A @LogField@ is just a 'Field' with a special interpretation.--- The 'LogField' function is presented instead of the constructor,--- in order to ensure semantic conversion. At present the 'Show'--- instance will convert back to the normal-domain, and hence will--- underflow at that point. This behavior may change in the future.------ Because 'logField' performs the semantic conversion, we can use--- operators which say what we *mean* rather than saying what we're--- actually doing to the underlying representation. That is,--- equivalences like the following are true[1] thanks to type-class--- overloading:------ > logField (p + q) == logField p + logField q--- > logField (p * q) == logField p * logField q--------- Performing operations in the log-domain is cheap, prevents--- underflow, and is otherwise very nice for dealing with miniscule--- probabilities. However, crossing into and out of the log-domain--- is expensive and should be avoided as much as possible. In--- particular, if you're doing a series of multiplications as in--- @lp * LogField q * LogField r@ it's faster to do @lp * LogField--- (q * r)@ if you're reasonably sure the normal-domain multiplication--- won't underflow; because that way you enter the log-domain only--- once, instead of twice. Also note that, for precision, if you're--- doing more than a few multiplications in the log-domain, you--- should use 'product' rather than using '(*)' repeatedly.------ Even more particularly, you should /avoid addition/ whenever--- possible. Addition is provided because sometimes we need it, and--- the proper implementation is not immediately apparent. However,--- between two @LogField@s addition requires crossing the exp\/log--- boundary twice; with a @LogField@ and a 'Double' it's three--- times, since the regular number needs to enter the log-domain--- first. This makes addition incredibly slow. Again, if you can--- parenthesize to do normal-domain operations first, do it!------ [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-           )--------------------------------------------------------------------- To show it, we want to show the normal-domain value rather than--- the log-domain value. Also, if someone managed to break our--- invariants (e.g. by passing in a negative and noone's pulled on--- the thunk yet) then we want to crash before printing the--- constructor, rather than after.  N.B. This means the show will--- 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)--------------------------------------------------------------------- | Constructor which does semantic conversion from normal-domain--- to log-domain. Throws errors on negative and NaN inputs. If @p@--- is non-negative, then following equivalence holds:------ > logField p == logToLogField (log p)-logField :: (ExpField a) => a -> LogField a-{-# INLINE [0] logField #-}-logField = LogField . log---- | 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):------ > fromLogField == exp . logFromLogField----fromLogField :: ExpField a => LogField a -> a-{-# 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-"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-{-# INLINE [0] expm1 #-}-expm1 x = exp x - one--{-# RULES-"expm1/log1p" forall x . expm1 (log1p x) = x-"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')))--  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, Eq a) =>-  Multiplicative (LogField a) where-  (LogField x) * (LogField y)-    | x == negInfinity || y == negInfinity = LogField negInfinity-    | otherwise = LogField (x + y)--  one = LogField zero--instance (LowerBoundedField a, Eq a) =>-  Divisive (LogField a) where-  recip (LogField x) = LogField $ negate x--instance (Ord a, LowerBoundedField a, ExpField a) =>-  Distributive (LogField a)--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 (FromIntegral a b, ExpField a) => FromIntegral (LogField a) b where-  fromIntegral_ = logField . fromIntegral_--instance (ToIntegral a b, ExpField a) => ToIntegral (LogField a) b where-  toIntegral = toIntegral . fromLogField--instance (FromRatio a b, ExpField a) => FromRatio (LogField a) b where-  fromRatio = logField . fromRatio--instance (ToRatio a b, ExpField a) => ToRatio (LogField a) b where-  toRatio = toRatio . fromLogField--instance (Ord a) => JoinSemiLattice (LogField a) where-  (\/) = min--instance (Ord a) => MeetSemiLattice (LogField a) where-  (/\) = max--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 (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) => Field (LogField a)--instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>-  LowerBoundedField (LogField a)--instance (Ord a, ExpField a, LowerBoundedField a) =>-  IntegralDomain (LogField a) where--instance (Ord a, ExpField a, LowerBoundedField a, UpperBoundedField a) =>-  UpperBoundedField (LogField a)--instance (Ord a, LowerBoundedField a, UpperBoundedField a, ExpField a) =>-  Signed (LogField a) where-  sign a-    | a == negInfinity = zero-    | otherwise = one-  abs = id--------------------------------------------------------------------- | /O(1)/. Compute powers in the log-domain; that is, the following--- equivalence holds (modulo underflow and all that):------ > LogField (p ** m) == LogField p `pow` m------ /Since: 0.13/-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'---- Some good test cases:--- for @logsumexp == log . accurateSum . map exp@:---     logsumexp[0,1,0] should be about 1.55--- for correctness of avoiding underflow:---     logsumexp[1000,1001,1000]   ~~ 1001.55 ==  1000 + 1.55---     logsumexp[-1000,-999,-1000] ~~ -998.45 == -1000 + 1.55------ | /O(n)/. Compute the sum of a finite list of 'LogField's, being--- careful to avoid underflow issues. That is, the following--- equivalence holds (modulo underflow and all that):------ > LogField . accurateSum == accurateSum . map LogField------ /N.B./, this function requires two passes over the input. Thus,--- 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 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---- | /O(n)/. Compute the product of a finite list of 'LogField's,--- being careful to avoid numerical error due to loss of precision.--- That is, the following equivalence holds (modulo underflow and--- all that):------ > LogField . accurateProduct == accurateProduct . map LogField-{-# INLINE accurateProduct #-}-accurateProduct :: (ExpField 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')
− src/NumHask/Data/Pair.hs
@@ -1,215 +0,0 @@-{-# 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)--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 (FromIntegral a b) => FromIntegral (Pair a) b where-  fromIntegral_ x = P.pure (fromIntegral_ x)--instance (FromRatio a b) => FromRatio (Pair a) b 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
@@ -1,82 +1,193 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RoleAnnotations #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} -module NumHask.Data.Positive where+-- |  A positive number type, defined as existing on [zero, +infinity)+module NumHask.Data.Positive+  ( Positive (..),+    positive,+    maybePositive,+    positive_,+    Monus (..),+    Addus (..),+    MonusSemiField,+  )+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 Control.Category ((>>>))+import Data.Bool (bool)+import Data.Maybe+import NumHask.Algebra.Action+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Metric+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Data.Integral-import NumHask.Exception-import qualified Prelude as P+import NumHask.Data.Rational+import NumHask.Data.Wrapped+import Numeric.Natural (Natural, minusNaturalMaybe)+import Prelude (Eq, Ord, Show)+import Prelude qualified as P -newtype Positive a = Positive { unPositive :: a }+-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude+-- >>> import NumHask.Data.Positive++-- | A positive number is a number that is contained in [zero,+infinity).+--+-- >>> 1 :: Positive Int+-- UnsafePositive {unPositive = 1}+--+--+-- >>> -1 :: Positive Int+-- ...+--     • No instance for ‘Subtractive (Positive Int)’+--         arising from a use of syntactic negation+-- ...+--+-- zero is positive+--+-- >>> positive 0 == zero+-- True+--+-- The main constructors:+--+-- >>> positive (-1)+-- UnsafePositive {unPositive = 0}+--+-- >>> maybePositive (-1)+-- Nothing+--+-- >>> UnsafePositive (-1)+-- UnsafePositive {unPositive = -1}+newtype Positive a = UnsafePositive {unPositive :: a}+  deriving stock+    (Eq, Ord, Show)   deriving-    ( P.Show-    , P.Eq-    , P.Ord-    , Additive-    , Multiplicative-    , Divisive-    , Distributive-    , IntegralDomain-    , Field-    , ExpField-    , TrigField-    , Integral-    , Signed-    , JoinSemiLattice-    , MeetSemiLattice-    , Epsilon+    ( Additive,+      Multiplicative,+      Divisive,+      Integral,+      FromInteger,+      FromRational,+      Basis,+      Direction,+      Epsilon,+      AdditiveAction,+      SubtractiveAction,+      MultiplicativeAction,+      DivisiveAction,+      JoinSemiLattice,+      MeetSemiLattice,+      UpperBounded     )+    via (Wrapped a) --- not sure if this is correct or needed-type role Positive representational+instance (JoinSemiLattice a, Integral a) => FromIntegral (Positive a) a where+  fromIntegral a = positive a -positive :: (P.Ord a, Additive a) => a -> P.Maybe (Positive a)-positive a-  | a P.< zero = P.Nothing-  | P.otherwise = P.Just (Positive a)+instance (FromIntegral a b) => FromIntegral (Positive a) b where+  fromIntegral a = UnsafePositive (fromIntegral 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 (ToIntegral a b) => ToIntegral (Positive a) b where+  toIntegral (UnsafePositive a) = toIntegral 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")+instance (FromRatio a b) => FromRatio (Positive a) b where+  fromRatio a = UnsafePositive (fromRatio a) -  (Positive a) - (Positive b)-    | a P.>= b = Positive (a - b)-    | P.otherwise = throw (NumHaskException "subtracting a larger positive")+instance (ToRatio a b) => ToRatio (Positive a) b where+  toRatio (UnsafePositive a) = toRatio a -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 (Additive a, JoinSemiLattice a) => LowerBounded (Positive a) where+  bottom = UnsafePositive zero -instance (P.Ord a, UpperBoundedField a) =>-  UpperBoundedField (Positive a) where-  infinity = Positive infinity+instance QuotientField (Positive P.Double) where+  type Whole (Positive P.Double) = Positive P.Int+  properFraction (UnsafePositive a) = (\(n, r) -> (UnsafePositive n, UnsafePositive r)) (P.properFraction a)+  ceiling = properFraction >>> P.fst >>> (+ one)+  floor = properFraction >>> P.fst+  truncate = floor+  round x = case properFraction x of+    (n, r) ->+      let half_up = r + half+       in case P.compare half_up one of+            P.LT -> n+            P.EQ -> bool (n + one) n (even n)+            P.GT -> n + one -instance (P.Ord a, UpperBoundedField a) => P.Bounded (Positive a) where-  minBound = zero-  maxBound = infinity+-- | Constructor which returns zero for a negative number.+--+-- >>> positive (-1)+-- UnsafePositive {unPositive = 0}+positive :: (Additive a, JoinSemiLattice a) => a -> Positive a+positive a = UnsafePositive (a \/ zero) --- Metric-instance (Normed a a) =>-  Normed a (Positive a) where-  normL1 a = Positive (normL1 a)-  normL2 a = Positive (normL2 a)+-- | Unsafe constructor.+--+-- >>> positive_ (-one)+-- UnsafePositive {unPositive = -1}+positive_ :: a -> Positive a+positive_ = UnsafePositive -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)+-- | Constructor which returns Nothing if a negative number is supplied.+--+-- >>> maybePositive (-one)+-- Nothing+maybePositive :: (Additive a, MeetSemiLattice a) => a -> Maybe (Positive a)+maybePositive a = bool Nothing (Just (UnsafePositive a)) (zero `meetLeq` a)++instance (Subtractive a, JoinSemiLattice a) => Monus (Positive a) where+  (UnsafePositive a) ∸ (UnsafePositive b) = positive (a - b)++-- | A field but with truncated subtraction.+type MonusSemiField a = (Monus a, Distributive a, Divisive a)++-- | <https://en.wikipedia.org/wiki/Monus Monus> or truncated subtraction.+--+-- @since 0.12+--+-- >>> positive 4 ∸ positive 7+-- UnsafePositive {unPositive = 0}+--+-- >>> 4 ∸ 7 :: Positive Int+-- UnsafePositive {unPositive = 0}+class Monus a where+  {-# MINIMAL (∸) #-}++  infixl 6 ∸+  (∸) :: a -> a -> a+  default (∸) :: (LowerBounded a, Subtractive a) => a -> a -> a+  a ∸ b = bottom \/ (a - b)++-- | A newtype wrapper intended for defining Monus instances by:+-- "x ∸ y = if x < y then zero else x - y"+newtype MonusFromOrd a = MonusFromOrd a+  deriving (Eq, Ord, Additive, Subtractive)++instance (Ord a, Subtractive a) => Monus (MonusFromOrd a) where+  x ∸ y+    | x P.< y = zero+    | P.otherwise = x - y++-- | It appears that Haskell doesn't have any built in truncated+-- subtraction operation for Word+deriving via MonusFromOrd P.Word instance Monus P.Word++instance Monus Natural where+  x ∸ y = fromMaybe 0 (minusNaturalMaybe x y)++-- | Truncated addition+--+-- @since 0.12+class Addus a where+  {-# MINIMAL (∔) #-}+  infixl 6 ∔+  (∔) :: a -> a -> a+  default (∔) :: (UpperBounded a, JoinSemiLattice a, Additive a) => a -> a -> a+  a ∔ b = top \/ (a + b)
src/NumHask/Data/Rational.hs view
@@ -1,70 +1,74 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wall #-} --- | Integral classes+-- | Rational classes module NumHask.Data.Rational-  ( Ratio(..)-  , Rational-  , ToRatio(..)-  , ToRational-  , toRational-  , FromRatio(..)-  , FromRational-  , fromRational-  , fromRational'-  , fromBaseRational-  -- * $integral_functionality-  , reduce-  , gcd+  ( Ratio (..),+    Rational,+    ToRatio (..),+    FromRatio (..),+    FromRational (..),+    reduce,+    gcd,+    numerator,+    denominator,   ) where -import Data.Int (Int8, Int16, Int32, Int64)-import Data.Word (Word, Word8, Word16, Word32, Word64) import Data.Bool (bool)+import Data.Int (Int16, Int32, Int64, Int8)+import Data.Word (Word, Word16, Word32, Word64, Word8) 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 GHC.Natural (Natural (..))+import GHC.Real qualified+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Metric+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Data.Integral-import Prelude (Int, Integer, Rational, (.))-import qualified GHC.Real-import qualified Prelude as P+import Prelude (Eq (..), Int, Integer, Ord (..), Ordering (..), (.))+import Prelude qualified as P +-- $setup+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude++-- | A rational number, represented as the ratio of two 'Integral' numbers. data Ratio a = !a :% !a deriving (P.Show) -instance (P.Eq a, Additive a) => P.Eq (Ratio a) where-  a == b+-- | Ratio of two integers+type Rational = Ratio Integer++numerator :: Ratio a -> a+numerator (a :% _) = a++denominator :: Ratio a -> a+denominator (_ :% a) = a++instance (P.Eq a, P.Ord a, Subtractive a, EndoBased a, Absolute a, Integral a) => P.Eq (Ratio a) where+  a@(xa :% ya) == b@(xb :% yb)     | isRNaN a P.|| isRNaN b = P.False-    | P.otherwise = (x P.== x') P.&& (y P.== y')-      where-        (x:%y) = a-        (x':%y') = b+    | xa == zero P.&& xb == zero = P.True+    | xa == zero P.|| xb == zero = P.False+    | P.otherwise =+        let (xa' :% ya', xb' :% yb') = (reduce xa ya, reduce xb yb)+         in (xa' P.== xb') P.&& (ya' P.== yb') +-- | Has a zero denominator 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 -instance  (P.Ord a, Multiplicative a, Additive 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 (P.Ord a, Integral a, EndoBased a, Subtractive 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 (GCDConstraints a) => Additive (Ratio a) where+instance (P.Ord a, EndoBased a, Integral a, Ring 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@@ -73,74 +77,63 @@    zero = zero :% one -instance (GCDConstraints a) => Subtractive (Ratio a) where+instance (P.Ord a, EndoBased a, Integral a, Ring 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')+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Multiplicative (Ratio a) where+  (x :% y) * (x' :% y') = reduce (x * x') (y * y')    one = one :% one -instance (GCDConstraints a) =>-  Divisive (Ratio a) where+instance+  (P.Ord a, EndoBased a, Integral a, Ring a) =>+  Divisive (Ratio a)+  where   recip (x :% y)-    | sign x P.== negate one = negate y :% negate x+    | x P.< zero = 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, FromIntegral b a) => 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)+instance (P.Ord a, EndoBased a, Absolute a, ToInt a, Integral a, Ring a) => QuotientField (Ratio a) where+  type Whole (Ratio a) = Int+  properFraction (n :% d) = let (w, r) = quotRem n d in (toIntegral w, r :% d) -instance (GCDConstraints a, Field a) => LowerBoundedField (Ratio a)+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Basis (Ratio a) where+  type Mag (Ratio a) = Ratio a+  type Base (Ratio a) = Ratio a+  basis (n :% _) =+    case compare n zero of+      EQ -> zero+      GT -> one+      LT -> negate one+  magnitude (n :% d) = abs n :% abs d -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 (P.Ord a, Integral a, EndoBased a, Subtractive a) => JoinSemiLattice (Ratio a) where+  (\/) = P.max -instance (GCDConstraints a) => Normed (Ratio a) (Ratio a) where-  normL1 = abs-  normL2 = abs+instance (P.Ord a, Integral a, EndoBased a, Subtractive a) => MeetSemiLattice (Ratio a) where+  (/\) = P.min -instance (GCDConstraints a) => Metric (Ratio a) (Ratio a) where-  distanceL1 a b = normL1 (a - b)-  distanceL2 a b = normL2 (a - b)+instance (P.Ord a, EndoBased a, Integral a, Ring a) => Epsilon (Ratio a) -instance (GCDConstraints a, MeetSemiLattice a) => Epsilon (Ratio a)+instance (FromInteger a, Multiplicative a) => FromInteger (Ratio a) where+  fromInteger x = fromInteger x :% one  instance (FromIntegral a b, Multiplicative a) => FromIntegral (Ratio a) b where-  fromIntegral_ x = fromIntegral_ x :% one+  fromIntegral x = fromIntegral x :% one --- | toRatio is equivalent to `Real` in base, but is polymorphic in the Integral type.+-- | toRatio is equivalent to `GHC.Real.Real` in base, but is polymorphic in the Integral type.+--+-- >>> toRatio (3.1415927 :: Float) :: Ratio Integer+-- 13176795 :% 4194304 class ToRatio a b where   toRatio :: a -> Ratio b-  default toRatio :: (Ratio c ~ a, ToIntegral c Integer, ToRatio (Ratio b) b, FromInteger b) => a -> Ratio b-  toRatio (n :% d) = toRatio ((fromIntegral n :: b) :% fromIntegral d) -type ToRational a = ToRatio a Integer--toRational :: (ToRatio a Integer) => a -> Ratio Integer-toRational = toRatio- instance ToRatio Double Integer where   toRatio = fromBaseRational . P.toRational  instance ToRatio Float Integer where   toRatio = fromBaseRational . P.toRational -instance ToRatio Rational Integer where-  toRatio = fromBaseRational- instance ToRatio (Ratio Integer) Integer where   toRatio = P.id @@ -180,68 +173,62 @@ instance ToRatio Word64 Integer where   toRatio = fromBaseRational . P.toRational --- | `Fractional` in base splits into fromRatio and Field--- FIXME: work out why the default type isn't firing so that an explicit instance is needed--- for `FromRatio (Ratio Integer) Integer`+-- | `GHC.Real.Fractional` in base splits into fromRatio and Field+--+-- >>> fromRatio (5 :% 2 :: Ratio Integer) :: Double+-- 2.5 class FromRatio a b where   fromRatio :: Ratio b -> a-  -- default fromRatio :: (a ~ Ratio c, ToIntegral b c) => Ratio b -> a-  -- fromRatio (n :% d) = toIntegral n :% toIntegral d-  default fromRatio :: (Ratio b ~ a) => Ratio b -> a-  fromRatio = P.id  fromBaseRational :: P.Rational -> Ratio Integer fromBaseRational (n GHC.Real.:% d) = n :% d  instance FromRatio Double Integer where-  fromRatio (n:%d)= rationalToDouble n d+  fromRatio (n :% d) = rationalToDouble n d  instance FromRatio Float Integer where-  fromRatio (n:%d)= rationalToFloat n d+  fromRatio (n :% d) = rationalToFloat n d  instance FromRatio Rational Integer where-  fromRatio (n:%d) = n GHC.Real.% d--instance FromRatio (Ratio Integer) Integer where   fromRatio = P.id --- | with RebindableSyntax the literal '1.0' mean exactly `fromRational (1.0::GHC.Real.Rational)`.+-- | fromRational is special in two ways:+--+-- - numeric decimal literals (like "53.66") are interpreted as exactly "fromRational (53.66 :: GHC.Real.Ratio Integer)". The prelude version, GHC.Real.fromRational is used as default (or whatever is in scope if RebindableSyntax is set).+--+-- - The default rules in < https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 haskell2010> specify that contraints on 'fromRational' need to be in a form @C v@, where v is a Num or a subclass of Num.+--+-- So a type synonym of `type FromRational a = FromRatio a Integer` doesn't work well with type defaulting; hence the need for a separate class. class FromRational a where   fromRational :: P.Rational -> a-  default fromRational :: (FromRatio a Integer) => P.Rational -> a-  fromRational = fromRatio . fromBaseRational -instance FromRational Double-instance FromRational Float-instance FromRational Rational---- | Given that fromRational is reserved, fromRational' provides general conversion between numhask rationals.-fromRational' :: (FromRatio b Integer, ToRatio a Integer) => a -> b-fromRational' a = fromRatio (toRatio a :: Ratio Integer)+instance FromRational Double where+  fromRational (n GHC.Real.:% d) = rationalToDouble n d -instance (GCDConstraints a) => JoinSemiLattice (Ratio a) where-  (\/) = P.min+instance FromRational Float where+  fromRational (n GHC.Real.:% d) = rationalToFloat n d -instance (GCDConstraints a) => MeetSemiLattice (Ratio a) where-  (/\) = P.max+instance FromRational (Ratio Integer) where+  fromRational (n GHC.Real.:% d) = n :% d --- * $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+-- | 'reduce' 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 72 60+-- 6 :% 5+--+-- prop> \a b -> reduce a b == a :% b || b == zero+reduce ::+  (P.Ord a, Subtractive a, EndoBased 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+  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@@ -249,12 +236,15 @@ -- (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+-- Note: Since for signed fixed-width integer types, @'abs' 'GHC.Enum.minBound' < 0@,+-- the result may be negative if one of the arguments is @'GHC.Enum.minBound'@ (and+-- necessarily is if the other is @0@ or @'GHC.Enum.minBound'@) for such types.+--+-- >>> gcd 72 60+-- 12+gcd :: (P.Eq a, EndoBased 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)+  where+    gcd' a b+      | b P.== zero = a+      | P.otherwise = gcd' b (a `rem` b)
src/NumHask/Data/Wrapped.hs view
@@ -1,60 +1,62 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE RoleAnnotations #-}-{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} -module NumHask.Data.Wrapped where+-- | Wrapped numhask instances, useful for derivingvia situations to quickly specifiy a numhask friendly numerical type.+module NumHask.Data.Wrapped+  ( 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.Algebra.Abstract.Group-import NumHask.Analysis.Metric+import NumHask.Algebra.Action+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Lattice+import NumHask.Algebra.Metric+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring import NumHask.Data.Integral import NumHask.Data.Rational-import qualified Prelude as P+import Prelude qualified as P -newtype Wrapped a = Wrapped { unWrapped :: a }+-- | Wrapped numhask instances+newtype Wrapped a = Wrapped {unWrapped :: a}   deriving-    ( P.Show-    , P.Eq-    , P.Ord-    , Magma-    , Idempotent-    , Additive-    , Subtractive-    , Multiplicative-    , Divisive-    , Distributive-    , IntegralDomain-    , InvolutiveRing-    , StarSemiring-    , KleeneAlgebra-    , Field-    , ExpField-    , TrigField-    , Integral-    , Signed-    , MeetSemiLattice-    , JoinSemiLattice-    , Epsilon-    , UpperBoundedField-    , LowerBoundedField+    ( P.Show,+      P.Eq,+      P.Ord,+      Additive,+      Subtractive,+      Multiplicative,+      Divisive,+      ExpField,+      TrigField,+      StarSemiring,+      InvolutiveRing,+      Integral,+      FromInteger,+      FromRational,+      MeetSemiLattice,+      JoinSemiLattice,+      LowerBounded,+      UpperBounded,+      Basis,+      Direction,+      Epsilon,+      AdditiveAction,+      SubtractiveAction,+      MultiplicativeAction,+      DivisiveAction     ) --- 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)+instance+  (P.Ord a, P.Eq (Whole a), Integral (Whole a), Subtractive (Whole a), Subtractive a, QuotientField a) =>+  QuotientField (Wrapped a)+  where+  type Whole (Wrapped a) = Whole a+  properFraction (Wrapped a) = let (i, r) = properFraction a in (i, Wrapped r)  instance (FromIntegral a b) => FromIntegral (Wrapped a) b where-  fromIntegral_ a = Wrapped (fromIntegral_ a)+  fromIntegral a = Wrapped (fromIntegral a)  instance (ToIntegral a b) => ToIntegral (Wrapped a) b where   toIntegral (Wrapped a) = toIntegral a@@ -64,11 +66,3 @@  instance (ToRatio a b) => ToRatio (Wrapped a) b where   toRatio (Wrapped a) = toRatio a--instance (Normed a b) => Normed (Wrapped a) (Wrapped b) where-  normL1 (Wrapped a) = Wrapped (normL1 a)-  normL2 (Wrapped a) = Wrapped (normL2 a)--instance (Metric a b) => Metric (Wrapped a) (Wrapped b) where-  distanceL1 (Wrapped a) (Wrapped b) = Wrapped (distanceL1 a b)-  distanceL2 (Wrapped a) (Wrapped b) = Wrapped (distanceL2 a b)
src/NumHask/Exception.hs view
@@ -1,15 +1,15 @@-{-# OPTIONS_GHC -Wall #-}-+-- | Exceptions arising within numhask. module NumHask.Exception-  ( NumHaskException(..)-  , throw-  ) where+  ( NumHaskException (..),+    throw,+  )+where -import qualified Prelude as P import Control.Exception-import Data.Typeable (Typeable)+import Prelude qualified as P -newtype NumHaskException = NumHaskException { errorMessage :: P.String }-  deriving (P.Show, Typeable)+-- | A numhask exception.+newtype NumHaskException = NumHaskException {errorMessage :: P.String}+  deriving (P.Show)  instance Exception NumHaskException
+ src/NumHask/Prelude.hs view
@@ -0,0 +1,95 @@+{-# OPTIONS_HADDOCK prune #-}++-- | A prelude composed by overlaying numhask on Prelude, together with a few minor tweaks needed for RebindableSyntax.+module NumHask.Prelude+  ( -- * numhask exports+    module NumHask.Algebra.Additive,+    module NumHask.Algebra.Field,+    module NumHask.Algebra.Group,+    module NumHask.Algebra.Lattice,+    module NumHask.Algebra.Action,+    module NumHask.Algebra.Multiplicative,+    module NumHask.Algebra.Ring,+    module NumHask.Algebra.Metric,+    module NumHask.Data.Complex,+    module NumHask.Data.Integral,+    module NumHask.Data.Rational,+    module NumHask.Exception,++    -- * rebindables+    -- $rebindables+    fromString,+    ifThenElse,+    fromList,+    fromListN,+    Natural (..),+    module GHC.OverloadedLabels,++    -- * Modules you can't live without+    module Data.Bool,+    module Data.Kind,+    module GHC.Generics,+    module Control.Applicative,+    module Data.Traversable,+    module Data.Semigroup,+    module Data.Maybe,++    -- * Data.Function+    module Data.Function,++    -- * Control.Category++    -- Putting id back.+    module Control.Category,++    -- * Data.Foldable+    module Data.Foldable,++    -- * The Prelude+    module Prelude,+  )+where++import Control.Applicative+import Control.Category+import Data.Bool+import Data.Foldable hiding (product, sum)+import Data.Function hiding (id, (.))+import Data.Kind+import Data.Maybe+import Data.Semigroup hiding (Product (..), Sum (..))+import Data.Traversable+import GHC.Exts+import GHC.Generics+import GHC.Natural (Natural (..))+import GHC.OverloadedLabels+import NumHask.Algebra.Action+import NumHask.Algebra.Additive+import NumHask.Algebra.Field+import NumHask.Algebra.Group+import NumHask.Algebra.Lattice+import NumHask.Algebra.Metric+import NumHask.Algebra.Multiplicative+import NumHask.Algebra.Ring+import NumHask.Data.Complex+import NumHask.Data.Integral+import NumHask.Data.Rational+import NumHask.Exception+import Prelude hiding (Integral (..), Rational, abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, even, exp, floor, fromInteger, fromIntegral, fromRational, gcd, id, log, logBase, negate, odd, pi, product, properFraction, recip, round, signum, sin, sinh, sqrt, subtract, sum, tan, tanh, toInteger, toRational, truncate, (*), (**), (+), (-), (.), (/), (^), (^^))++-- $usage+--+-- >>> :m -Prelude+-- >>> :set -XRebindableSyntax+-- >>> import NumHask.Prelude+-- >>> 1+1+-- 2++-- $rebindables+--+-- Using different types for numbers requires RebindableSyntax.  This then removes base-level stuff that has to be put back in.++-- | RebindableSyntax splats this, and I'm not sure where it exists in GHC land+ifThenElse :: Bool -> a -> a -> a+ifThenElse True x _ = x+ifThenElse False _ y = y