Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add linear map semantics and safe transformations #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Add linear map semantics and safe transformations #9

wants to merge 2 commits into from

Conversation

snowleopard
Copy link

@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.

@bolt12
Copy link
Owner

bolt12 commented Feb 28, 2020

Thanks for this Andrey 😄

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?

@snowleopard
Copy link
Author

@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.

@bolt12
Copy link
Owner

bolt12 commented Feb 29, 2020

@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!

@snowleopard
Copy link
Author

I also have a Relation module that uses a similar type to type 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 :)

@bolt12
Copy link
Owner

bolt12 commented Feb 29, 2020

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

@bolt12
Copy link
Owner

bolt12 commented Feb 29, 2020

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!

@snowleopard
Copy link
Author

@bolt12 Awesome! Could you show the full code?

@bolt12
Copy link
Owner

bolt12 commented Feb 29, 2020

@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! 😄

@snowleopard
Copy link
Author

@bolt12 Thanks but I meant the full code, including the implementation of various other key functions like kr, ><, etc :)

@bolt12
Copy link
Owner

bolt12 commented Mar 1, 2020

I'm still working on the refactoring! I hope to open a PR soon with all the changes!

@bolt12
Copy link
Owner

bolt12 commented Mar 1, 2020

@snowleopard please see #11 for the full code!

I think we are getting there 😄 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants