///|
/// axes[new_axis] = old_axis. Never transforms vector-valued components.
pub fn Tensor::permute(
  self : Tensor,
  axes : Array[Int32],
  limits~ : Limits = Limits::default(),
) -> Tensor raise NrrdError {
  if axes.length() != self.shape.dimension() {
    raise Invalid("permutation dimension")
  }
  let seen = Array::make(axes.length(), false)
  for axis in axes {
    check_axis(self.shape, axis)
    if seen[axis] {
      raise Invalid("duplicate permutation axis")
    }
    seen[axis] = true
  }
  let shape = Shape::new(axes.map(fn(a) { self.shape.axes[a] }), limits~)
  ignore(shape.byte_count(self.scalar, limits))
  let values = Array::make(shape.count, 0.0)
  for i in 0.. Tensor raise NrrdError {
  check_axis(self.shape, axis)
  let offsets = Array::make(self.shape.dimension(), 0)
  offsets[axis] = self.shape.axes[axis] - 1
  let m = shifted_metadata(self.metadata, offsets)
  let directions = m.directions.copy()
  if !directions.is_empty() {
    if directions[axis] is Some(v) {
      directions[axis] = Some(v.map(fn(x) { -x }))
    }
  }
  ignore(Shape::new(self.shape.axes, limits~))
  ignore(self.shape.byte_count(self.scalar, limits))
  let values = Array::make(self.shape.count, 0.0)
  for i in 0..