5 Best Ways to Compute Sums of Diagonals of a Matrix Using Python

πŸ’‘ Problem Formulation: This article focuses on how to compute the sum of the main and secondary diagonals of a square matrix using Python. A matrix here is represented as a 2D list, with the main diagonal running from the top-left to the bottom-right and the secondary diagonal running from the top-right to the bottom-left. For instance, given a matrix [[1, 2, 3], [4, 5, 6], [7, 8, 9]], the desired outputs should be 15 for the main diagonal (1 + 5 + 9) and 15 for the secondary diagonal (3 + 5 + 7).

Method 1: Using a Straightforward Approach

An intuitive method for computing diagonal sums involves iterating through the matrix with loops. For the main diagonal, you would sum elements where the row and column indices are equal. For the secondary diagonal, you would sum elements where the indices fulfill the condition row_index + column_index = size of the matrix – 1.

Here’s an example:

def diagonal_sums(matrix):
    size = len(matrix)
    main_diagonal_sum = sum(matrix[i][i] for i in range(size))
    secondary_diagonal_sum = sum(matrix[i][size-1-i] for i in range(size))
    return main_diagonal_sum, secondary_diagonal_sum

# Example matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Call the function and print the sums
print(diagonal_sums(matrix))

Output of the code snippet

(15, 15)

This code snippet defines a function diagonal_sums() that computes the sums of the main and secondary diagonals of a given square matrix. It uses list comprehensions to sum the appropriate elements by iterating over the range of the matrix length.

Method 2: Using NumPy Library

NumPy offers a highly optimized way to perform various matrix operations. For diagonal sums, numpy.trace() can be used for the main diagonal, and numpy.fliplr().trace() for the secondary diagonal since numpy.fliplr() flips the matrix left-right.

Here’s an example:

import numpy as np

def diagonal_sums_numpy(matrix):
    np_matrix = np.array(matrix)
    main_diagonal_sum = np.trace(np_matrix)
    secondary_diagonal_sum = np.trace(np.fliplr(np_matrix))
    return main_diagonal_sum, secondary_diagonal_sum

# Example matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Call the function and print the sums
print(diagonal_sums_numpy(matrix))

Output of the code snippet

(15, 15)

The diagonal_sums_numpy() function leverages NumPy’s built-in methods to calculate the diagonal sums efficiently. This approach is faster for larger matrices due to NumPy’s optimizations under the hood.

Method 3: Using the zip Function

The Python built-in zip function can be harnessed to compute the sum of the main diagonal in a single line by pairing up the elements of each row with its matching index and summing them.

Here’s an example:

def main_diagonal_sum_zip(matrix):
    return sum(row[i] for i, row in enumerate(matrix))

# Example matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Call the function and print the sum
print(main_diagonal_sum_zip(matrix))

Output of the code snippet

15

This snippet introduces the function main_diagonal_sum_zip() which iterates through the matrix while leveraging the enumerate and zip functions to extract each row’s diagonal element and calculate their sum.

Method 4: Using List Slicing

List slicing in Python can be effectively used to extract the diagonals of a matrix. By using a slicing step equal to the length of the matrix plus one for the main diagonal, and minus one for the secondary diagonal, we can get the respective diagonal elements.

Here’s an example:

def diagonal_sums_slicing(matrix):
    size = len(matrix)
    main_diagonal_sum = sum(matrix[i][i] for i in range(size))
    secondary_diagonal_sum = sum(matrix[i][-i-1] for i in range(size))
    return main_diagonal_sum, secondary_diagonal_sum

# Example matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Call the function and print the sums
print(diagonal_sums_slicing(matrix))

Output of the code snippet

(15, 15)

In this code, the function diagonal_sums_slicing() utilizes list slicing to obtain the necessary elements. It iterates over the indices of the matrix, but uses negative indexing for the secondary diagonal.

Bonus One-Liner Method 5: Using List Comprehensions

A concise one-liner using list comprehensions makes use of Python’s concise expression syntax to directly sum the diagonal elements without explicitly writing out a loop.

Here’s an example:

# Example matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# One-liners to compute diagonal sums
main_diagonal_sum = sum(matrix[i][i] for i in range(len(matrix)))
secondary_diagonal_sum = sum(matrix[i][~i] for i in range(len(matrix)))

print(main_diagonal_sum, secondary_diagonal_sum)

Output of the code snippet

15 15

The one-liners use list comprehensions where ~i is equivalent to -i-1 and acts as a concise way to access elements from the end of the list.

Summary/Discussion

  • Method 1: Straightforward Approach. Clear and easy to understand. Not the most efficient for large matrices.
  • Method 2: Using NumPy Library. Very efficient and concise. Requires an external library.
  • Method 3: Using the zip Function. A creative use of built-in functions. Only applies to the main diagonal.
  • Method 4: Using List Slicing. A simple method that plays on Python’s indexing capabilities. Very similar to the first method in terms of efficiency.
  • Method 5: One-Liner List Comprehensions. Extremely concise. Might be less readable for beginners.