laop
laop copied to clipboard
Add linear map semantics and safe transformations
@bolt12 This replaces my previous PR #7. You don't have to merge it -- it's just an illustration of how the ideas from my experiment can be translated to your data type.
Thanks for this Andrey :smile:
As I said in my email, it would be very nice if a version of matrixBuilder
or fromF
can be implemented in a type safe manner. Do you have any idea on how to do it?
@bolt12 I think we can implement matrixBuilder
type-safely. I've just pushed a quick experiment, although I haven't had enough time to see how well it scales for Generic
data types.
As for fromF
, it's semantics is a bit obscure: it produces only 0/1 matrices, which seem more like relations to me. Using the Matrix e a b
data type feels wrong here. Perhaps, you better have a separate type for relations, something like type Relation a b = Matrix Bool a b
.
@snowleopard
As for fromF, it's semantics is a bit obscure: it produces only 0/1 matrices, which seem more like relations to me. Using the Matrix e a b data type feels wrong here. Perhaps, you better have a separate type for relations, something like type Relation a b = Matrix Bool a b.
They are indeed relations I decided to use 1 and 0's because I could work with other quantitative matrices. I also have a Relation
module that uses a similar type to type Relation a b = Matrix Bool a b
!
This seems promising! There must be a cool way to work with arbitrary generic types!
I also have a
Relation
module that uses a similar type totype Relation a b = Matrix Bool a b
!
Ah, indeed, got it!
There must be a cool way to work with arbitrary generic types!
Good, hope you'll manage to make it work :)
The way I see it work with your implementation is to use Generics to create a deconstructor similar to either
for each type. I have something that can work but needs TH https://github.com/bolt12/f-algebra-gen... I think I saw somewhere this solved using Generics
I think I was able to do it!
toNorm :: (Enum a, Enum (Normalize a)) => a -> Normalize a
toNorm = toEnum . fromEnum
fromNorm :: (Enum a, Enum (Normalize a)) =>Normalize a -> a
fromNorm = toEnum . fromEnum
There's no need for the type-class anymore I think! Since Count a ~ Count (Normalize a)
, under this restrictions this isomorphism is correct!
@bolt12 Awesome! Could you show the full code?
@snowleopard sure!
type ConstructNorm a = (Enum a, Enum (Normalize a))
toNorm :: ConstructNorm a => a -> Normalize a
toNorm = toEnum . fromEnum
fromNorm :: ConstructNorm a => Normalize a -> a
fromNorm = toEnum . fromEnum
rowN :: (Construct (Normalize a), ConstructNorm a, Num e) => Vector e a -> Matrix e (Normalize a) ()
rowN = row' . contramap fromNorm
linearMapN :: (Construct (Normalize a), Construct (Normalize b), ConstructNorm a, ConstructNorm b, Num e)
=> LinearMap e a b -> Matrix e (Normalize a) (Normalize b)
linearMapN = linearMap . dimap (contramap toNorm) (contramap fromNorm)
columnN :: (Construct (Normalize a), ConstructNorm a, Num e) => Vector e a -> Matrix e () (Normalize a)
columnN = tr . rowN
functionN :: (Construct (Normalize a), Construct (Normalize b), ConstructNorm a, ConstructNorm b, Enumerable a, Num e)
=> (a -> b -> e) -> Matrix e (Normalize a) (Normalize b)
functionN f = linearMapN $ \v -> Vector $ \b -> dot v $ Vector $ \a -> f a b
Everything is the same as your code but without the type class. What do you think?
Thank you once again for all your help! :smile:
@bolt12 Thanks but I meant the full code, including the implementation of various other key functions like kr
, ><
, etc :)
I'm still working on the refactoring! I hope to open a PR soon with all the changes!
@snowleopard please see #11 for the full code!
I think we are getting there :smile: the Internal.hs
and Type.hs
modules are good to go! The whole project still does not compile because I haven't finished refactoring yet.