Highly polymorphic vector space operations on sparse and free vector spaces.
Contributions and bug reports are welcome!
Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
-Edward Kmett
Low-dimensional linear algebra primitives for Haskell.
Home Page: http://hackage.haskell.org/package/linear
License: Other
[1 of 1] Compiling Main ( /tmp/linear-1.15-17656/linear-1.15/dist/setup/setup.hs, /tmp/linear-1.15-17656/linear-1.15/dist/setup/Main.o )
Linking /tmp/linear-1.15-17656/linear-1.15/dist/setup/setup ...
Configuring linear-1.15...
Dependency adjunctions ==4.2: using adjunctions-4.2
Dependency base ==4.7.0.1: using base-4.7.0.1
Dependency binary ==0.7.1.0: using binary-0.7.1.0
Dependency containers ==0.5.5.1: using containers-0.5.5.1
Dependency distributive ==0.4.4: using distributive-0.4.4
Dependency ghc-prim ==0.3.1.0: using ghc-prim-0.3.1.0
Dependency hashable ==1.2.2.0: using hashable-1.2.2.0
Dependency lens ==4.4.0.2: using lens-4.4.0.2
Dependency reflection ==1.5.1: using reflection-1.5.1
Dependency semigroupoids ==4.2: using semigroupoids-4.2
Dependency semigroups ==0.15.4: using semigroups-0.15.4
Dependency tagged ==0.7.3: using tagged-0.7.3
Dependency template-haskell ==2.9.0.0: using template-haskell-2.9.0.0
Dependency transformers ==0.3.0.0: using transformers-0.3.0.0
Dependency unordered-containers ==0.2.5.1: using unordered-containers-0.2.5.1
Dependency vector ==0.10.12.1: using vector-0.10.12.1
Dependency void ==0.6.1: using void-0.6.1
Using Cabal-1.20.0.0 compiled by ghc-7.8
Using compiler: ghc-7.8.3
Using install prefix: /home/ubuntu/.cabal
Binaries installed in: /home/ubuntu/haskell/stackage/sandbox/bin
Libraries installed in:
/home/ubuntu/haskell/stackage/sandbox/lib/x86_64-linux-ghc-7.8.3/linear-1.15
Private binaries installed in: /home/ubuntu/.cabal/libexec
Data files installed in:
/home/ubuntu/haskell/stackage/sandbox/share/x86_64-linux-ghc-7.8.3/linear-1.15
Documentation installed in:
/home/ubuntu/haskell/stackage/sandbox/share/doc/linear-1.15
Configuration files installed in: /home/ubuntu/.cabal/etc
Using alex version 3.1.3 found on system at:
/home/ubuntu/haskell/stackage/sandbox/bin/alex
Using ar found on system at: /usr/bin/ar
Using c2hs version 0.19.1 found on system at:
/home/ubuntu/haskell/stackage/sandbox/bin/c2hs
Using cpphs version 1.18.6 found on system at:
/home/ubuntu/haskell/stackage/sandbox/bin/cpphs
No ffihugs found
Using gcc version 4.6 found on system at: /usr/bin/gcc
Using ghc version 7.8.3 found on system at: /opt/ghc/7.8.3/bin/ghc
Using ghc-pkg version 7.8.3 found on system at: /opt/ghc/7.8.3/bin/ghc-pkg
No greencard found
Using haddock version 2.14.3 found on system at: /opt/ghc/7.8.3/bin/haddock
Using happy version 1.19.4 found on system at:
/home/ubuntu/haskell/stackage/sandbox/bin/happy
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.67 found on system at: /opt/ghc/7.8.3/bin/hpc
Using hsc2hs version 0.67 found on system at: /opt/ghc/7.8.3/bin/hsc2hs
Using hscolour version 1.20 found on system at:
/home/ubuntu/haskell/stackage/sandbox/bin/HsColour
No hugs found
No jhc found
Using ld found on system at: /usr/bin/ld
No lhc found
No lhc-pkg found
No nhc98 found
Using pkg-config version 0.26 found on system at: /usr/bin/pkg-config
Using strip found on system at: /usr/bin/strip
Using tar found on system at: /bin/tar
No uhc found
creating dist/build/autogen
creating dist/build
creating dist/build/autogen
Component build order: library
creating dist/build
creating dist/build/autogen
Building linear-1.15...
Preprocessing library linear-1.15...
Building library...
creating dist/build
/opt/ghc/7.8.3/bin/ghc --make -fbuilding-cabal-package -O -static -dynamic-too -dynosuf dyn_o -dynhisuf dyn_hi -outputdir dist/build -odir dist/build -hidir dist/build -stubdir dist/build -i -idist/build -isrc -idist/build/autogen -Idist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -package-name linear-1.15 -hide-all-packages -no-user-package-db -package-db /home/ubuntu/haskell/stackage/sandbox/package-db -package-db dist/package.conf.inplace -package-id adjunctions-4.2-027a965214263db4b763593c034e52d6 -package-id base-4.7.0.1-e4b74d27ad8c8987c63abc42a80e7335 -package-id binary-0.7.1.0-0f423baba09114329ffe209a4a948ca4 -package-id containers-0.5.5.1-23e2a2b94d6e452c773209f31d8672c5 -package-id distributive-0.4.4-716d4f27f77ddcefb494f54eb15a0a3d -package-id ghc-prim-0.3.1.0-954cb57749cf319beafdc89b3415422c -package-id hashable-1.2.2.0-2207c7a3e2f29279b5e1a43b13d17cd7 -package-id lens-4.4.0.2-b93706f27538892d314e96c98c67e700 -package-id reflection-1.5.1-e781cdf3179931dd11936b0a5ba72d6c -package-id semigroupoids-4.2-46943e53a945617f25887dd4ca957301 -package-id semigroups-0.15.4-dcbb3594fc3ccf36021fab70b6e16dc1 -package-id tagged-0.7.3-576a8b2a1d599d27b0b9ed9b00e28ed6 -package-id template-haskell-2.9.0.0-3afdeeadb657091939ef0bfa600dc614 -package-id transformers-0.3.0.0-16a97696ae672940f1523b262e566ba5 -package-id unordered-containers-0.2.5.1-db1c5ef9cf247980070064bd949f8e6d -package-id vector-0.10.12.1-c3ff03261f53e4f90a1b1dea904942f8 -package-id void-0.6.1-c2ed24a84823037c3b07e9bcc7229fed -XHaskell98 Linear Linear.Affine Linear.Algebra Linear.Binary Linear.Conjugate Linear.Covector Linear.Epsilon Linear.Instances Linear.Matrix Linear.Metric Linear.Plucker Linear.Plucker.Coincides Linear.Projection Linear.Quaternion Linear.Trace Linear.V Linear.V0 Linear.V1 Linear.V2 Linear.V3 Linear.V4 Linear.Vector -Wall -fwarn-tabs -O2 -fdicts-cheap -funbox-strict-fields
src/Linear.hs:40:8:
Could not find module ‘Linear.Perspective’
Use -v to see a list of the files searched for.
As things stand, I find myself frequently needing rather a long list of imports when using linear. Should we have a re-export module that offers up everything (or nearly everything)? At the very least, it would be handy to get V2, V3, V4, and the functions defined in Vector all at once.
Rotating (1,0,0) by PI radians around the y axis CORRECTLY results in (-1,0,0) :
(axisAngle (V3 0 1 0) pi)
rotate
(V3 1 0 0)
V3 (-1.0) 0.0 (-1.2246063538223773e-16)
This code still behaves as expected with a non-unit axis:
(axisAngle (V3 0 10 0) pi)
rotate
(V3 1 0 0)
V3 (-1.0) 0.0 (-1.2246063538223773e-17)
The bug is apparent only when composing quaternions generated by axisAngle. If we attempt the same rotation expressed as 2 half rotations, there is unexpected behavior:
-- works with unit axis
(let q = axisAngle (V3 0 1 0) (pi/2) in q*q)rotate
(V3 1 0 0)
V3 (-1.0) 0.0 (-4.440892098500626e-16)-- HERE IS THE BUG (expected result is (-1,0,0))
-- does NOT work with non-unit axis
(let q = axisAngle (V3 0 10 0) (pi/2) in q*q)rotate
(V3 1 0 0)
V3 0.9215763160474459 0.0 0.3881972355651406
Which of the following (if any) would you like in linear?
I've defined all these outside of linear recently.
Is there a good way of dealing with triangular matrices in a type-safe way? It would be nice to represent a triangular matrix as a vector of vectors of increasing length -- [V1, V2, V3], etc. But how would the types work?
It turns out that one can get at columns of a matrix by transforming the simple element-wise _x
lenses using incore
from Linear.Core
> let mat = V2 (V3 1 2 3) (V3 4 5 6)
> mat ^. _x
V3 1 2 3
> mat ^. incore _x
V2 1 4
This could be mentioned in the documentation of Matrix or incore
itself. As a sidenote this blows my mind (taking a slice of a 3D matrix):
> let mat3d = V2 (V2 (V3 1 2 3) (V3 4 5 6)) (V2 (V3 7 8 9) (V3 10 11 12))
> mat ^. incore (incore _xy)
V2 (V2 (V2 1 2) (V2 4 5)) (V2 (V2 7 8) (V2 10 11))
I've got a really strange failure building linear when lens is loaded via TH. Am I even at the right issue tracker here, or is something missing on the lens-side?
Configuring linear-1.18.0.1...
Building linear-1.18.0.1...
Preprocessing library linear-1.18.0.1...
[ 1 of 22] Compiling Linear.Instances ( src/Linear/Instances.hs, dist/build/Linear/Instances.o )
[ 2 of 22] Compiling Linear.Vector ( src/Linear/Vector.hs, dist/build/Linear/Vector.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package containers-0.5.6.3 ... linking ... done.
Loading package stm-2.4.4 ... linking ... done.
Loading package transformers-0.4.2.0 ... linking ... done.
Loading package StateVar-1.1.0.0 ... linking ... done.
Loading package bytestring-0.10.4.1 ... linking ... done.
Loading package text-1.2.0.4 ... linking ... done.
Loading package hashable-1.2.3.1 ... linking ... done.
Loading package nats-1 ... linking ... done.
Loading package unordered-containers-0.2.5.1 ... linking ... done.
Loading package semigroups-0.16.0.1 ... linking ... done.
Loading package transformers-compat-0.4.0.4 ... linking ... done.
Loading package void-0.7 ... linking ... done.
Loading package contravariant-1.3 ... linking ... done.
Loading package tagged-0.7.3 ... linking ... done.
Loading package distributive-0.4.4 ... linking ... done.
Loading package comonad-4.2.5 ... linking ... done.
Loading package semigroupoids-4.3 ... linking ... done.
Loading package bifunctors-4.2.1 ... linking ... done.
Loading package mtl-2.2.1 ... linking ... done.
Loading package exceptions-0.6.1 ... linking ... done.
Loading package filepath-1.3.0.2 ... linking ... done.
Loading package prelude-extras-0.4 ... linking ... done.
Loading package profunctors-4.4.1 ... linking ... done.
Loading package pretty-1.1.1.1 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package free-4.11 ... linking ... done.
Loading package adjunctions-4.2 ... linking ... done.
Loading package kan-extensions-4.2.1 ... linking ... done.
Loading package parallel-3.2.0.6 ... linking ... done.
Loading package primitive-0.5.4.0 ... linking ... done.
Loading package reflection-1.5.1.2 ... linking ... done.
Loading package vector-0.10.12.2 ... linking ... done.
Loading package lens-4.8 ... <command line>: can't load .so/.DLL for: /home/mgore/.cabal/lib/x86_64-linux-ghc-7.8.4/lens-4.8/libHSlens-4.8-ghc7.8.4.so (/home/mgore/.cabal/lib/x86_64-linux-ghc-7.8.4/lens-4.8/libHSlens-4.8-ghc7.8.4.so: undefined symbol: templatezmhaskell_LanguageziHaskellziTHziSyntax_zdfMonadQ4_closure)
They are trivial and it is in base
.
http://hackage.haskell.org/package/base-4.6.0.1/docs/Control-Monad-Zip.html
All the dense cases are isomorphic to functions, so we can borrow the semantics of the MonadFix ((->) r)
instance, to get the equivalent of:
instance MonadFix V2 where
mfix f = V2 (let V2 a _ = f a in a)
(let V2 _ a = f a in a)
I'm using the vagrant buildpack recommended by the ghcjs 'team' https://github.com/ghcjs/ghcjs
They have a version of GHC 7.7 installed apparently. Most libraries I have tried to install compile, but it doesn't seem to like linear (both in "normal" ghc and ghcjs)
The problem occurs for both when compiling Linear.V
--- there are two errors:
src/Linear/V.hs:83:10:
Not in scope: type constructor or class 'KnownNat'
src/Linear/V.hs:84:30: Not in scope: 'natVal'
Is this a known issue/has this popped up before? This happens when both using the hackage version and the HEAD version from github of Linear.
I’m building a realtime 3D engine. That’s quite logical that I use linear
for my linear algebra stuff then.
I’ve been experiencing a few framerate drops, so I profiled my application pretty quite intensively to find out the bug. I’m not sure it’s related to my FPS drops, but I’ve found something pretty weird about a few linear
’s functions.
The first thing weird is that mkTransformation
and scaled
appear as top functions that consume the more memory. Here is a header of my starting profile report. As you can see, mkTransformation
and scaled
eats up to 50% of the memory (and omniProjViews
also has a high impact, I’ll check that later).
Here’s a better context of a use of both the functions. As you can see, mkTransformation
and scaled
are responsible of a lot of memory consumption.
What I did is pretty simple. I rewrote both the function to see if it was better. After having performed another profile, I got this. scaled
has totally disappeared and mkTransformation
eats less memory, even though it still consumes a bit (fromQuaternion
implementation, I guess).
Here’s a better point of view.
Now, I can write a patch if you think it’s worth it. The implementation of my own functions is here. Straight-forward implementation ;)
This would help me use types like V3, Quaternion, etc in my libraries.
If there's is no objection I'd be happy to make a patch.
Current classes in linear are only instantiable for * → *
kinds. We'd be able to supplant vector-space
had we classes for *
kinds as well.
Preliminary discussion on #haskell-lens; @acowley @ekmett @shachaf
[12 of 20] Compiling Linear.V ( src/Linear/V.hs, dist/build/Linear/V.o )
src/Linear/V.hs:287:37:
Ambiguous occurrence `index'
It could refer to either `Lens.index',
imported from `Control.Lens' at src/Linear/V.hs:48:1-27
(and originally defined in `Control.Lens.Indexed')
or `Data.Functor.Rep.index',
imported from `Data.Functor.Rep' at src/Linear/V.hs:52:1-23
In case it helps, here's the list of dependencies compiled against:
/opt/ghc-7.4.2/bin/ghc --make -fbuilding-cabal-package -O -outputdir dist/build -odir dist/build -hidir dist/build -stubdir dist/build -i -idist/build -isrc -idist/build/autogen -Idist/build/autogen -Idist/build -optP-include -optPdist/build/autogen/cabal_macros.h -package-name linear-1.9 -hide-all-packages -no-user-package-conf -package-conf /var/lib/jenkins/workspace/Stackage with GHC 7.4.2 no HP/stackage/sandbox/package-db -package-conf dist/package.conf.inplace -package-id adjunctions-4.0.2-8508728fbcfca6da69f410beef808815 -package-id base-4.5.1.0-66f22db3dfcd87541c9c7e50e7095d26 -package-id binary-0.5.1.0-1dd25e339bc04e2d8ca8103c35947bf6 -package-id containers-0.4.2.1-75f143aa39a3e77a1ce2300025bdd8ce -package-id distributive-0.4-6904bfd74c396ff9bbc3124a01d54437 -package-id ghc-prim-0.2.0.0-7d3c2c69a5e8257a04b2c679c40e2fa7 -package-id hashable-1.2.1.0-d1c30e608c4a205e735527c4ee1eef95 -package-id lens-4.0.5-7757191438cdf1946fc9b14cc09ae43d -package-id reflection-1.4-41707588ee0b794fe554c4e00a5ccd47 -package-id semigroupoids-4.0-9884dfeb7141abbbcbe6d00162802171 -package-id semigroups-0.12.2-986e2309921aeb43bb6298bb6eb9ae7d -package-id tagged-0.7-6a76711121b053f1f4a07d2e528e4947 -package-id template-haskell-2.7.0.0-ea0103105685f73dfd311f959f3ec5a5 -package-id transformers-0.3.0.0-8e66ecc7d4dae2b07b2b5406908c70e4 -package-id unordered-containers-0.2.3.3-bb2367957511c4dcd385b8f1cdddd32d -package-id vector-0.10.9.1-156c25b890435eaeab1a012545441415 -package-id void-0.6.1-e9a931e30ce8da0833d33dd8285bd347 -XHaskell98 Linear Linear.Affine Linear.Algebra Linear.Binary Linear.Conjugate Linear.Covector Linear.Epsilon Linear.Instances Linear.Matrix Linear.Metric Linear.Plucker Linear.Quaternion Linear.Trace Linear.V Linear.V0 Linear.V1 Linear.V2 Linear.V3 Linear.V4 Linear.Vector -Wall -fwarn-tabs -O2 -fdicts-cheap -funbox-strict-fields
[17 of 21] Compiling Linear.Affine ( src/Linear/Affine.hs, dist/build/Linear/Affine.o )
src/Linear/Affine.hs:140:10:
Variable s `g, b' occur more often than in the instance head
in the constraint: t ~ Point g b
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Rewrapped (Point f a) t'
How can I enumerate the setters for a vector?
set _x (V2 0 0 :: V2 Double) 9 :: V2 Double
works
let x = V2 9 9 :: V2 Double
tabulate (\i -> Rep.index x i) :: V2 Double
works
but
> tabulate (\i -> set i (0 :: V2 Int) x) :: V2 (V2 Int)
<interactive>:93:21:
Couldn't match type ‘E V2’
with ‘(a0 -> Identity (V2 Int)) -> V2 Int -> Identity (V2 Int)’
Expected type: ASetter (V2 Int) (V2 Int) a0 (V2 Int)
Actual type: Rep V2
In the first argument of ‘set’, namely ‘i’
In the expression: set i (0 :: V2 Int) x
Is there a way to enumerate the ASetters for a lens the way we can enumerate the viewing indices?
I want a function that will give me all the _x
, _y
, etc automatically.
I'm having a problem where trying to write functions that are generic in which vector type to use (V0
, V1
, V2
, etc), the constraints explode. For example:
storeInV :: (Applicative v, Unbox (v Int), Unbox (v Double), Unbox (v String),
Num (v Int), Num (v Double))
=> Int -> (VU.Vector (v Int), VU.Vector (v Double), VU.Vector (v String))
storeInV n =
let
x = VU.replicate n 1
y = VU.replicate n 2
z = VU.replicate n (pure "a")
in (x, y, z)
If I have a function that calls storeInV
, it has to "inherit" all of the constraints. All those constraints quickly become unmanageable.
I see two ways to solve this problem:
Find some way to express in Haskell the idea of a "Unboxing" container v
such that any Unbox a
implies Unbox (v a)
. Perhaps the constraints
package can help, but I don't know how to use it.
Somehow unify all V0
, V1
, etc under a single type, Vn
. Perhaps a closed type family or something. We write an Unbox
instance for Vn
, and then the type signature for the above can simply be:
storeInV :: Int -> (VU.Vector (Vn dim Int), VU.Vector (Vn dim Double), VU.Vector (Vn dim String))
I would be interested in working on this, but I don't know enough about advanced Haskell type system topics to know how to proceed. Could someone can point me to the relevant resources?
If people agree these instances make sense I can go ahead and add them.
I'd like to add the following functions to linear
. They are currently part of diagrams
(HEAD, unreleased), but are more generally useful.
@ekmett says the names should probably be changed, though. The first should probably be _P
, by analogy with other constructor-based Iso
s. I'm not sure about the others.
cc @cchalmers, @jeffreyrosenbluth
-- Point v <-> v
_pIso :: Iso' (Point v n) (v n)
_pIso = iso (\(P a) -> a) P
-- | @project u v@ computes the projection of @v@ onto @u@.
project :: (Metric v, Fractional n) => v n -> v n -> v n
project u v = ((v `dot` u) / quadrance u) *^ u
-- | An isomorphism between points and vectors, given a reference
-- point.
_relative :: (Additive v, Num n) => Point v n -> Iso' (Point v n) (v n)
_relative p0 = iso (.-. p0) (p0 .+^)
e.g.
src/Linear/V.hs:371:21:
Expecting one more argument to `V n'
In the instance declaration for `Data (V n a)'
cabal: Error: some packages failed to install:
&
STDERR: src/Linear/V0.hs:82:10:
STDERR: Could not deduce (GHC.Generics.Generic1 V0,
STDERR: GSerial1 (GHC.Generics.Rep1 V0))
STDERR: arising from a use of `Data.Bytes.Serial.$gdmserializeWith'
STDERR: from the context (Data.Bytes.Put.MonadPut m)
STDERR: bound by the type signature for
STDERR: serializeWith :: Data.Bytes.Put.MonadPut m =>
STDERR: (a -> m ()) -> V0 a -> m ()
STDERR: at src/Linear/V0.hs:82:10-19
STDERR: Possible fix:
STDERR: add (GHC.Generics.Generic1 V0,
STDERR: GSerial1 (GHC.Generics.Rep1 V0)) to the context of
STDERR: the type signature for
STDERR: serializeWith :: Data.Bytes.Put.MonadPut m =>
STDERR: (a -> m ()) -> V0 a -> m ()
STDERR: or add instance declarations for
STDERR: (GHC.Generics.Generic1 V0, GSerial1 (GHC.Generics.Rep1 V0))
STDERR: In the expression: (Data.Bytes.Serial.$gdmserializeWith)
STDERR: In an equation for `serializeWith':
STDERR: serializeWith = (Data.Bytes.Serial.$gdmserializeWith)
STDERR: In the instance declaration for `Serial1 V0'
STDERR:
STDERR: src/Linear/V0.hs:82:10:
STDERR: Could not deduce (GHC.Generics.Generic1 V0,
STDERR: GSerial1 (GHC.Generics.Rep1 V0))
STDERR: arising from a use of `Data.Bytes.Serial.$gdmdeserializeWith'
STDERR: from the context (Data.Bytes.Get.MonadGet m)
STDERR: bound by the type signature for
STDERR: deserializeWith :: Data.Bytes.Get.MonadGet m => m a -> m (V0 a)
STDERR: at src/Linear/V0.hs:82:10-19
STDERR: Possible fix:
STDERR: add (GHC.Generics.Generic1 V0,
STDERR: GSerial1 (GHC.Generics.Rep1 V0)) to the context of
STDERR: the type signature for
STDERR: deserializeWith :: Data.Bytes.Get.MonadGet m => m a -> m (V0 a)
STDERR: or add instance declarations for
STDERR: (GHC.Generics.Generic1 V0, GSerial1 (GHC.Generics.Rep1 V0))
STDERR: In the expression: (Data.Bytes.Serial.$gdmdeserializeWith)
STDERR: In an equation for `deserializeWith':
STDERR: deserializeWith = (Data.Bytes.Serial.$gdmdeserializeWith)
STDERR: In the instance declaration for `Serial1 V0'
while linear-1.18
claims to support base >= 4.5
E.g:
{-# INLINE diag #-}
diag44 (V4 a b c d) =
V4 (V4 a 0 0 0)
(V4 0 b 0 0)
(V4 0 0 c 0)
(V4 0 0 0 d)
Any particular reason or did no one get around to it yet?
Is this an oversight or was it left out for some reason?
Preprocessing test suite 'UnitTests' for linear-1.10.1...
[1 of 3] Compiling Binary ( tests/Binary.hs, dist/build/UnitTests/UnitTests-tmp/Binary.o )
tests/Binary.hs:7:1: Warning:
The import of ‘Linear.Binary’ is redundant
except perhaps to import instances from ‘Linear.Binary’
To import instances alone, use: import Linear.Binary()
<no location info>:
Failing due to -Werror.
The slerp function incorrectly divides by (1/phi) TWICE. once using multiplication by r and then division by phi:
slerp :: RealFloat a => Quaternion a -> Quaternion a -> a -> Quaternion a
slerp q p t
| 1.0 - cosphi < 1e-8 = q
| phi <- acos cosphi, r <- recip (sin phi)
= (sin ((1-t)*phi)*r *^ q ^+^ f (sin (t*phi)*r) *^ p) ^/ sin phi
where
dqp = dot q p
(cosphi, f) = if dqp < 0 then
Here is a suggested correction:
slerp :: RealFloat a => Quaternion a -> Quaternion a -> a -> Quaternion a
slerp q p t
| 1.0 - cosphi < 1e-8 = q
| otherwise = ((sin ((1-t)*phi) *^ q) + (sin (t*phi)) *^ (f p)) ^/ (sin phi)
where
dqp = dot q p
(cosphi, f) = if dqp < 0 then (-dqp, negate) else (dqp, id)
phi = acos cosphi
These are probably of more general use than just for accelerate
.
Now that I'm using it, I'm not sure we get much utility out of the Linear.Dim
experiment.
On 7.10.1
, the testsuite fails to build due to a redundant import warning for Applicative. Given that in general compilers tend to differ significantly in warnings from version to version, IMO as a general rule -Werror should not be put into end-user configurations by default.
Linear> inv44 $ V4 (V4 9.99000999000999e-4 0.0 0.0 0.0) (V4 0.0 9.99000999000999e-4 0.0 0.0) (V4 0.0 0.0 9.99000999000999e-4 0.0) (V4 0.0 0.0 0.0 9.99000999000999e-4)
Nothing
The inverse is of course just a diagonal matrix of 1001
s.
This declaration compiles fine. Is there something wrong with it semantically, or was it omitted from Linear.Metric by accident?
instance Metric []
The definition for int
in Linear.V
is within
#if !(MIN_VERSION_reflection(1,3,0))
yet it is unconditionally present in the export list, which yields
src/Linear/V.hs:37:5:
Not in scope: ‘int’
We should add a direct transformers-compat
dependency so we can portably add support for Eq1
, Show1
, Read1
, and Ord1
from transformers
0.5.
Test suite doctests: RUNNING...
### Failure in src/Linear/Matrix.hs:230: expression `identity :: V 2 (V 2 Int)'
expected: V (fromList [V (fromList [1, 0]), V (fromList [0, 1]))
but got:
<interactive>:160:15:
Illegal literal in type (use DataKinds to enable): 2
Examples: 66 Tried: 66 Errors: 0 Failures: 1
Test suite doctests: FAIL
Test suite logged to: dist/test/linear-1.18-doctests.log
Test suite UnitTests: RUNNING...
Test suite UnitTests: PASS
Test suite logged to: dist/test/linear-1.18-UnitTests.log
1 of 2 test suites (1 of 2 test cases) passed.
cabal: Error: some packages failed to install:
linear-1.18 failed during the tests phase. The exception was:
It would be great if there was a way to turn a Vector (V4 Double)
to a V4 (Vector Double)
. There is distribute
, of course, but it only works for Functor
s, of which Vector
s are not. Is there a better way than to write a new VectorDistributive
class?
I'm not sure I understand the changes in semigroupoids, but I hope this is just a .cabal
change.
I need this released in order to release diagrams
that supports lens-4.11
for commercialhaskell/stackage#590
Due to the recent introduction of roles, GND will no longer derive our boilerplate for Point
,
src/Linear/Affine.hs:105:34:
Can't make a derived instance of ‛Bind (Point f)’
(even with cunning newtype deriving):
it is not type-safe to use GeneralizedNewtypeDeriving on this class;
the last parameter of ‛Bind’ is at role Nominal
In the newtype declaration for ‛Point’
I am implementing code using OpenGL using linear, and I find myself creating Data.Binary
instances for the different vector and matrix types so I can generate buffer data for use with OpenGL. From discussing it with someone else in #haskell on FreeNode, we figured it was a good idea to propose doing so as part of linear so this code would not be specific to my own project.
One note is that as matrix types have two different general ways in which they can be represented, in columns-first order and rows-first order, it would likely be a good idea to use newtypes with different Binary
instances to specify the order, either by creating a newtype for each order, or by having a default order (OpenGL for one defaults to columns-first order) have one set of Binary
instances and creating a newtype with another set of Binary
instances for the alternative order.
Thanks,
Travis
$ cabal install linear --constraint 'reflection ==1.3.1'
[11 of 15] Compiling Linear.V ( src/Linear/V.hs, dist/build/Linear/V.o )
src/Linear/V.hs:190:18:
Ambiguous occurrence `Z'
It could refer to either `Linear.V.Z',
defined at src/Linear/V.hs:185:6
or `R.Z',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:194:36:
Ambiguous occurrence `D'
It could refer to either `Linear.V.D',
defined at src/Linear/V.hs:186:6
or `R.D',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:198:37:
Ambiguous occurrence `SD'
It could refer to either `Linear.V.SD',
defined at src/Linear/V.hs:187:6
or `R.SD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:202:37:
Ambiguous occurrence `PD'
It could refer to either `Linear.V.PD',
defined at src/Linear/V.hs:188:6
or `R.PD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:206:36:
Ambiguous occurrence `D'
It could refer to either `Linear.V.D',
defined at src/Linear/V.hs:186:6
or `R.D',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:210:36:
Ambiguous occurrence `SD'
It could refer to either `Linear.V.SD',
defined at src/Linear/V.hs:187:6
or `R.SD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:214:36:
Ambiguous occurrence `PD'
It could refer to either `Linear.V.PD',
defined at src/Linear/V.hs:188:6
or `R.PD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:224:18:
Ambiguous occurrence `Z'
It could refer to either `Linear.V.Z',
defined at src/Linear/V.hs:185:6
or `R.Z',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:225:18:
Ambiguous occurrence `PD'
It could refer to either `Linear.V.PD',
defined at src/Linear/V.hs:188:6
or `R.PD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:225:30:
Ambiguous occurrence `int'
It could refer to either `Linear.V.int',
defined at src/Linear/V.hs:223:1
or `R.int',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:226:18:
Ambiguous occurrence `D'
It could refer to either `Linear.V.D',
defined at src/Linear/V.hs:186:6
or `R.D',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:226:30:
Ambiguous occurrence `int'
It could refer to either `Linear.V.int',
defined at src/Linear/V.hs:223:1
or `R.int',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:227:18:
Ambiguous occurrence `SD'
It could refer to either `Linear.V.SD',
defined at src/Linear/V.hs:187:6
or `R.SD',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
src/Linear/V.hs:227:30:
Ambiguous occurrence `int'
It could refer to either `Linear.V.int',
defined at src/Linear/V.hs:223:1
or `R.int',
imported from `Data.Reflection' at src/Linear/V.hs:28:1-27
Failed to install linear-1.1.1
cabal: Error: some packages failed to install:
linear-1.1.1 failed during the building phase. The exception was:
ExitFailure 1
In the latest version of linear
on Hackage, 1.10.1.2
, there are no links to the documentation.
Previous versions (although perhaps not all, I only checked 3) have this.
The Linear.Affine modules fail to build against GHC HEAD (ghc/ghc@072259c).
polarina@tictactoe:~/linear-1.14.0.1$ cabal-head install
Resolving dependencies...
Configuring linear-1.14.0.1...
Building linear-1.14.0.1...
Failed to install linear-1.14.0.1
Build log ( /home/polarina/.cabal/logs/linear-1.14.0.1.log ):
Configuring linear-1.14.0.1...
Building linear-1.14.0.1...
Preprocessing library linear-1.14.0.1...
[ 1 of 22] Compiling Linear.Instances ( src/Linear/Instances.hs, dist/build/Linear/Instances.o )
src/Linear/Instances.hs:22:1: Warning:
The import of ‘Data.Foldable’ is redundant
except perhaps to import instances from ‘Data.Foldable’
To import instances alone, use: import Data.Foldable()
src/Linear/Instances.hs:29:1: Warning:
The import of ‘Data.Traversable’ is redundant
except perhaps to import instances from ‘Data.Traversable’
To import instances alone, use: import Data.Traversable()
[ 2 of 22] Compiling Linear.Vector ( src/Linear/Vector.hs, dist/build/Linear/Vector.o )
src/Linear/Vector.hs:39:1: Warning:
The import of ‘Foldable’ from module ‘Data.Foldable’ is redundant
src/Linear/Vector.hs:44:1: Warning:
The import of ‘Data.Monoid’ is redundant
except perhaps to import instances from ‘Data.Monoid’
To import instances alone, use: import Data.Monoid()
[ 3 of 22] Compiling Linear.Epsilon ( src/Linear/Epsilon.hs, dist/build/Linear/Epsilon.o )
[ 4 of 22] Compiling Linear.Metric ( src/Linear/Metric.hs, dist/build/Linear/Metric.o )
[ 5 of 22] Compiling Linear.V0 ( src/Linear/V0.hs, dist/build/Linear/V0.o )
[ 6 of 22] Compiling Linear.V1 ( src/Linear/V1.hs, dist/build/Linear/V1.o )
[ 7 of 22] Compiling Linear.V2 ( src/Linear/V2.hs, dist/build/Linear/V2.o )
[ 8 of 22] Compiling Linear.V3 ( src/Linear/V3.hs, dist/build/Linear/V3.o )
src/Linear/V3.hs:42:1: Warning:
The import of ‘Data.Foldable’ is redundant
except perhaps to import instances from ‘Data.Foldable’
To import instances alone, use: import Data.Foldable()
[ 9 of 22] Compiling Linear.V4 ( src/Linear/V4.hs, dist/build/Linear/V4.o )
src/Linear/V4.hs:49:1: Warning:
The import of ‘Data.Foldable’ is redundant
except perhaps to import instances from ‘Data.Foldable’
To import instances alone, use: import Data.Foldable()
[10 of 22] Compiling Linear.Plucker ( src/Linear/Plucker.hs, dist/build/Linear/Plucker.o )
[11 of 22] Compiling Linear.V ( src/Linear/V.hs, dist/build/Linear/V.o )
[12 of 22] Compiling Linear.Plucker.Coincides ( src/Linear/Plucker/Coincides.hs, dist/build/Linear/Plucker/Coincides.o )
[13 of 22] Compiling Linear.Conjugate ( src/Linear/Conjugate.hs, dist/build/Linear/Conjugate.o )
[14 of 22] Compiling Linear.Quaternion ( src/Linear/Quaternion.hs, dist/build/Linear/Quaternion.o )
[15 of 22] Compiling Linear.Trace ( src/Linear/Trace.hs, dist/build/Linear/Trace.o )
[16 of 22] Compiling Linear.Matrix ( src/Linear/Matrix.hs, dist/build/Linear/Matrix.o )
[17 of 22] Compiling Linear.Perspective ( src/Linear/Perspective.hs, dist/build/Linear/Perspective.o )
[18 of 22] Compiling Linear.Affine ( src/Linear/Affine.hs, dist/build/Linear/Affine.o )
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘product’
from type ‘forall a. (Foldable f, Num a) => f a -> a’
to type ‘forall a. (Foldable (Point f), Num a) => Point f a -> a’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘maximum’
from type ‘forall a. (Foldable f, Ord a) => f a -> a’
to type ‘forall a. (Foldable (Point f), Ord a) => Point f a -> a’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘elem’
from type ‘forall a. (Foldable f, Eq a) => a -> f a -> Bool’
to type ‘forall a.
(Foldable (Point f), Eq a) =>
a -> Point f a -> Bool’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘length’
from type ‘forall a. Foldable f => f a -> Int’
to type ‘forall a. Foldable (Point f) => Point f a -> Int’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘null’
from type ‘forall a. Foldable f => f a -> Bool’
to type ‘forall a. Foldable (Point f) => Point f a -> Bool’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
src/Linear/Affine.hs:121:64:
Could not coerce from ‘Foldable f’ to ‘Foldable (Point f)’
because the first type argument of ‘Foldable’ has role Nominal,
but the arguments ‘f’ and ‘Point f’ differ
arising from the coercion of the method ‘toList’
from type ‘forall a. Foldable f => f a -> [a]’
to type ‘forall a. Foldable (Point f) => Point f a -> [a]’
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Foldable (Point f))
cabal-head: Error: some packages failed to install:
linear-1.14.0.1 failed during the building phase. The exception was:
ExitFailure 1
The library could provide cleaner suport for trace operation defining a trace monad with the join operation as trace. Instead of reusing the monad instance.
{-# LANGUAGE TypeOperators #-}
module Space.Trace where
import Linear.V1
import Linear.V2
import Linear.V3
import Linear.V4
import CartesianProduct
import Data.Functor.Compose
import Data.Functor.Product
import Data.Distributive
class Functor m => Trace m where
trace :: m (m a) -> m a
instance Trace V1 where
trace (V1 x) = x
instance Trace V2 where
trace (V2 (V2 xx _) (V2 _ yy) ) = V2 xx yy
instance Trace V3 where
trace (V3 (V3 xx _ _ ) (V3 _ yy _) (V3 _ _ zz )) = V3 xx yy zz
instance Trace V4 where
trace (V4 (V4 xx _ _ _ ) (V4 _ yy _ _) (V4 _ _ zz _ ) (V4 _ _ _ tt) ) = V4 xx yy zz
instance (Trace f, Trace g ) => Trace (f `Product` g ) where
trace ( xx `Pair` yy ) = trace (fmap pfst xx) `Pair` trace (fmap psnd yy)
where pfst (Pair x y) = x
psnd (Pair x y) = y
-- A cleaner cartesian product
-- instance (Trace f, Trace g ) => Trace (f :|:g ) where
-- trace ( xx :|: yy ) = trace (fmap _cfst xx) :|: trace (fmap _csnd yy)
instance (Distributive g,Trace g, Trace f) => Trace (Compose g f ) where
trace = Compose . fmap trace . trace . fmap distribute .unCompose . fmap unCompose
where
unCompose :: Compose f g a -> f (g a)
unCompose (Compose x ) = x
How would you feel about a dependency on cereal? I'm currently running into issues with orphan instances. I'm happy to implement this if it's desired.
In-place registering linear-1.18.0.1...
Preprocessing test suite 'doctests' for linear-1.18.0.1...
[1 of 2] Compiling Build_doctests ( dist/build/autogen/Build_doctests.hs, dist/build/doctests/doctests-tmp/Build_doctests.o )
[2 of 2] Compiling Main ( tests/doctests.hs, dist/build/doctests/doctests-tmp/Main.o )
tests/doctests.hs:4:1: Warning:
The import of ‘Control.Applicative’ is redundant
except perhaps to import instances from ‘Control.Applicative’
To import instances alone, use: import Control.Applicative()
<no location info>:
Failing due to -Werror.
I'm working on a program with lots of tiny 4x4 matrices. I would like to store all of my matrices in Vector.Storable
or Vector.Unboxed
instead of Vector.Vector
, so that the Garbage Collector doesn't have to step though millions of pointers.
Because of the way matrices are defined, it doesn't seem possible to define Storable instances for them. Is there a workaround? I feel that there should be a way to "view" a vector of vectors as a vector of matrices somehow. Should I define my own matrix implementation that just uses the vector part of linear
?
We already depend on vector
, so these should probably be added.
My math is terrible so I apologize in advance if I'm just confused, but shouldn't the sign of "((f+n)*z))" be flipped?
Perhaps like so:
ortho' l r b t n f =
V4 (V4 (-2*x) 0 0 ((r+l)*x))
(V4 0 (-2*y) 0 ((t+b)*y))
(V4 0 0 (-2*z) ((f+n)*z))
(V4 0 0 0 1)
where x = recip(l-r)
y = recip(b-t)
z = recip(f-n)
Many of the functions in linear
require an Applicative
constraint for use of pure
. Unfortunately, many of the types which linear
supposedly supports provide Applicative
instances which don't have the right semantics leading to type-safe code yielding incorrect results. Take for example Vector
,
import qualified Data.Vector as V
import Linear
main = print $ kronecker $ V.fromList [1,2,3]
This results in fromList [fromList [1,0,0]]
instead of the expected fromList [fromList [1,0,0],fromList [0,2,0],fromList [0,0,3]]
.
The reason for this can be found in the definition of kronecker
,
kronecker :: (Applicative t, Num a, Traversable t) => t a -> t (t a)
kronecker v = snd $ mapAccumL aux 0 v
where aux i e = let i' = i + 1
in i' `seq` (i', setElement i e z)
z = pure 0
where z
in this case will be a singleton Vector
. If I'm not mistaken, the use of pure
here isn't even necessary. Taking z = fmap (const 0) v
will always give the correct answer and will never drop dimensions. That being said, it may come at a performance cost (as might be the case in, say, a Map
).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.