27

I am trying to find out the sum of the diagonal elements in a matrix. Here, n is the size of the square matrix and a is the matrix. Can someone explain this to me what is happening here.

n = 3
a = [[11,2,4],[4,5,6],[10,8,-12]]
sum_first_diagonal = sum(a[i][i] for i in range(n))
sum_second_diagonal = sum(a[n-i-1][n-i-1] for i in range(n))
print(str(sum_first_diagonal)+" "+str(sum_first_diagonal))
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
  • You are summing the same diagonal twice, once from top left to bottom right and then the other way around. I don't believe that this code snippet can print anything other than `4 4` on any Python installation. – Sven Marnach Feb 07 '16 at 11:48

18 Answers18

25

Use numpy library which is powerful for any matrix calculations. For your specific case:

import numpy as np
a = [[11,2,4],[4,5,6],[10,8,-12]]
b = np.asarray(a)
print('Diagonal (sum): ', np.trace(b))
print('Diagonal (elements): ', np.diagonal(b))

You can easily install numpy with pip or other ways that you will find on many webs.

If you want all the diagonals, and not just the main diagonal, check this that also uses numpy.

EDIT

mhawke, if you want to calculate antidiagonal (secondary diagonal), as explained in wikipedia, you can flip the matrix in numpy

import numpy as np
a = [[11,2,4],[4,5,6],[10,8,-12]]
b = np.asarray(a)
b = np.fliplr(b)
print('Antidiagonal (sum): ', np.trace(b))
print('Antidiagonal (elements): ', np.diagonal(b))
iblasi
  • 1,269
  • 9
  • 21
  • I think the OP is unable to use `numpy` since they are submitting their code to an online judge that does not permit `numpy`. How is the second diagonal calculated? – mhawke Feb 07 '16 at 11:58
20

Try this for summing your second diagonal:

sum(a[i][n-i-1] for i in range(n))

The inner loop accesses these entries:

>>> n = 3
>>> [(i, n-i-1) for i in range(n)]
[(0, 2), (1, 1), (2, 0)]

And the summed value of this diagonal for your sample matrix is:

>>> n = 3
>>> sum(a[i][n-i-1] for i in range(n))
19

The mistake in your code is to use the same expression for both dimensions:

a[n-i-1][n-i-1]

which will process the first diagonal again in reverse order [(2, 2), (1, 1), (0, 0)] giving you the same sum twice.

mhawke
  • 84,695
  • 9
  • 117
  • 138
1

getting total and diagonal sum from a squared matrix

squared_matrix = [[2,3,4],[4,3,3],[3,3,4]]
s, ds = get_sum(squared_matrix)

