Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adds AdjoinedUnit Ring #130

Merged
merged 2 commits into from

2 participants

P. Oscar Boykin Sam Ritchie
P. Oscar Boykin
Collaborator

No description provided.

P. Oscar Boykin
Collaborator

Addresses: #47

Sam Ritchie sritchie commented on the diff
...est/scala/com/twitter/algebird/AdJoinedUnitRing.scala
((13 lines not shown))
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package com.twitter.algebird
+
+import org.scalacheck.Arbitrary
+import org.scalacheck.Arbitrary.arbitrary
+import org.scalacheck.Properties
+import org.scalacheck.Gen.choose
+
+object AdjoinedRingSpecification extends Properties("AdjoinedRing") {
+ import BaseProperties._
+
+ implicit def adjoined[T:Arbitrary]: Arbitrary[AdjoinedUnit[T]] = Arbitrary {
+ implicitly[Arbitrary[T]].arbitrary.map { t => AdjoinedUnit(t) }
Sam Ritchie Collaborator

Arbitrary.arbitrary[T].map

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sam Ritchie sritchie merged commit 9f24431 into from
Sam Ritchie sritchie deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 25, 2013
  1. P. Oscar Boykin

    Adds AdjoinedUnit Ring

    johnynek authored
  2. P. Oscar Boykin
This page is out of date. Refresh to see the latest.
82 algebird-core/src/main/scala/com/twitter/algebird/AdjoinedUnitRing.scala
View
@@ -0,0 +1,82 @@
+/*
+Copyright 2012 Twitter, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package com.twitter.algebird
+
+import scala.annotation.tailrec
+
+/**
+ * This is for the case where your Ring[T] is a Rng (i.e. there is no unit).
+ * @see http://en.wikipedia.org/wiki/Pseudo-ring#Adjoining_an_identity_element
+ */
+case class AdjoinedUnit[T](ones: BigInt, get: T)
+
+object AdjoinedUnit {
+ def apply[T](item: T): AdjoinedUnit[T] = new AdjoinedUnit[T](BigInt(0), item)
+ implicit def ring[T](implicit ring: Ring[T]): Ring[AdjoinedUnit[T]] = new AdjoinedUnitRing[T]
+}
+
+class AdjoinedUnitRing[T](implicit ring: Ring[T]) extends Ring[AdjoinedUnit[T]] {
+ val one = AdjoinedUnit[T](BigInt(1), ring.zero)
+ val zero = AdjoinedUnit[T](ring.zero)
+
+ override def isNonZero(it: AdjoinedUnit[T]) =
+ (it.ones != 0) && (ring.isNonZero(it.get))
+
+ def plus(left: AdjoinedUnit[T], right: AdjoinedUnit[T]) =
+ AdjoinedUnit(left.ones + right.ones, ring.plus(left.get, right.get))
+
+ override def negate(it: AdjoinedUnit[T]) =
+ AdjoinedUnit(-it.ones, ring.negate(it.get))
+ override def minus(left: AdjoinedUnit[T], right: AdjoinedUnit[T]) =
+ AdjoinedUnit(left.ones - right.ones, ring.minus(left.get, right.get))
+
+ final def intTimes(i: BigInt, v: T): T = {
+ if(i < 0) {
+ intTimes(i, ring.negate(v))
+ }
+ else if (i == 0) {
+ ring.zero
+ }
+ else if(i == 1) {
+ v
+ }
+ else {
+ // i * v == ((i/2) * v + (i/2)*v) + (1/0)*v
+ val half = i / 2
+ val rem = i % 2
+ val ht = intTimes(half, v)
+ val twoV = ring.plus(ht, ht)
+ if (rem == 0) {
+ twoV
+ }
+ else {
+ ring.plus(twoV, v)
+ }
+ }
+ }
+
+ def times(left: AdjoinedUnit[T], right: AdjoinedUnit[T]) = {
+ // (n1, g1) * (n1, g2) = (n1*n2, (n2*g1) + (n2*g1) + g1*g2))
+ val ones = left.ones * right.ones
+ val part0 = intTimes(left.ones, right.get)
+ val part1 = intTimes(right.ones, left.get)
+ val part2 = ring.times(left.get, right.get)
+ val nonUnit = ring.plus(part0, ring.plus(part1, part2))
+
+ AdjoinedUnit(ones, nonUnit)
+ }
+
+}
33 algebird-test/src/test/scala/com/twitter/algebird/AdJoinedUnitRing.scala
View
@@ -0,0 +1,33 @@
+/*
+Copyright 2012 Twitter, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package com.twitter.algebird
+
+import org.scalacheck.Arbitrary
+import org.scalacheck.Arbitrary.arbitrary
+import org.scalacheck.Properties
+import org.scalacheck.Gen.choose
+
+object AdjoinedRingSpecification extends Properties("AdjoinedRing") {
+ import BaseProperties._
+
+ implicit def adjoined[T:Arbitrary]: Arbitrary[AdjoinedUnit[T]] = Arbitrary {
+ implicitly[Arbitrary[T]].arbitrary.map { t => AdjoinedUnit(t) }
Sam Ritchie Collaborator

Arbitrary.arbitrary[T].map

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ property("AdjoinedUnit[Int] is a Ring") = ringLaws[AdjoinedUnit[Int]]
+ property("AdjoinedUnit[Long] is a Ring") = ringLaws[AdjoinedUnit[Long]]
+}
Something went wrong with that request. Please try again.