##Exercice 3 :

##Q3 : Corrigé
import numpy as np

def phi(M):
    (n,p)=np.shape(M)
    s=0
    for i in range(n):
        for j in range(p):
            s+=M[i,j]
    return s

##Q4 : fonction donnée
import numpy as np

def ortho(dim=3):
     random_state = np.random
     H = np.eye(dim)
     D = np.ones((dim,))
     for n in range(1, dim):
         x = random_state.normal(size=(dim-n+1,))
         D[n-1] = np.sign(x[0])
         x[0] -= D[n-1]*np.sqrt((x*x).sum())
         # Householder transformation
         Hx = (np.eye(dim-n+1) - 2.*np.outer(x, x)/(x*x).sum())
         mat = np.eye(dim)
         mat[n-1:, n-1:] = Hx
         H = np.dot(H, mat)
         # Fix the last sign such that the determinant is 1
     D[-1] = (-1)**(1-(dim % 2))*D.prod()
     # Equivalent to np.dot(np.diag(D), H) but faster, apparently
     H = (D*H.T).T
     return H

##Q4 : Corrigé :

from numpy.linalg import det

def simul(n):
    mini=n
    maxi=n
    mini1=n
    maxi1=n
    for i in range(8000):
        M=ortho(n)
        a=phi(M)
        print(a)
        if a<mini:
            mini=a
        if a>maxi:
            maxi=a
        if det(M)>0:
            if a<mini1:
                mini1=a
            if a>maxi1:
                maxi1=a
    return mini, maxi, mini1, maxi1

##
print(simul(3))