def get_sum(diag_mat):
    n = len(diag_mat)
    total = sum([diag_mat[i][j] for i in range(n) for j in range(j)]
    d_sum = sum([diag_mat[i][j] if i==j else 0 for i in range(n) for j in range(j)]
   return d_sum, total
Samir Paul
  • 11
  • 1
1

Here is a simpler way to get the full primary diagonal and secondary diagonal

squared_matrix = [
    [2, 3, 4],
    [4, 3, 3],
    [3, 3, 4]
]


def primary_diagonal(matrix):
    sum = 0
    for i in range(len(matrix)):
        sum += matrix[i][i]
    return sum

def secondary_left_diagonal(matrix):
    sum = 0
    for i in range(len(matrix)):
        sum += matrix[i][len(matrix) - i - 1]
    return sum


print(primary_diagonal(squared_matrix))
print(secondary_left_diagonal(squared_matrix))

Result

9
10
Dhia Shalabi
  • 1,332
  • 1
  • 13
  • 29
0

try this:

n=3
sum_second_diagonal=sum([a[i][j] for i in range(n) for j in range(n) if i==j]) #it will add when i==j
Lokesh Sharma
  • 411
  • 5
  • 6
Binyamin Even
  • 3,318
  • 1
  • 18
  • 45
0
def sum_up_diagonals(li):
index = len(li)
first_dia =  sum(li[i][i]for i in range(index))
second_dia = sum(li[i][index-i-1]for i in range(index))
return (first_dia,second_dia)

Pass in your list. This should work for you :)

greyk0
  • 35
  • 5
0

O(n) time solution to find the diagonal difference of given multidimensional array.

def diagonalDifference(arr):
        # arr[0][0], arr[1][1], arr[2][2]
        # arr[0][2], arr[1][1], arr[2][0]
        sumOfDiagonalFromLeft = 0
        sumOfDiagonalFromRight = 0
        pointIndexFromLeft = 0
        pointIndexFromLast = len(arr)-1
        for i in range(len(arr)):
            sumOfDiagonalFromLeft += arr[i][pointIndexFromLeft]
            # print(arr[i][pointIndexFromLeft])
            pointIndexFromLeft += 1
        
        for i in range(len(arr)):
            sumOfDiagonalFromRight += arr[i][pointIndexFromLast]
            # print(arr[i][pointIndexFromLast])
            if pointIndexFromLast < 0:
                break
            else:
                pointIndexFromLast -= 1
    
        diagonalDifference = abs(sumOfDiagonalFromLeft - sumOfDiagonalFromRight)
        return diagonalDifference
    
arr = [[11, 2, 4], [4, 5, 6], [10, 8, -12]]
print(diagonalDifference(arr))
0
//we simply swap  corner elements of matrix

def diagonalDifference(arr):

    c=0;d=0
    for i in range(len(arr)):
        for j in range(len(arr)):
            if i==j :
                c = c+ arr[i][j]
        for k in range(len(arr)):
            arr[i][k-1],arr[i][k-2] = arr[i][k-2],arr[i][k-1]
        

        for j in range(len(arr)):
            if i==j :
                d = d + arr[i][j]
        for k in range(len(arr)):
            arr[i][k-1],arr[i][k-2] = arr[i][k-2],arr[i][k-1]
            
    
    
    print(c,d)  
    result = abs(c-d)
    print(result)
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
  • Welcome to Stack Overflow. Code dumps without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please [edit] your question and explain how it answers the specific question being asked. See [answer]. This is particularly important when answering old questions (this one is 5.5 years old) with existing answers. – ChrisGPT was on strike Aug 29 '21 at 19:33
0

Python 3 Solution with dynamic inputs of matrix as list inputs

#Even matrix size is dynamic in this code as "n".

n=int(input())
s1=0
s2=0
a =[]
for i in range(n):

    # x here take input of size n and as separate lists to act like a matrix.

    x=list(map(int,input().strip().split()))[:n]
    a.append(x)
for i in range(n):
    s1+=a[i][i]
    s2+=a[i][n-i-1]

# If use abs() only if non-negative output is needed!!
print(abs(s1-s2)) 
# First enter the size of matrix then enter the matrix vales with spaces in each line
0

Assuming a square matrix (nxn), you can compute the sums of both primary and secondary diagonals with only 1 iteration through the rows of the matrix; by keeping track of the indices involved in each computation.

mat = [
    [1,2,3],
    [4,5,6],
    [9,8,9]
]

primary = 0
secondary = 0
low = 0 # start index for primary
high = len(mat)-1 # end index for secondary

for row in mat:
    primary += row[low]
    secondary += row[high]
    low += 1
    high -= 1

print(f'Primary Sum = {primary}', f'Secondary Sum = {secondary}', sep='\n')
0

Let's suppose, you have a matrix A n×m.

  A = [[random.rand() for i in range(n+1)] for i in range(m+1)]
  
  d = m+n-1 # that's the overall number of different diagonals
  sumrow = [0]*d # I'd like to create a list of all the sums of those
  for diag in range(d): # iterate by diagonal number
      # A difference of two related spike functions, so that it was a spike without the top
      diaglength = int(max(0,1+d/2-abs(diag+1/2-d/2)) - max(0,1+d/2-n-abs(diag+1/2-d/2)))
      # initial coordinates for further iteration inside sum() function
      x = max(0, diag-m+1)
      y = max(0, m-diag-1)
      # iterating values along the current diagonal
      sumrow[diag]=sum(A[x+i][y+i] for i in range(0,diaglength))

Thus, sumrow[] is a list of every sum of every diagonal, choose and don't get puddled up. I think, it's obvious what to cut off this code to get some specific value immediately. Technically, this code could be compressed in one line. Really long line.

But why?

0

mat = [[1 ,2, 3, 4,5],[1,2,1,2,3],[2,3,4,5,2],[1,3,5,1,1],[1,2,1,2,1]]

def isSquare(mat): if len(mat) == 1: return True for i in range(len(mat)): if len(mat[i]) != len(mat): print("Matrix is not Squared") return False return True

def sumOfLeftDiagonal(mat): d1 = 0 size = len(mat) for i in range(0,size): for j in range(0,size): if i == j: d1 = d1 + mat[i][j] return d1

def sumOfRightDiagonal(mat): d2 = 0 size = len(mat) for i in range(0,size): d2 = d2 + mat[i][(size-1)-i] return d2

if isSquare(mat): if len(mat) == 1: print("Difference: ",mat[0]) else: print("sumOfLeftDiagonal: ",sumOfLeftDiagonal(mat)) print("sumOfRightDiagonal: ",sumOfRightDiagonal(mat)) print("Difference: ",abs(sumOfLeftDiagonal(mat)-sumOfRightDiagonal(mat)))

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 16 '22 at 06:55
0

Here is one way one how to do it:

Since the matrix is square we can get sum of a diagonal and anti-diagonal by using a original and reversed lists.

matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

to_sum =[]                             # an empty list for collection values

for i in range(len(matrix)):           # diagonal coordinats [0][0], [1][1].... [n][n]
    to_sum.append(matrix[i][i])        # append value of diagonal
    rev = matrix[i][::-1]              # for anti-diagonal reverse list
    to_sum.append(rev[i])              # append value of anti-diagonal
                                       # to_sum list [1, 4, 6, 7, 11, 10, 16, 13]
return sum(to_sum)                     # return sum of all values in list (68)
iGRiK
  • 13
  • 4
-1

Since you know the positions of the diagonal elements for row i, you can write it quite densely like:

d = sum(row[i] + row[-1-i] for i, row in a)

And, for odd sized matrices, you shouldn't add the center element twice:

if len(a)%2:
    centre = len(a)//2
    d -= a[centre][centre]
xtofl
  • 40,723
  • 12
  • 105
  • 192
-1
def sum_diagnol():
    import random
    sum=0
    r1=int(input("row"))
    c1=int(input("col"))
    a=[[random.random()for col in range(c1)]for row in range(r1)]
    print("enter elements")
    for i in range(r1):
        for j in range(c1):
            a[i][j]=int(input("enter elements"))
    r2=int(input("row"))
    c2=int(input("col"))
    b=[[random.random()for col in range(c2)]for row in range(r2)]
    print("enter elements")
    for i in range(r2):
        for j in range(c2):
            b[i][j]=int(input("enter elements"))
    c=[[random.random()for col in range(c2)]for row in range(r1)]
    if(c1==r2):
        for i in range(r1):
            for j in range(c2):
                c[i][j]=0
                for k in range(c2):
                    c[i][j]=a[j][k]*b[k][j]
    else:
        print("multiplication not possible")
    for i in range(r1):
        for j in range(c2):
            print(c[i][j],end=" ")
        print()
sum_diagnol()
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
-1

I found a simple algorithm to accomplish this task.

  1. Store the square matrix in a single one dimensional array.

  2. Let 'n' be the order of square matrix.

  3. There are two diagonals , one that starts from the leftmost element in top row and another that starts from nth element of the top row.

  4. To get the indexes of numbers on the diagonal that starts from left most element in top row ,from the array containing all the numbers in the matrix; just add (n+1) recursively starting from index 1. That is, indexes of elements in left to right diagonal in the array are, 1, 1+(n+1) , (n+2)+(n+1) , (2n+3)+(n+1) till the last index of array.

  5. To get the indexes of another diagonal's numbers from the array containing all the numbers in the matrix ; just add (n-1) recursively to the indexes starting from index equals to the 'n', which is the order of the square matrix. That is, indexes of elements in right to left diagonal in the array are, n, n+(n-1), (2n-1)+(n-1) and so on till the index equals to 'length of the array - (n-1)'.

  6. If the order is odd then subtract the middle number in the array from the final sum.

The example 'c++' code is as follows:

 #include<iostream>
 using namespace std;

int sumOfDiagonalNumbersInSquareMatrix(int numberArray[],int order){
int sumOfLeftToRightDiagonal = 0;
int sumOfRightToLeftDiagonal = 0;
int length = order*order;
for(int i=0; i<length;i+=(order+1)){
    //cout<<numberArray[i]<<"\t";
    sumOfLeftToRightDiagonal = sumOfLeftToRightDiagonal + numberArray[i];

}
for(int i=(order-1);i<=length-order;i+=(order-1)){
    //cout<<numberArray[i]<<"\t";
    sumOfRightToLeftDiagonal = sumOfRightToLeftDiagonal + numberArray[i];
}
if(order % 2 != 0){
    return (sumOfLeftToRightDiagonal + sumOfRightToLeftDiagonal) - numberArray[(length/2)];
}
return (sumOfLeftToRightDiagonal + sumOfRightToLeftDiagonal);
}

 int main(){
 int nums[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
 cout<<sumOfDiagonalNumbersInSquareMatrix(nums,4);
 return 0;
 }

You can run it here: http://cpp.sh/6cmdp

Deepeshkumar
  • 395
  • 3
  • 13
-1

I don't understand why no one posted any good solution. Here is as descent solution:

length = len(arr)
r1 = 0
r2 = 0
for i in range(length):
    r1 += arr[i][length - i - 1]
    r2 += arr[i][i]
print(r1 + r2)
# If you want sum of there absolute values
print(abs(r1) + abs(r2))

Here arr is a 2d list.

Akshat Tamrakar
  • 2,193
  • 2
  • 13
  • 21
-1

'''

a = [[],[],[]] #your matrix
s = 0
for i in range(len(a)):
    for j in range(len(a[0])):
           if i == j:
               s += a[i][j]
print('sum ='s)

''' here is a simple approach. Thanks