0

I'm writing simple polynomial-related library for my own needs. As for now, I'm working with just the polynomials in polynomial basis over GF(2), so they are represented simply as

case class Polynomial(coeffs: BitSet)

So I can just write something like

Polynomial(BitSet(0,1,2))

to represent

(x^2 + x + 1)

Now, I'm particularly proud about my multiplication function:

def *(that: Polynomial): Polynomial = Polynomial {
    coeffs.foldLeft(BitSet.empty) { case (acc, i) => acc ^ that.coeffs.map(i +) }
}

But as for now, all my efforts to express reduction by some other polynomial modulo didn't show any similar result. I do indeed understand that division is somewhat more complex, but I currently have very, very dirty recursive solution and I don't like it at all. What I currently have is something like what follows (don't forget we are in GF(2)). (UPD: Simplified code to make it runnable outside class)

  def foo(thisSet: BitSet, thatSet: BitSet): BitSet = {
    var ts = thisSet
    while (!ts.isEmpty && ts.max >= thatSet.max) {
      ts = ts ^ thatSet.map(_ - thatSet.max + ts.max)
    }
    ts
  }

It works fine (though I didn't write any test so far), but I'd like to have something neat (tail-recursive at most, but desirably just using folds/maps/reduces.

tkroman
  • 4,811
  • 1
  • 26
  • 46

1 Answers1

0

You could always write simple loop in a recursive manner

exemple with your foo function :

import scala.annotation.tailrec
def fooRec(thisSet : BitSet, thatSet : BitSet) : BitSet = {
    @tailrec def loop(acc : BitSet) : BitSet = {
        if (!acc.isEmpty && acc.max >= thatSet.max) loop(acc ^ thatSet.map(_ - thatSet.max + acc.max))
        else acc
    }
    loop(thisSet)
}                                         //> fooRec: (thisSet: scala.collection.BitSet, thatSet: scala.collection.BitSet)
                                          //| scala.collection.BitSet

foo(BitSet(1, 2, 0), BitSet(3, 0, 1))           //> res0: scala.collection.BitSet = BitSet(0, 1, 2)
fooRec(BitSet(1, 2, 0), BitSet(3, 0, 1))        //> res1: scala.collection.BitSet = BitSet(0, 1, 2)

You can see that the var ts is the parameter of the inner recursive function loop and the while is now just an if.

Tail recursive function and while loop are almost identical in performance and readability, in my opinion. you can choose the style that suits you best.

Personally i don't think this version is more dirty than the while version.

volia17
  • 938
  • 15
  • 29