Torch.ger() for batch usage

Hi all,

My torch version is 1.6.0.

And I can use torch.ger() method to calculate the outer product of two tensors.

For example, I can calculate the outer product of two vectors of shape 1x2 which gives me an output with shape 2x2.

But for example, if I store the tensors of shape 1 x 2 for which I want to calculate outer products with themselves in a batch tensor of shape N x 2 for example, I can’t do the batch calculation. At the end what I want is a solution tensor of shape N x 2 x 2 for example. Below are some example outputs

Would you please comment on how I can calculate this?

And then what I need further is to calculate the mean of the diagonal terms of the previous solution output which was of shape N x 2 x 2. My expected output for this part should be N x 1.
I think I also need in this part as well.

Thank you in advance
-Jarvi

import torch

print(torch.__version__)


a = torch.tensor([1.,2.])
b = torch.tensor([3.,4.])


print("a is ",a)
print("shape of a is ",a.shape)
print("b is ",b)
print("shape of b is ",b.shape)

outer_a = torch.ger(a,a)
print("outer product of a and a is ",outer_a)
print("shape of outer_a is ",outer_a.shape)

print("mean of the diagonal terms for outer_b is ",torch.diagonal(outer_a, 0).mean().item())

outer_b = torch.ger(b,b)
print("outer product of b and b is ",outer_b)
print("shape of outer_b is ",outer_b.shape)

print("mean of the diagonal terms for outer_b is ", torch.diagonal(outer_b, 0).mean().item())

t = torch.tensor([[1.,2.],[3.,4.]])

print("t is ",t)
print("shape of t is ",t.shape)

#outer_t = torch.ger(t,t) # THIS IS NOT WORKING

solution = torch.tensor([[[ 1.,  2.], [ 2.,  4.]], [[ 9., 12.], [12., 16.]]])

print("solution is ",solution)
print("shape of solution is ",solution.shape)

print("mean of the diagonal terms for solution is   ",torch.tensor([[2.5],[12.5]]))

OUTPUTS : 
1.6.0
a is  tensor([1., 2.])
shape of a is  torch.Size([2])
b is  tensor([3., 4.])
shape of b is  torch.Size([2])
outer product of a and a is  tensor([[1., 2.],
        [2., 4.]])
shape of outer_a is  torch.Size([2, 2])
mean of the diagonal terms for outer_b is  2.5
outer product of b and b is  tensor([[ 9., 12.],
        [12., 16.]])
shape of outer_b is  torch.Size([2, 2])
mean of the diagonal terms for outer_b is  12.5
t is  tensor([[1., 2.],
        [3., 4.]])
shape of t is  torch.Size([2, 2])
solution is  tensor([[[ 1.,  2.],
         [ 2.,  4.]],

        [[ 9., 12.],
         [12., 16.]]])
shape of solution is  torch.Size([2, 2, 2])
mean of the diagonal terms for solution is    tensor([[ 2.5000],
        [12.5000]])
#shape is 2x1

Update after searching on the forum, I think these solve the problems:

outer_product = a[:, :, None] @ a[:, None, :]
solution.diagonal(dim1=-2, dim2=-1)[:]