#!/usr/bin/env python

# Homework 2, problem 2.  Conventions and notation follow the C
# version, hw2.2.c, wherever possible.
#
# Run with
#
#	hw2.2.py < hw2.2.dat

import sys

from numpy import zeros
from scipy import dot
from scipy.linalg import lu_factor
from scipy.linalg import lu_solve

n = int(sys.stdin.readline())
print "n =", n

A = zeros((n,n))

for i in range(n):
    for j in range(n):
        A[i,j] = float(sys.stdin.readline())

# No lubksb in this version, so decompose and invert in the python way.

LU,piv = lu_factor(A)	# LU is combined L and U, with permutations included

# Compute the determinant.  In this version, LU has the relevant
# diagonal elements.

d = 1
for i in range(n):
    d *= LU[i,i]
print "determinant =", d

# Invert column by column, as in hw2.2.c.

Ainv = zeros((n,n))
for j in range(n):
    col = zeros(n)
    col[j] = 1
    xj = lu_solve((LU,piv), col)
    for i in range(n):
        Ainv[i,j] = xj[i]

print "\ninverse first row:"
print Ainv[0]

print "\ninverse last row:"
print Ainv[n-1]

# Check.

I = dot(A, Ainv)
max_diag = 0
max_offd = 0

for i in range(n):
    for j in range(n):
        if i == j:
            error = abs(I[i,i] - 1)
            if (error  > max_diag):
                max_diag = error
        else:
            error = abs(I[i,i] - 1)
            if (error  > max_offd):
                max_offd = error

print "\nmax diagonal error =", max_diag
print "max off-diagonal error =", max_offd

