Behind the
<foo>.t(..) // .t() is transpose
method of [DenseVector|DenseMatrix] is a relative labyrinthe of implicits, traits, and class hierarchies. Some of the pieces:
Here is a possible example of what I am looking for: inside the Transpose object there is the following low-level code (the "dot"):
implicit def transTimesNormalFromDot[T, U, R](implicit dot: OpMulInner.Impl2[T, U, R]): OpMulMatrix.Impl2[Transpose[T], U, R] = {
new OpMulMatrix.Impl2[Transpose[T], U, R] {
def apply(v: Transpose[T], v2: U): R = {
dot(v.inner, v2)
}
}
}
Note however that Intellij IDE was unable to find any usages. I am trying to find how the DenseMatrix and DenseVector implement the transpose.
I freely admit the implicits can be a bit hard to follow. The .t method for NumericOps (which is where DenseVector and DM get it from) is defined as follows:
final def t[TT >: This, That](implicit op: CanTranspose[TT, That]) =
op.apply(repr)
DenseMatrix has a CanTranspose implicit defined like so:
implicit def canTranspose[V]: CanTranspose[DenseMatrix[V], DenseMatrix[V]] = {
new CanTranspose[DenseMatrix[V], DenseMatrix[V]] {
def apply(from: DenseMatrix[V]) = {
new DenseMatrix(data = from.data, offset = from.offset,
cols = from.rows, rows = from.cols,
majorStride = from.majorStride,
isTranspose = !from.isTranspose)
}
}
}
The relevant bit is the flip of the isTranspose boolean (and the swap of rows and columns). So ".t" on a DenseMatrix just creates a new DenseMatrix that is either column-major (!isTranspose) and row-major (isTranpose).
DenseVector has no CanTranspose implicit in general. Instead, there's an implicit defined for all Tensors in the Tensor companion object:
implicit def transposeTensor[K, V, T](implicit ev: T<:<Tensor[K, V]): CanTranspose[T, Transpose[T]] = {
new CanTranspose[T, Transpose[T]] {
def apply(from: T): Transpose[T] = new Transpose(from)
}
}
So dv.t gives a Transpose[DenseVector].
Hope that helps!