Skip to content

Commit

Permalink
Switch to Scala 3.5-style givens
Browse files Browse the repository at this point in the history
  • Loading branch information
propensive committed Jun 14, 2024
1 parent 97531b3 commit 70da2e6
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 46 deletions.
2 changes: 1 addition & 1 deletion fury
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ project mosquito
compiler scala
sources src/test
coverage mosquito/core
include probably/cli quantitative/core mosquito/core larceny/plugin
include probably/cli quantitative/units mosquito/core larceny/plugin
main mosquito.Tests


95 changes: 50 additions & 45 deletions src/core/vector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import vacuous.*

import scala.compiletime.*, ops.int.*

class Matrix[+ElementType, RowsType <: Int, ColumnsType <: Int]
class Matrix[ElementType, RowsType <: Int, ColumnsType <: Int]
(val rows: Int, val columns: Int, val elements: IArray[ElementType]):

def apply(row: Int, column: Int): ElementType = elements(columns*row + column)
Expand All @@ -36,22 +36,22 @@ class Matrix[+ElementType, RowsType <: Int, ColumnsType <: Int]
case _ => false

override def hashCode: Int = scala.util.hashing.MurmurHash3.arrayHash(elements.mutable(using Unsafe))

override def toString(): String = t"[${elements.debug}]".s

@targetName("scalarMul")
def * [RightType](right: RightType)(using mul: MulOperator[ElementType, RightType])
(using ClassTag[mul.Result])
: Matrix[mul.Result, RowsType, ColumnsType] =
def * [RightType](right: RightType)(using multiplication: ElementType is Multiplicable[RightType])
(using ClassTag[multiplication.Result])
: Matrix[multiplication.Result, RowsType, ColumnsType] =

val elements2 = IArray.create[mul.Result](elements.length): array =>
val elements2 = IArray.create[multiplication.Result](elements.length): array =>
elements.indices.foreach: index =>
array(index) = elements(index)*right

new Matrix(rows, columns, elements2)

@targetName("scalarDiv")
def / [RightType](right: RightType)(using div: DivOperator[ElementType, RightType])
def / [RightType](right: RightType)(using div: ElementType is Divisible[RightType])
(using ClassTag[div.Result])
: Matrix[div.Result, RowsType, ColumnsType] =

Expand All @@ -63,29 +63,33 @@ class Matrix[+ElementType, RowsType <: Int, ColumnsType <: Int]

@targetName("mul")
def * [RightType, RightColumnsType <: Int: ValueOf](right: Matrix[RightType, ColumnsType, RightColumnsType])
(using mul: MulOperator[ElementType, RightType], add: AddOperator[mul.Result, mul.Result])
(using add.Result =:= mul.Result, ValueOf[RowsType], ValueOf[ColumnsType], ClassTag[mul.Result])
: Matrix[mul.Result, RowsType, RightColumnsType] =
(using multiplication: ElementType is Multiplicable[RightType],
addition: multiplication.Result is Addable[multiplication.Result],
equality: addition.Result =:= multiplication.Result,
rowValue: ValueOf[RowsType],
columnValue: ValueOf[ColumnsType],
classTag: ClassTag[multiplication.Result])
: Matrix[multiplication.Result, RowsType, RightColumnsType] =

val columns2 = valueOf[RightColumnsType]
val inner = valueOf[ColumnsType]
val elements = IArray.create[mul.Result](rows*columns2): array =>

val elements = IArray.create[multiplication.Result](rows*columns2): array =>
for row <- 0 until rows; column <- 0 until columns2
do array(columns2*column + row) =
(0 until inner).map { index => apply(row, index)*right(index, column) }.reduce(_ + _)

new Matrix(rows, columns2, elements)

object Matrix:
given show[ElementType: Show](using TextMetrics): Show[Matrix[ElementType, ?, ?]] = matrix =>
given [ElementType: Showable](using TextMetrics) => Matrix[ElementType, ?, ?] is Showable = matrix =>
val textElements = matrix.elements.map(_.show)
val sizes = textElements.map(_.length)

val columnWidths: IArray[Int] = IArray.from:
(0 until matrix.columns).map: column =>
sizes(column + matrix.columns*(0 until matrix.rows).maxBy { row => sizes(matrix.columns*row + column) })

(0 until matrix.rows).map: row =>
val before = if row == 0 then t"" else if row == matrix.rows - 1 then t"" else t""
val after = if row == 0 then t"" else if row == matrix.rows - 1 then t"" else t""
Expand All @@ -109,7 +113,7 @@ object Matrix:

val rowCount: Int = valueOf[Rows]
val columnCount = valueOf[Columns]

