Skip to content
This repository has been archived by the owner on Feb 8, 2022. It is now read-only.

Add GenBool instance for Map[K, V: GenBool]. #126

Closed
wants to merge 2 commits into from

Conversation

TomasMikula
Copy link
Collaborator

No description provided.

def zero: Map[K, V] = Map.empty

def and(a: Map[K, V], b: Map[K, V]): Map[K, V] = (
(a.keySet intersect b.keySet)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for performance you might want:

(a.keySet intersect b.keySet).iterator
  .map { k => (k, GBV.and(a(k), b(k))) }
  .filter { case (_, v) => EqV.neqv(GBV.zero, v) }
  .toMap

putting the iterator early prevents materialization after .map and .filter. Also, note, .map is returning a set here and so if filter, so that is going to be bit slower than the iterator.

@johnynek
Copy link
Contributor

I realize we didn't add MapBoundedSemilattice when we have Semilattice which we could.

Also, there are many similar constructions related to Option[T] which is like a Map[Unit, T].

@TomasMikula
Copy link
Collaborator Author

I will rewrite the expressions to invoke iterator early. Now I'm thinking, if the two maps differ in size by 3 orders of magnitude, it might be better to apply the small number of individual updates on the bigger map.

@TomasMikula
Copy link
Collaborator Author

Yeah, I realized there could be interesting structures for Map weaker than GenBool.

@TomasMikula
Copy link
Collaborator Author

I don't know how immutable Map is implemented, but if I assume that updating a single key costs log n, and if the other (smaller) map has size m, then if

m log n < n + m

it is more efficient to update the big map.

@johnynek
Copy link
Contributor

Immutable map is a HashTrie, so it is ~ log_32 n cost to update a map of size n.

@johnynek
Copy link
Contributor

@TomasMikula you might want to take a look at: https://github.com/non/algebra/blob/a32f76aba93245b95972b4b4bb80f29b0621c9ba/std/src/main/scala/algebra/std/Util.scala#L154 the addMap/subtractMap methods may be able to be used in these cases.

@TomasMikula
Copy link
Collaborator Author

Yeah, addMap could be used to implement or right away. subtractMap could possibly be used to implement without, passing constant function returning zero as negate (because here, unlike in rings, 0\a = 0). The problem is that if in x\y, x is much smaller, x\y can be fast, because we don't have to introduce 0s for all the elements of y (whereas in subtractMap you have to introduce the inverses).

 - Optimize chains of map/filter by invoking iterator early.
 - Use tuple pattern matching on function argument.
@johnynek
Copy link
Contributor

i think we need the TotalMap[K, V] to handle this. @TomasMikula I wonder if your https://github.com/TomasMikula/hasheq could be the right place to add such a type?

@TomasMikula
Copy link
Collaborator Author

i think we need the TotalMap[K, V] to handle this.

I'm afraid you're right.

I wonder if your https://github.com/TomasMikula/hasheq could be the right place to add such a type?

Indeed, it would make sense to add TotalMap to hasheq. Then have a third module that provides algebra instances for hasheq structures.

@non
Copy link
Contributor

non commented Sep 14, 2016

That sounds like a great plan to me!

@TomasMikula
Copy link
Collaborator Author

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

Successfully merging this pull request may close these issues.

3 participants