Skip to content
This repository was archived by the owner on Feb 19, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Fix spaces and new lines.
  • Loading branch information
Giulio De Luise committed Apr 24, 2016
commit 0669ac7c2bbc638ba47061b74bca8e89f726cdf0
8 changes: 4 additions & 4 deletions src/main/java/epic/util/Arrays.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ object Arrays {
val ret = new Array[C](arr1.length * arr2.length)
var off = 0
var i = 0
while(i < arr1.length) {
while (i < arr1.length) {
var j = 0
while(j < arr2.length) {
while (j < arr2.length) {
ret(off) = f(arr1(i), arr2(j))
off += 1
j += 1
Expand All @@ -65,9 +65,9 @@ object Arrays {
val ret = new Array[Int](arr1.length * arr2.length)
var off = 0
var i = 0
while(i < arr1.length) {
while (i < arr1.length) {
var j = 0
while(j < arr2.length) {
while (j < arr2.length) {
ret(off) = arr1(i) + arr2(j) * secondScale
off += 1
j += 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package epic.constraints

import epic.util.CacheBroker


/**
* A cached version of [[epic.constraints.LabeledSpanConstraints.Factory]].
* Uses the [[epic.util.CacheBroker]] infrastructure
Expand Down
15 changes: 5 additions & 10 deletions src/main/scala/epic/constraints/ChartConstraints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,26 @@ import java.io.{DataOutput, DataInput}
case class ChartConstraints[L](top: LabeledSpanConstraints[L],
bot: LabeledSpanConstraints[L]) extends SpanConstraints with Serializable {


def isAllowedSpan(begin: Int, end: Int):Boolean = top.isAllowedSpan(begin, end) || bot.isAllowedSpan(begin, end)
def isAllowedSpan(begin: Int, end: Int): Boolean = top.isAllowedSpan(begin, end) || bot.isAllowedSpan(begin, end)
/** TODO */ // TODO
def hasMaximalLabel(begin: Int, end: Int):Boolean = ???

def hasMaximalLabel(begin: Int, end: Int): Boolean = ???

def maxSpanLengthStartingAt(begin: Int): Int = top.maxSpanLengthStartingAt(begin) max bot.maxSpanLengthStartingAt(begin)

def flatten = top | bot
def &(other: ChartConstraints[L]) = if(this eq other) this else ChartConstraints(top & other.top, bot & other.bot)
def &(other: ChartConstraints[L]) = if (this eq other) this else ChartConstraints(top & other.top, bot & other.bot)
def |(other: ChartConstraints[L]) = ChartConstraints(top | other.top, bot | other.bot)


}

object ChartConstraints {

def noSparsity[L]: ChartConstraints[L] = ChartConstraints[L](LabeledSpanConstraints.noConstraints[L], LabeledSpanConstraints.noConstraints[L])

def apply[L](top: TriangularArray[_ <: BitSet], bot: TriangularArray[_ <: BitSet]): ChartConstraints[L] = ChartConstraints(LabeledSpanConstraints(top), LabeledSpanConstraints(bot))

trait Factory[L, W] extends SpanConstraints.Factory[W] {
def constraints(w: IndexedSeq[W]): ChartConstraints[L]

def |(cf: Factory[L, W]) = new OrFactory(this, cf)
}

Expand Down Expand Up @@ -82,11 +79,9 @@ object ChartConstraints {
case _ =>
bot(t.begin,t.end) = BitSet(labelIndex(t.label))
}

ChartConstraints(LabeledSpanConstraints(top), LabeledSpanConstraints(bot))
}


implicit def serializerChartConstraints[L]:Serializer[ChartConstraints[L]] = new Serializer[ChartConstraints[L]] with Serializable {
def serialize(out: DataOutput, value: ChartConstraints[L]) {
implicitly[Serializer[LabeledSpanConstraints[L]]].serialize(out, value.top)
Expand All @@ -98,6 +93,6 @@ object ChartConstraints {
val bot = implicitly[Serializer[LabeledSpanConstraints[L]]].deserialize(in, available)
ChartConstraints(top, bot)
}

}

}
90 changes: 33 additions & 57 deletions src/main/scala/epic/constraints/LabeledSpanConstraints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,25 @@ sealed trait LabeledSpanConstraints[-L] extends SpanConstraints {
def isAllowedLabeledSpan(begin: Int, end: Int, label: Int): Boolean
def isAllowedSpan(begin: Int, end: Int): Boolean
/** How long can a span be if it starts at begin*/
def maxSpanLengthStartingAt(begin: Int):Int
def maxSpanLengthStartingAt(begin: Int): Int
/** How long can a span be if it has label label in this sentence? */
def maxSpanLengthForLabel(label: Int):Int
def maxSpanLengthForLabel(label: Int): Int

/**
* Computes the intersection of the constraints
* @param other
* @return
*/
def &(other: LabeledSpanConstraints[L @uncheckedVariance ]): LabeledSpanConstraints[L] = {
if(this eq other) this
if (this eq other) this
else this match {
case NoConstraints => other
case PromotedSpanConstraints(inner) => other match {
case NoConstraints => this
case PromotedSpanConstraints(otherinner) => PromotedSpanConstraints(inner & otherinner)
case SimpleConstraints(maxPosX, maxLx, x) => SimpleConstraints(maxPosX, maxLx,
TriangularArray.tabulate(x.dimension){(b, e) =>
if(x(b,e) == null || !inner.isAllowedSpan(b,e)) null
if (x(b,e) == null || !inner.isAllowedSpan(b,e)) null
else x(b,e)
})
}
Expand All @@ -55,14 +55,14 @@ sealed trait LabeledSpanConstraints[-L] extends SpanConstraints {
require(x.dimension == y.dimension, "Dimensions of constrained spans must match!")
SimpleConstraints( elementwiseMin(maxPosX, maxPosY), elementwiseMin(maxLx, maxLy),
TriangularArray.tabulate(x.dimension) { (b,e) =>
if(x(b,e) == null || y(b,e) == null) null
if (x(b,e) == null || y(b,e) == null) null
else x(b,e) & y(b,e)
})
}
}
}

def containsAll(other: LabeledSpanConstraints[L @uncheckedVariance]):Boolean = this match {
def containsAll(other: LabeledSpanConstraints[L @uncheckedVariance]): Boolean = this match {
case NoConstraints => true
case SimpleConstraints(maxPosX, maxLx, x) => other match {
case NoConstraints => throw new UnsupportedOperationException("Can't check Simple.containsAll(noconstraints)")
Expand All @@ -75,7 +75,6 @@ sealed trait LabeledSpanConstraints[-L] extends SpanConstraints {
yield (y(i,j) eq null) || ((x(i,j) ne null) && (y(i,j) &~ x(i,j )).isEmpty)
}.forall(identity))
}

}

/**
Expand All @@ -89,7 +88,6 @@ sealed trait LabeledSpanConstraints[-L] extends SpanConstraints {
case NoConstraints => this
case PromotedSpanConstraints(otherinner) => PromotedSpanConstraints(inner | otherinner)
case SimpleConstraints(maxPosX, maxLx, x) => ???

}
case SimpleConstraints(maxPosX, maxLx, x) => other match {
case NoConstraints => this
Expand All @@ -98,15 +96,14 @@ sealed trait LabeledSpanConstraints[-L] extends SpanConstraints {
require(x.dimension == y.dimension, "Dimensions of constrained spans must match!")
SimpleConstraints( elementwiseMax(maxPosX, maxPosY), elementwiseMax(maxLx, maxLy),
TriangularArray.tabulate(x.dimension) { (b,e) =>
if(x(b,e) == null) y(b,e)
if (x(b,e) == null) y(b,e)
else if (y(b,e) == null) x(b, e)
else x(b,e) | y(b,e)
})
}
}

def decode(labelIndex: Index[L@uncheckedVariance ]):String

def decode(labelIndex: Index[L@uncheckedVariance ]): String

}

Expand All @@ -122,7 +119,7 @@ object LabeledSpanConstraints {
out.writeBoolean(true)
val length: Int = maxLengthsForPosition.length
out.writeInt(length)
if(length < Byte.MaxValue) {
if (length < Byte.MaxValue) {
maxLengthsForPosition.foreach(maxLengthForPosition =>
out.writeByte((maxLengthForPosition min length).toByte)
)
Expand All @@ -133,9 +130,9 @@ object LabeledSpanConstraints {
maxLengthsForLabel.foreach(out.writeInt)
for(i <- 0 until length; j <- (i+1) to length if value.isAllowedSpan(i, j)) {
val cardinality: Int = spans(i, j).cardinality
if(cardinality != 0) {
if (cardinality != 0) {
out.writeInt(TriangularArray.index(i, j))
if(cardinality == 1) {
if (cardinality == 1) {
// have to deal with 0 length mask
out.writeInt(~(spans(i, j).nextSetBit(0)))
} else {
Expand Down Expand Up @@ -163,13 +160,13 @@ object LabeledSpanConstraints {
val maxLengthsForLabel = Array.fill(labelLen)(in.readInt())
val spans = new TriangularArray[util.BitSet](length+1)
var ok = true
while(ok) {
while (ok) {
ok = false
val ti = readInt()
if(ti >= 0) {
if (ti >= 0) {
ok = true
val bitmaskSize = readInt()
if(bitmaskSize < 0) {
if (bitmaskSize < 0) {
val index = ~bitmaskSize
spans.data(ti) = new util.BitSet()
spans.data(ti).set(index)
Expand All @@ -182,7 +179,6 @@ object LabeledSpanConstraints {
}
new SimpleConstraints[L](maxLengthsForPosition, maxLengthsForLabel, spans)
}

}
}

Expand All @@ -200,27 +196,26 @@ object LabeledSpanConstraints {
}
val maxLengthLabel = ArrayBuffer[Int]()
for(begin <- 0 until spans.dimension; end <- (begin+1) until spans.dimension) {
if(spans(begin, end) ne null) {
if (spans(begin, end) ne null) {
for(l <- spans(begin, end)) {
if(l >= maxLengthLabel.length) {
if (l >= maxLengthLabel.length) {
maxLengthLabel ++= new Array[Int](l - maxLengthLabel.length + 1)
}
maxLengthLabel(l) = maxLengthLabel(l) max (end-begin)
}

}
}

apply(maxLengthPos, maxLengthLabel.toArray, spans)
}

def apply[L](maxLengthPos: Array[Int], maxLengthLabel: Array[Int], spans: TriangularArray[_ <: BitSet]):LabeledSpanConstraints[L] = {
SimpleConstraints(maxLengthPos, maxLengthLabel, spans.map(bs => if(bs eq null) null else java.util.BitSet.valueOf(bs.toBitMask)))
SimpleConstraints(maxLengthPos, maxLengthLabel, spans.map(bs => if (bs eq null) null else java.util.BitSet.valueOf(bs.toBitMask)))
}

def fromTagConstraints[L](constraints: TagConstraints[L]): LabeledSpanConstraints[L] = {
val arr = TriangularArray.tabulate(constraints.length+1) { (b,e) =>
if(b +1 == e) {
if (b +1 == e) {
ensureBitSet(constraints.allowedTags(b))
} else {
null
Expand All @@ -229,7 +224,6 @@ object LabeledSpanConstraints {
apply(arr)
}


private def ensureBitSet[L](tags: Set[Int]): BitSet = {
tags match {
case x: BitSet => x
Expand All @@ -247,21 +241,19 @@ object LabeledSpanConstraints {
val arr = new TriangularArray[BitSet](localization.length + 1)
val maxMaxLength = maxLengthForLabel.max min localization.length
for(i <- 0 until localization.length) {
arr(i, i+1) = ensureBitSet(localization.allowedTags(i))
arr(i, i+1) = ensureBitSet(localization.allowedTags(i))
}

val maxLengthPos = Array.fill(localization.length)(1)
val maxLengthLabel = maxLengthForLabel.clone()

var acceptableTags = BitSet.empty ++ maxLengthForLabel.indices
for(length <- 2 to maxMaxLength if acceptableTags.nonEmpty) {
acceptableTags = acceptableTags.filter(i => maxLengthForLabel(i) >= length)
if(acceptableTags.nonEmpty)
if (acceptableTags.nonEmpty)
for (begin <- 0 to (localization.length - length) ) {
val end = begin + length
if(arr(begin,begin+1) != null && arr(begin+1,end) != null) {
if (arr(begin,begin+1) != null && arr(begin+1,end) != null) {
arr(begin, end) = (arr(begin, begin+1) & arr(begin+1, end)) & acceptableTags
if(arr(begin,end).isEmpty) {
if (arr(begin,end).isEmpty) {
arr(begin, end) = null
} else {
maxLengthPos(begin) = length
Expand All @@ -274,50 +266,34 @@ object LabeledSpanConstraints {
apply(maxLengthPos, maxLengthLabel, arr)
}


@SerialVersionUID(1L)
object NoConstraints extends LabeledSpanConstraints[Any] with Serializable {

def maxSpanLengthStartingAt(begin: Int): Int = Int.MaxValue/2 // /2 because i get worried about wrap around.

def isAllowedSpan(begin: Int, end: Int): Boolean = true
def isAllowedLabeledSpan(begin: Int, end: Int, label: Int): Boolean = true

def maxSpanLengthForLabel(label: Int):Int = Int.MaxValue / 2


def decode(labelIndex: Index[Any]):String = toString
def maxSpanLengthForLabel(label: Int): Int = Int.MaxValue / 2
def decode(labelIndex: Index[Any]): String = toString
}


@SerialVersionUID(1L)
case class PromotedSpanConstraints(inner: SpanConstraints) extends LabeledSpanConstraints[Any] with Serializable {

def maxSpanLengthStartingAt(begin: Int): Int = Int.MaxValue/2 // /2 because i get worried about wrap around.

def isAllowedSpan(begin: Int, end: Int): Boolean = inner.isAllowedSpan(begin, end)
def isAllowedLabeledSpan(begin: Int, end: Int, label: Int): Boolean = isAllowedSpan(begin, end)

def maxSpanLengthForLabel(label: Int):Int = Int.MaxValue / 2

def decode(labelIndex: Index[Any]):String = inner.toString
def maxSpanLengthForLabel(label: Int): Int = Int.MaxValue / 2
def decode(labelIndex: Index[Any]): String = inner.toString
}


// private vars for serialization.
@SerialVersionUID(2L)
case class SimpleConstraints[L](private var maxLengthsForPosition: Array[Int], // maximum length for position
private var maxLengthsForLabel: Array[Int],
private var spans: TriangularArray[java.util.BitSet]) extends LabeledSpanConstraints[L] with Serializable {
def isAllowedSpan(begin: Int, end: Int): Boolean = (spans(begin,end) ne null) && spans(begin,end).cardinality() > 0

def isAllowedLabeledSpan(begin: Int, end: Int, label: Int): Boolean = (spans(begin,end) ne null) && spans(begin, end).get(label)

def maxSpanLengthStartingAt(begin: Int): Int = maxLengthsForPosition(begin)

def maxSpanLengthForLabel(label: Int) = if(maxLengthsForLabel.length <= label) 0 else maxLengthsForLabel(label)

def decode(labelIndex: Index[L]):String = {
def maxSpanLengthForLabel(label: Int) = if (maxLengthsForLabel.length <= label) 0 else maxLengthsForLabel(label)
def decode(labelIndex: Index[L]): String = {
val ret = new StringBuilder()
val enc = Encoder.fromIndex(labelIndex)
ret ++= "SimpleConstraints(positionMaxLengths="
Expand All @@ -327,7 +303,7 @@ object LabeledSpanConstraints {
ret ++= ")\n"
for(i <- 0 until maxLengthsForPosition.length; j <- (i+1) to maxLengthsForPosition.length) {
val s = spans(i, j)
if(s ne null) {
if (s ne null) {
ret ++= s" ($i,$j) " + enc.decode(Array.tabulate(labelIndex.size)(x => spans(i, j).get(x))).toString + "\n"
}
}
Expand All @@ -352,15 +328,15 @@ object LabeledSpanConstraints {

private def elementwiseMax(a: Array[Int], b: Array[Int]):Array[Int] = {
// could avoid the allocation, but whatever.
if(a.length < b.length) elementwiseMax(util.Arrays.copyOf(a, b.length), b)
else if(b.length < a.length) elementwiseMax(a, util.Arrays.copyOf(b, a.length))
if (a.length < b.length) elementwiseMax(util.Arrays.copyOf(a, b.length), b)
else if (b.length < a.length) elementwiseMax(a, util.Arrays.copyOf(b, a.length))
else Array.fillWith[Int](a.length)(i => math.max(a(i), b(i)))
Copy link
Owner

Choose a reason for hiding this comment

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

why not Array.tabulate? Also, in general I'm a bit concerned about replacing while loops with HOFs. If it's a while loop, I was probably concerned about performance.

}

private def elementwiseMin(a: Array[Int], b: Array[Int]):Array[Int] = {
// could avoid the allocation, but whatever.
if(a.length < b.length) elementwiseMin(util.Arrays.copyOf(a, b.length), b)
else if(b.length < a.length) elementwiseMin(a, util.Arrays.copyOf(b, a.length))
if (a.length < b.length) elementwiseMin(util.Arrays.copyOf(a, b.length), b)
else if (b.length < a.length) elementwiseMin(a, util.Arrays.copyOf(b, a.length))
else Array.fillWith[Int](a.length)(i => math.min(a(i), b(i)))
}

Expand Down
8 changes: 0 additions & 8 deletions src/main/scala/epic/constraints/LongSpanConstraints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,9 @@ object LongSpanConstraints {
val spans = new SpanConstraints {
val oks = w.map(ww => okWords(ww) || !ww.head.isLetterOrDigit)
def maxSpanLengthStartingAt(begin: Int): Int = w.length - begin


def maxSpanLengthForLabel(label: Int): Int = w.length


def decode(labelIndex: Index[L]): String = "..."


def isAllowedLabeledSpan(begin: Int, end: Int, label: Int): Boolean = isAllowedSpan(begin, end)

def isAllowedSpan(begin: Int, end: Int): Boolean = (
end - begin <= maxSimpleLength
|| end == w.length
Expand All @@ -36,6 +29,5 @@ object LongSpanConstraints {
}
new ChartConstraints(PromotedSpanConstraints(spans), PromotedSpanConstraints(spans))
}

}
}
Loading