class_docstr: This class redefine the backpropagation of a quaternion linear layer
  (not a spinor layer). By doing so, we can save up to 4x memory, but it
  is also 2x slower than 'quaternion_linear_op'. It should be used
  within speechbrain.nnet.quaternion_networks.linear.QuaternionLinear.
class_docstr_tok: ["This","class","redefine","the","backpropagation","of","a","quaternion","linear","layer","(","not","a","spinor","layer",")",".","By","doing","so",",","we","can","save","up","to","4x","memory",",","but","it","is","also","2x","slower","than","'quaternion_linear_op","'",".","It","should","be","used","within","speechbrain.nnet.quaternion_networks.linear.QuaternionLinear","."]
docstr: Applies a quaternion linear transformation to the incoming data:
  It is important to notice that the forward phase of a QNN is defined
  as W * Inputs (with * equal to the Hamilton product). The constructed
  cat_kernels_4_quaternion is a modified version of the quaternion
  representation so when we do torch.mm(Input,W) it's equivalent
  to W * Inputs.
  
  Arguments
  ---------
  input : torch.Tensor
      Quaternion input tensor to be transformed. Shape: [batch*time, X].
  r_weight : torch.Parameter
      Real part of the quaternion weight matrix of this layer.
  i_weight : torch.Parameter
      First imaginary part of the quaternion weight matrix of this layer.
  j_weight : torch.Parameter
      Second imaginary part of the quaternion weight matrix of this layer.
  k_weight : torch.Parameter
      Third imaginary part of the quaternion weight matrix of this layer.
  bias : torch.Parameter
docstr_tok: ["Applies","a","quaternion","linear","transformation","to","the","incoming","data",":","It","is","important","to","notice","that","the","forward","phase","of","a","QNN","is","defined","as","W","*","Inputs","(","with","*","equal","to","the","Hamilton","product",")",".","The","constructed","cat_kernels_4_quaternion","is","a","modified","version","of","the","quaternion","representation","so","when","we","do","torch.mm","(","Input",",","W",")","it","'s","equivalent","to","W","*","Inputs",".","Arguments","--","--","--","--","-","input",":","torch.Tensor","Quaternion","input","tensor","to","be","transformed",".","Shape",":","[","batch","*","time",",","X","]",".","r_weight",":","torch.Parameter","Real","part","of","the","quaternion","weight","matrix","of","this","layer",".","i_weight",":","torch.Parameter","First","imaginary","part","of","the","quaternion","weight","matrix","of","this","layer",".","j_weight",":","torch.Parameter","Second","imaginary","part","of","the","quaternion","weight","matrix","of","this","layer",".","k_weight",":","torch.Parameter","Third","imaginary","part","of","the","quaternion","weight","matrix","of","this","layer",".","bias",":","torch.Parameter"]
code: def forward(ctx, input, r_weight, i_weight, j_weight, k_weight, bias):
      """
      Applies a quaternion linear transformation to the incoming data:
      It is important to notice that the forward phase of a QNN is defined
      as W * Inputs (with * equal to the Hamilton product). The constructed
      cat_kernels_4_quaternion is a modified version of the quaternion
      representation so when we do torch.mm(Input,W) it's equivalent
      to W * Inputs.
  
      Arguments
      ---------
      input : torch.Tensor
          Quaternion input tensor to be transformed. Shape: [batch*time, X].
      r_weight : torch.Parameter
          Real part of the quaternion weight matrix of this layer.
      i_weight : torch.Parameter
          First imaginary part of the quaternion weight matrix of this layer.
      j_weight : torch.Parameter
          Second imaginary part of the quaternion weight matrix of this layer.
      k_weight : torch.Parameter
          Third imaginary part of the quaternion weight matrix of this layer.
      bias : torch.Parameter
      """
  
      ctx.save_for_backward(
          input, r_weight, i_weight, j_weight, k_weight, bias
      )
  
      cat_kernels_4_r = torch.cat(
          [r_weight, -i_weight, -j_weight, -k_weight], dim=0
      )
      cat_kernels_4_i = torch.cat(
          [i_weight, r_weight, -k_weight, j_weight], dim=0
      )
      cat_kernels_4_j = torch.cat(
          [j_weight, k_weight, r_weight, -i_weight], dim=0
      )
      cat_kernels_4_k = torch.cat(
          [k_weight, -j_weight, i_weight, r_weight], dim=0
      )
      cat_kernels_4_quaternion = torch.cat(
          [
              cat_kernels_4_r,
              cat_kernels_4_i,
              cat_kernels_4_j,
              cat_kernels_4_k,
          ],
          dim=1,
      )
      if bias.requires_grad:
          return torch.addmm(bias, input, cat_kernels_4_quaternion)
      else:
          return torch.mm(input, cat_kernels_4_quaternion)
  
file_path: speechbrain/speechbrain/nnet/quaternion_networks/q_ops.py
imports: import torch
  import math
  import numpy
  import torch.nn.functional
  from scipy.stats import chi
  from torch.autograd import Variable
label_desc: Use image node_id 1 for calling the QuaternionLinearCustomBackward obj's underlying member method code with example usage: obj.forward(ctx, input, r_weight, i_weight, j_weight, k_weight, bias) and returns: torch, torch