---
title: Dependently typed tensors
author: [Stefano Gogioso, Ayberk Tosun]
date-started: 2025-02-19
---
Summary of a discussion (2025-02-13) with Stefano Gogioso on encoding tensors
using dependent types. This observation was made independently by both of us.
\begin{code}
{-# OPTIONS --safe --without-K #-}
open import UF.FunExt
module gist.DependentlyTypedTensors (fe : Fun-Ext) where
open import MLTT.Fin
open import MLTT.Spartan
open import UF.Base
open import UF.Equiv
\end{code}
We work in a module parameterized by a type `R`. This can be thought of as the
carrier of a ring, but we are not interested in the ring structure in this gist.
\begin{code}
module Tensor (R : π€β Μ ) where
\end{code}
A vector of length `n` over `R` is a function `Fin n β R`
\begin{code}
Vector : β β π€β Μ
Vector n = Fin n β R
\end{code}
An `m` by `n` matrix over `R` is a function `Fin m Γ Fin n β R`. It has `m`
rows and `n` columns.
\begin{code}
Matrix : β β β β π€β Μ
Matrix m n = (Fin m Γ Fin n) β R
\end{code}
This readily generalizes to a rank-`r` tensor over `R`.
\begin{code}
Rank-[_]-Tensor : (r : β) β (Fin r β β) β π€β Μ
Rank-[_]-Tensor r d = ((i : Fin r) β Fin (d i)) β R
\end{code}
Vectors are just rank-1 tensors.
\begin{code}
vector-is-rank-1-tensor : (n : β) β Vector n β Rank-[ 1 ]-Tensor (Ξ» _ β n)
vector-is-rank-1-tensor n = s , qinvs-are-equivs s (r , sec , ret)
where
s : Vector n β Rank-[ 1 ]-Tensor (Ξ» _ β n)
s v i = v (i π)
r : Rank-[ 1 ]-Tensor (Ξ» _ β n) β Vector n
r Ο i = Ο (Ξ» _ β i)
sec : r β s βΌ id
sec = Ξ» _ β refl
ret : s β r βΌ id
ret Ο = dfunext fe β
where
β : (i : Fin 1 β Fin n) β s (r Ο) i οΌ Ο i
β i = s (r Ο) i οΌβ¨ refl β©
r Ο (i π) οΌβ¨ refl β©
Ο (Ξ» _ β i π) οΌβ¨ β‘ β©
Ο i β
where
β‘ : Ο (Ξ» _ β i π) οΌ Ο i
β‘ = ap Ο (dfunext fe Ξ» { π β refl })
\end{code}
Matrices are rank-2 tensors.
\begin{code}
_by_ : {X : π₯ Μ } β X β X β Fin 2 β X
_by_ x y π = x
_by_ x y π = y
matrix-is-rank-2-tensor : (m n : β)
β Matrix m n β Rank-[ 2 ]-Tensor (m by n)
matrix-is-rank-2-tensor m n = s , qinvs-are-equivs s (r , sec , ret)
where
s : Matrix m n β Rank-[ 2 ]-Tensor (m by n)
s Ο Ξ½ = Ο (Ξ½ π , Ξ½ π)
doubletonβ² : Fin m β Fin n β (k : Fin 2) β Fin ((m by n) k)
doubletonβ² i j π = i
doubletonβ² i j π = j
r : Rank-[ 2 ]-Tensor (m by n) β Matrix m n
r Ο (i , j) = Ο (doubletonβ² i j)
sec : r β s βΌ id
sec = Ξ» _ β refl
ret : s β r βΌ id
ret Ο = dfunext fe β
where
β : (s β r) Ο βΌ id Ο
β Ξ½ = s (r Ο) Ξ½ οΌβ¨ refl β©
r Ο (Ξ½ π , Ξ½ π) οΌβ¨ refl β©
Ο (doubletonβ² (Ξ½ π) (Ξ½ π)) οΌβ¨ β‘ β©
Ο Ξ½ β
where
ΞΎ : doubletonβ² (Ξ½ π) (Ξ½ π) βΌ Ξ½
ΞΎ π = refl
ΞΎ π = refl
β‘ = ap Ο (dfunext fe ΞΎ)
\end{code}
We now generalize tensors as to be able to consider arbitrary index types.
Previously, we had a function `d : Fin r β β`, whose product
`Ξ i : Fin r , Fin (d i)` gave us the _shape_ of the tensor in consideration.
We now work with a generalized shape function `S : I β π₯ Μ`.
\begin{code}
Shape-[_]-Tensor : {I : π€β Μ } β (I β π€β Μ ) β π€β Μ
Shape-[_]-Tensor {I} S = ((i : I) β S i) β R
\end{code}
The previous notion of `Rank-[ r ]-Tensor d` can now be reconstructed as a
special case.
\begin{code}
finite-shape : (r : β) (d : Fin r β β)
β Rank-[ r ]-Tensor d οΌ Shape-[_]-Tensor (Fin β d)
finite-shape _ _ = refl
\end{code}