new Matrix[ElementType, Rows, Columns](rowCount, columnCount,
IArray.create[ElementType](columnCount*rowCount): array =>
for row <- 0 until rowCount; column <- 0 until columnCount
Expand All @@ -120,13 +124,13 @@ object Matrix:


object Mosquito:
opaque type Euclidean[+ValueType, SizeType <: Int] = Tuple
opaque type Euclidean[ValueType, SizeType <: Int] = Tuple

object Euclidean:
def apply(elems: Tuple): Euclidean[Tuple.Union[elems.type], Tuple.Size[elems.type]] = elems

given show[SizeType <: Int: ValueOf, ElemType: Show](using TextMetrics)
: Show[Euclidean[ElemType, SizeType]] =
given [SizeType <: Int: ValueOf, ElemType: Showable](using TextMetrics)
=> Euclidean[ElemType, SizeType] is Showable as showable =

euclidean =>
val items = euclidean.list.map(_.show)
Expand All @@ -136,29 +140,30 @@ object Mosquito:
else
val top = t"${items.head.pad(width, Rtl)}"
val bottom = t"${items.last.pad(width, Rtl)}"

val middle = items.tail.init.map: item =>
t"${item.pad(width, Rtl)}"

(top :: middle ::: bottom :: Nil).join(t"\n")

extension [LeftType](left: Euclidean[LeftType, 3])
def cross[RightType](right: Euclidean[RightType, 3])(using multiply: MulOperator[LeftType, RightType])
(using add: AddOperator[multiply.Result, multiply.Result],
subtract: SubOperator[multiply.Result, multiply.Result])
: Euclidean[add.Result, 3] =
def cross[RightType](right: Euclidean[RightType, 3])
(using multiplication: LeftType is Multiplicable[RightType],
addition: multiplication.Result is Addable[multiplication.Result],
subtraction: multiplication.Result is Subtractable[multiplication.Result])
: Euclidean[addition.Result, 3] =

(left(1)*right(2) - left(2)*right(1)) *:
(left(2)*right(0) - left(0)*right(2)) *:
(left(0)*right(1) - left(1)*right(0)) *:
EmptyTuple


extension [SizeType <: Int, LeftType](left: Euclidean[LeftType, SizeType])
def apply(index: Int): LeftType = left.toArray(index).asInstanceOf[LeftType]
def list: List[LeftType] = left.toList.asInstanceOf[List[LeftType]]
def iarray: IArray[LeftType] = left.toIArray.asInstanceOf[IArray[LeftType]]

def map[LeftType2](fn: LeftType => LeftType2): Euclidean[LeftType2, SizeType] =
def recur(tuple: Tuple): Tuple = tuple match
case head *: tail => fn(head.asInstanceOf[LeftType]) *: recur(tail)
Expand All @@ -167,24 +172,24 @@ object Mosquito:
recur(left)

@targetName("add")
def + [RightType](right: Euclidean[RightType, SizeType])(using add: AddOperator[LeftType, RightType])
: Euclidean[add.Result, SizeType] =
def + [RightType](right: Euclidean[RightType, SizeType])(using addition: LeftType is Addable[RightType])
: Euclidean[addition.Result, SizeType] =

def recur(left: Tuple, right: Tuple): Tuple = left match
case leftHead *: leftTail => right match
case rightHead *: rightTail =>
(leftHead.asInstanceOf[LeftType] + rightHead.asInstanceOf[RightType]) *: recur(leftTail, rightTail)

case _ =>
EmptyTuple

case _ =>
EmptyTuple

recur(left, right)

@targetName("sub")
def - [RightType](right: Euclidean[RightType, SizeType])(using sub: SubOperator[LeftType, RightType])
def - [RightType](right: Euclidean[RightType, SizeType])(using sub: LeftType is Subtractable[RightType])
: Euclidean[sub.Result, SizeType] =

def recur(left: Tuple, right: Tuple): Tuple = left match
Expand All @@ -197,30 +202,30 @@ object Mosquito:
EmptyTuple

recur(left, right)

@targetName("scalarMul")
def * [RightType](right: RightType)(using mul: MulOperator[LeftType, RightType])
: Euclidean[mul.Result, SizeType] =
def * [RightType](right: RightType)(using multiplication: LeftType is Multiplicable[RightType])
: Euclidean[multiplication.Result, SizeType] =

map(_*right)

@targetName("scalarDiv")
def * [RightType](right: RightType)(using div: DivOperator[LeftType, RightType])
def * [RightType](right: RightType)(using div: LeftType is Divisible[RightType])
: Euclidean[div.Result, SizeType] =

map(_/right)

def dot[RightType](right: Euclidean[RightType, SizeType])
(using multiply: MulOperator[LeftType, RightType],
(using multiply: LeftType is Multiplicable[RightType],
size: ValueOf[SizeType],
add: AddOperator[multiply.Result, multiply.Result],
equality: add.Result =:= multiply.Result)
addition: multiply.Result is Addable[multiply.Result],
equality: addition.Result =:= multiply.Result)
: multiply.Result =

def recur(index: Int, sum: multiply.Result): multiply.Result =
if index < 0 then sum else recur(index - 1, sum + left(index)*right(index))

val start = size.value - 1
recur(start - 1, left(start)*right(start))

export Mosquito.Euclidean
export Mosquito.Euclidean

0 comments on commit 70da2e6

Please sign in to comment.