using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sistema
{
class Matrice:MRettangolare
{
public Matrice(int dimensione): base(dimensione, dimensione)
{
}
public Matrice(Matrice originale):base(originale.Righe, originale.Colonne)
{
int fine = vettore.Length;
for (int i = 0; i < fine; i++)
vettore[i] = originale.vettore[i];
}
public Matrice() : this(3)
{ }
public int Dimensione
{
get
{
return Righe;
}
}
public double Determinante()
{
// Calcolo del determinante mediantl l'algoritmo di Gauss Jordn.
if (Righe == 1)
return vettore[0];
Matrice servizio
= new Matrice
(this);
double moltiplicatore,esito;
for (int i=0; i<Dimensione; i++)
{
if (!servizio.CercaRigaNonNulla(i, out int nonNulla))
{
return 0.0;
}
if (i != nonNulla)
{
servizio.ScambiaRighe(i, nonNulla);
}
for (int j = i + 1; j < Righe; j++)
{
if (Math.Abs(servizio[j, i]) > 1e-100)
{
moltiplicatore = servizio[j, i] / servizio[i, i];
for (int l=i; l<Righe; l++)
{
servizio[j, l] = servizio[j, l] - moltiplicatore * servizio[i, l];
}
}
}
}
esito = 1.0;
for (int i = 0; i < Righe; i++)
esito *= servizio[i, i];
return esito;
}
public Matrice Trasporteta()
{
Matrice esito
= new Matrice
(Righe
);
for (int i = 0; i < Righe; i++)
for (int j = 0; j < Righe; j++)
esito[i, j] = this[j, i];
return esito;
}
public static Matrice Identita(int dimensione)
{
Matrice Esito
= new Matrice
(dimensione
);
for (int i = 0; i < Esito.Dimensione; i++)
Esito[i, i] = 1.0;
return Esito;
}
public double ComplementoAlgebrico(int riga, int colonna)
{
ControlloDimensioni(riga, colonna);
int fine = Righe - 1;
Matrice servizio
= new Matrice
(fine
);
int pRiga, pColonna;
for (int i = 0; i < fine; i++)
{
pRiga = i >= riga ? i + 1 : i;
for (int j = 0; j < fine; j++)
{
pColonna = j >= colonna ? j + 1 : j;
servizio[i, j] = this[pRiga, pColonna];
}
}
return servizio.Determinante();
}
public static bool Divisione(Matrice sinistra, Matrice destra, out Matrice risultato)
{
if (destra.Dimensione != sinistra.Dimensione)
{
risultato = null;
return false;
}
if (destra.Inversa(out Matrice terza))
{
MRettangolare esito = sinistra * terza;
risultato
= new Matrice
(esito.
Colonne);
for (int i = 0; i < risultato.Righe; i++)
for (int j = 0; j < risultato.Colonne; j++)
risultato[i, j] = esito[i, j];
return true;
}
else
{
risultato = null;
return false;
}
}
public bool Inversa(out Matrice risultato)
{
double determinante;
determinante = Determinante();
if (Math.Abs(determinante) < 1e-100)
{
risultato = null;
return false;
}
risultato
= new Matrice
(Righe
);
Matrice servizio = Trasporteta();
for (int i=0; i<Righe; i++)
{
for (int j=0; j<Righe; j++)
{
double segno = ((i + j) & 1) == 0 ? 1.0 : -1.0;
risultato[i, j] = (segno / determinante) * servizio.ComplementoAlgebrico(i, j);
}
}
return true;
}
private bool CercaRigaNonNulla(int posizione, out int risultato)
{
risultato = posizione;
do
{
if (Math.Abs(this[risultato, posizione]) > 1e-100)
{
return true;
}
risultato++;
} while (risultato < Righe);
return false;
}
private void ScambiaRighe(int prima, int seconda)
{
double temp;
for (int i =0; i<Righe; i++)
{
temp = this[prima, i];
this[prima, i] = this[seconda, i] * -1.0;
this[seconda, i] = temp;
}
}
}
}