Matrices. Sistema de ecuaciones lineales. Valores y vectores propios.
Determinante y matriz inversa de una matriz cuadrada
Calcular el determinate y la matriz inversa de.
|
3
1
−1
2
1
−2
3
1
4
3
1
4
2
3
1
5
−2
−3
5
−1
−1
1
2
3
2
|
Comprueba que A·A-1=I (matriz identidad)
Solución
public class Vector {
public int n; //dimensión
double[] x;
public Vector(int n) {
this.n=n;
x=new double[n];
for(int i=0; i<n; i++){
x[i]=0.0;
}
}
public Vector(double[] x) {
this.x=x;
n=x.length;
}
public String toString(){
String texto=" ";
for(int i=0; i<n; i++){
texto+="\t "+(double)Math.round(1000*x[i])/1000;
}
texto+="\n";
return texto;
}
public static Vector producto(Matriz a,Vector v){
int n=v.n;
Vector b=new Vector(n);
for(int i=0; i<n; i++){
for(int k=0; k<n; k++){
b.x[i]+=a.x[i][k]*v.x[k];
}
}
return b;
}
}
public class Matriz implements Cloneable{
public int n; //dimensión
public double[][] x;
public Matriz(int n) {
this.n=n;
x=new double[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
x[i][j]=0.0;
}
}
}
public Matriz(double[][] x) {
this.x=x;
n=x.length;
}
public String toString(){
String texto="\n";
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
texto+="\t "+(double)Math.round(1000*x[i][j])/1000;
}
texto+="\n";
}
texto+="\n";
return texto;
}
public Object clone(){
Matriz obj=null;
try{
//llama a clone de la clase base Object
obj=(Matriz)super.clone();
}catch(CloneNotSupportedException ex){
System.out.println(" no se puede duplicar");
}
//copia la matriz bidimensional
obj.x=(double[][])obj.x.clone();
for(int i=0; i<obj.x.length; i++){
obj.x[i]=(double[])obj.x[i].clone();
}
return obj;
}
public static Matriz producto(Matriz a, Matriz b){
Matriz resultado=new Matriz(a.n);
for(int i=0; i<a.n; i++){
for(int j=0; j<a.n; j++){
for(int k=0; k<a.n; k++){
resultado.x[i][j]+=a.x[i][k]*b.x[k][j];
}
}
}
return resultado;
}
public double determinante(){
Matriz a=(Matriz)clone();
for(int k=0; k<n-1; k++){
for(int i=k+1; i<n; i++){
for(int j=k+1; j<n; j++){
a.x[i][j]-=a.x[i][k]*a.x[k][j]/a.x[k][k];
}
}
}
double deter=1.0;
for(int i=0; i<n; i++){
deter*=a.x[i][i];
}
return deter;
}
public static Matriz inversa(Matriz d){
int n=d.n;
Matriz a=(Matriz)d.clone();
Matriz b=new Matriz(n);
Matriz c=new Matriz(n);
//matriz unidad
for(int i=0; i<n; i++){
b.x[i][i]=1.0;
}
//transformación de la matriz y de los términos independientes
for(int k=0; k<n-1; k++){
for(int i=k+1; i<n; i++){
//términos independientes
for(int s=0; s<n; s++){
b.x[i][s]-=a.x[i][k]*b.x[k][s]/a.x[k][k];
}
//elementos de la matriz
for(int j=k+1; j<n; j++){
a.x[i][j]-=a.x[i][k]*a.x[k][j]/a.x[k][k];
}
}
}
//cálculo de las incógnitas, elementos de la matriz inversa
for(int s=0; s<n; s++){
c.x[n-1][s]=b.x[n-1][s]/a.x[n-1][n-1];
for(int i=n-2; i>=0; i--){
c.x[i][s]=b.x[i][s]/a.x[i][i];
for(int k=n-1; k>i; k--){
c.x[i][s]-=a.x[i][k]*c.x[k][s]/a.x[i][i];
}
}
}
return c;
}
}
public class MyClass1 {
public static void main(String[] args){
double[][] a1={{3,1,-1,2,1},{-2,3,1,4,3},{1,4,2,3,1},{5,-2,-3,5,-1},{-1,1,2,3,2}};
Matriz a=new Matriz(a1);
System.out.println("Determinante "+a.determinante());
System.out.println("Inversa: "+Matriz.inversa(a));
System.out.println("Comprobación:"+Matriz.producto(a, Matriz.inversa(a)));
}
}
Sistema de ecuaciones lineales
Resolver el sistema de eucaciones lineales
π
x
1
−e
x
2
+
2
x
3
−
3
x
4
=
11
π
2
x
1
+e
x
2
−
e
2
x
3
+
3
7
x
4
=0
5
x
1
−
6
x
2
+
x
3
−
2
x
4
=π
π
3
x
1
+
e
2
x
2
−
7
x
3
+
1
9
x
4
=
2
Solución
//Poner aquí las definiciones de las clases Vector y Matriz (ejercicio 1)
public class MyClass1 {
public static void main(String[] args){
double[][] m={{Math.PI,-Math.E,Math.sqrt(2),-Math.sqrt(3)},
{Math.PI*Math.PI, Math.E,-Math.E*Math.E,3.0/7},
{Math.sqrt(5),-Math.sqrt(6),1,-Math.sqrt(2)},
{Math.PI*Math.PI*Math.PI,Math.E*Math.E,-Math.sqrt(7),1.0/9}};
Matriz coef=new Matriz(m);
double[] n={Math.sqrt(11),0,Math.PI,Math.sqrt(2)};
Vector ter=new Vector (n);
Vector solucion=(Vector.producto(Matriz.inversa(coef), ter));
System.out.println("solución :"+solucion);
}
}
Resolver el sistema de ecuaciones lineales
3
x
1
+
x
2
−
x
3
+2
x
4
=6
−5
x
1
+
x
2
+3
x
3
−4
x
4
=−12
2
x
1
+0
x
2
+
x
3
−
x
4
=1
x
1
−5
x
2
−3
x
3
−3
x
4
=3
Press W. H., Teukolsky S. A., Vetterling W. T., Flannery B.
P. Numerical Recipes in C, Second edition. Chapter 2. Solution of Linear Algebraic Equations. 2.3 LU Decomposition and Its Applications. Cambridge University Press. Código en C adaptado por el
autor al lenguaje Java
Solución
public class LU {
private final static double TINY=1.0e-20;
static private void ludcmp(double[][] a, int[] indx) {
int n=a[0].length;
int i,imax=0,j,k;
double big,dum,sum,temp;
double[] vv=new double[n];
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=Math.abs(a[i][j])) > big) big=temp;
if (big == 0.0) System.out.println("Singular matrix in routine ludcmp");
vv[i]=1.0/big;
}
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
big=0.0;
for (i=j;i<n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*Math.abs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n-1) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
}
}
static private void lubksb(double[][] a, double b[], int[] indx){
int n=a[0].length;
int i,ii=0,ip,j;
double sum;
for (i=1;i<=n;i++) {
ip=indx[i-1];
sum=b[ip];
b[ip]=b[i-1];
if (ii>0)
for (j=ii;j<=i-1;j++) sum -= a[i-1][j-1]*b[j-1];
else if (sum!=0) ii=i;
b[i-1]=sum;
}
for (i=n-1;i>=0;i--) {
sum=b[i];
for (j=i+1;j<n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}
static public void resolver(double[][]a, double[] b){
int[] index=new int[b.length];
LU.ludcmp(a, index);
LU.lubksb(a, b, index);
}
}
public class MyClass1 {
public static void main(String[] args) {
double[][] a={{3, 1, -1, 2}, {-5, 1, 3, -4}, {2, 0, 1, -1}, {1, -5, -3, -3}};
double[] b={6, -12, 1, 3};
LU.resolver(a, b);
//solución
for(int i=0; i<b.length; i++){
System.out.print(b[i]+" ");
}
}
}
Valores propios y vectores propios
Calcular los valores propios de la matriz simétrica
[
1
2
3
4
2
1
2
3
3
2
1
2
4
3
2
1
]
Solución
public class Vector {
public int n;
double[] x;
public Vector(int n) {
this.n=n;
x=new double[n];
for(int i=0; i<n; i++){
x[i]=0.0;
}
}
public Vector(double[] x) {
this.x=x;
n=x.length;
}
public String toString(){
String texto=" ";
for(int i=0; i<n; i++){
texto+="\t "+(double)Math.round(1000*x[i])/1000;
}
texto+="\n";
return texto;
}
public static Vector producto(Matriz a,Vector v){
int n=v.n;
Vector b=new Vector(n);
for(int i=0; i<n; i++){
for(int k=0; k<n; k++){
b.x[i]+=a.x[i][k]*v.x[k];
}
}
return b;
}
}
public class Matriz implements Cloneable{
public int n;
public double[][] x;
public Matriz(int n) {
this.n=n;
x=new double[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
x[i][j]=0.0;
}
}
}
public Matriz(double[][] x) {
this.x=x;
n=x.length;
}
public String toString(){
String texto="\n";
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
texto+="\t "+(double)Math.round(1000*x[i][j])/1000;
}
texto+="\n";
}
texto+="\n";
return texto;
}
public Object clone(){
Matriz obj=null;
try{
//llama a clone de la clase base Object
obj=(Matriz)super.clone();
}catch(CloneNotSupportedException ex){
System.out.println(" no se puede duplicar");
}
//copia la matriz bidimensional
obj.x=(double[][])obj.x.clone();
for(int i=0; i<obj.x.length; i++){
obj.x[i]=(double[])obj.x[i].clone();
}
return obj;
}
public static Matriz producto(Matriz a, Matriz b){
Matriz resultado=new Matriz(a.n);
for(int i=0; i<a.n; i++){
for(int j=0; j<a.n; j++){
for(int k=0; k<a.n; k++){
resultado.x[i][j]+=a.x[i][k]*b.x[k][j];
}
}
}
return resultado;
}
public static Matriz inversa(Matriz d){
int n=d.n;
Matriz a=(Matriz)d.clone();
Matriz b=new Matriz(n);
Matriz c=new Matriz(n);
//matriz unidad
for(int i=0; i<n; i++){
b.x[i][i]=1.0;
}
//transformación de la matriz y de los términos independientes
for(int k=0; k<n-1; k++){
for(int i=k+1; i<n; i++){
//términos independientes
for(int s=0; s<n; s++){
b.x[i][s]-=a.x[i][k]*b.x[k][s]/a.x[k][k];
}
//elementos de la matriz
for(int j=k+1; j<n; j++){
a.x[i][j]-=a.x[i][k]*a.x[k][j]/a.x[k][k];
}
}
}
//cálculo de las incógnitas, elementos de la matriz inversa
for(int s=0; s<n; s++){
c.x[n-1][s]=b.x[n-1][s]/a.x[n-1][n-1];
for(int i=n-2; i>=0; i--){
c.x[i][s]=b.x[i][s]/a.x[i][i];
for(int k=n-1; k>i; k--){
c.x[i][s]-=a.x[i][k]*c.x[k][s]/a.x[i][i];
}
}
}
return c;
}
//matriz traspuesta
static Matriz traspuesta(Matriz a){
int n=a.n;
Matriz d=new Matriz(a.n);
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
d.x[i][j]=a.x[j][i];
}
}
return d;
}
public double[] polCaracteristico(){
Matriz pot=new Matriz(n);
//matriz unidad
for(int i=0; i<n; i++){
pot.x[i][i]=1.0;
}
double[] p=new double[n+1];
double[] s=new double[n+1];
//potencias de la matriz y traza
for(int i=1; i<=n; i++){
pot=Matriz.producto(pot, this);
s[i]=pot.traza();
}
//coeficientes del polinomio característico
p[0]=1.0;
p[1]=-s[1];
for(int i=2; i<=n; i++){
p[i]=-s[i]/i;
for(int j=1; j<i; j++){
p[i]-=s[i-j]*p[j]/i;
}
}
return p;
}
public double traza(){
double t=0;
for(int i=0; i<n; i++) t+=x[i][i];
return t;
}
}
//Raíces del polinomio por el procedimiento de Graeffe
//Vectores propios
//Definición de las clase Graeffe y Complejo
public class MyClass1 {
public static void main(String[] args) {
double[][] p1={{1,2,3,4},{2,1,2,3},{3,2,1,2},{4,3,2,1}};
Matriz p=new Matriz(p1);
double pol[]=p.polCaracteristico();
System.out.println("Polinomio característico");
for(int i=0; i<pol.length; i++){
System.out.print((double)Math.round(pol[i]*1000)/1000+" , ");
}
System.out.println("");
//raíces del polinomio
Graeffe g=new Graeffe(pol);
g.mostrarRaices();
double[] lambda=g.raicesReales; //valores propios
//vectores propios
double[][] p2=new double[p1.length-1][p1.length-1];
double[] ind=new double[p2.length];
Vector x;
Matriz m;
for(int j=0; j<ind.length; j++){
ind[j]=-p1[0][j+1];
}
Vector v=new Vector(ind);
for(int k=0; k<lambda.length; k++){
for(int i=0; i<p2.length; i++){
for(int j=0; j<p2.length; j++){
p2[i][j]=p1[i+1][j+1];
if(i==j) p2[i][j]=p1[i+1][j+1]-lambda[k];
}
}
m=new Matriz(p2);
System.out.println("Valor propio "+ lambda[k]);
System.out.println("Vectores propios ");
x=Vector.producto(Matriz.inversa(m), v);
System.out.println("1");
System.out.println(x);
}
}
}
Calcular los valores y vectores propios de la matriz simétrica por el procedimiento de Jacobi
[
1
2
3
4
2
1
2
3
3
2
1
2
4
3
2
1
]
Solución
public class Matriz implements Cloneable{
public int n; //dimensión
private double[][] x;
public Matriz(int n) {
this.n=n;
x=new double[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
x[i][j]=0.0;
}
}
}
public Matriz(double[][] x) {
this.x=x;
n=x.length;
}
public Object clone(){
Matriz obj=null;
try{
obj=(Matriz)super.clone();
}catch(CloneNotSupportedException ex){
System.out.println(" no se puede duplicar");
}
//este es el código para clonar la matriz bidimensional
obj.x=(double[][])obj.x.clone();
for(int i=0; i<obj.x.length; i++){
obj.x[i]=(double[])obj.x[i].clone();
}
return obj;
}
//producto de dos matrices
static Matriz producto(Matriz a, Matriz b){
Matriz resultado=new Matriz(a.n);
for(int i=0; i<a.n; i++){
for(int j=0; j<a.n; j++){
for(int k=0; k<a.n; k++){
resultado.x[i][j]+=a.x[i][k]*b.x[k][j];
}
}
}
return resultado;
}
//producto de una matriz por un escalar
static Matriz producto(Matriz a, double d){
Matriz resultado=new Matriz(a.n);
for(int i=0; i<a.n; i++){
for(int j=0; j<a.n; j++){
resultado.x[i][j]=a.x[i][j]*d;
}
}
return resultado;
}
//producto de un escalar por una matriz
static Matriz producto(double d, Matriz a){
Matriz resultado=new Matriz(a.n);
for(int i=0; i<a.n; i++){
for(int j=0; j<a.n; j++){
resultado.x[i][j]=a.x[i][j]*d;
}
}
return resultado;
}
//matriz traspuesta
static Matriz traspuesta(Matriz a){
int n=a.n;
Matriz d=new Matriz(a.n);
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
d.x[i][j]=a.x[j][i];
}
}
return d;
}
public Matriz valoresPropios(double[] valores, int maxIter)throws ValoresExcepcion{
final double CERO=1e-8;
double maximo, tolerancia, sumsq;
double x, y, z, c, s;
int contador=0;
int i, j, k, l;
Matriz a=(Matriz)clone(); //matriz copia
Matriz p=new Matriz(n);
Matriz q=new Matriz(n);
//matriz unidad
for(i=0; i<n; i++){
q.x[i][i]=1.0;
}
do{
k=0; l=1;
maximo=Math.abs(a.x[k][1]);
for(i=0; i<n-1; i++){
for(j=i+1; j<n; j++){
if(Math.abs(a.x[i][j])>maximo){
k=i; l=j;
maximo=Math.abs(a.x[i][j]);
}
}
}
sumsq=0.0;
for(i=0; i<n; i++){
sumsq+=a.x[i][i]*a.x[i][i];
}
tolerancia=0.0001*Math.sqrt(sumsq)/n;
if(maximo<tolerancia) break;
//calcula la matriz ortogonal de p
//inicialmente es la matriz unidad
for(i=0; i<n; i++){
for(j=0; j<n; j++){
p.x[i][j]=0.0;
}
}
for(i=0; i<n; i++){
p.x[i][i]=1.0;
}
y=a.x[k][k]-a.x[l][l];
if(Math.abs(y)<CERO){
c=s=Math.sin(Math.PI/4);
}else{
x=2*a.x[k][l];
z=Math.sqrt(x*x+y*y);
c=Math.sqrt((z+y)/(2*z));
s=signo(x/y)*Math.sqrt((z-y)/(2*z));
}
p.x[k][k]=c;
p.x[l][l]=c;
p.x[k][l]=s;
p.x[l][k]=-s;
a=Matriz.producto(p, Matriz.producto(a, Matriz.traspuesta(p)));
q=Matriz.producto(q, Matriz.traspuesta(p));
contador++;
}while(contador<maxIter);
if(contador==maxIter){
throw new ValoresExcepcion("No se han podido calcular los valores propios");
}
//valores propios
for(i=0; i<n; i++){
valores[i]=(double)Math.round(a.x[i][i]*1000)/1000;
}
//vectores propios
return q;
}
private int signo(double x){
return (x>0 ? 1 : -1);
}
public String toString(){
String texto="\n";
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
texto+="\t "+(double)Math.round(1000*x[i][j])/1000;
}
texto+="\n";
}
texto+="\n";
return texto;
}
}
class ValoresExcepcion extends Exception {
public ValoresExcepcion() {
super();
}
public ValoresExcepcion(String s) {
super(s);
}
}public class MyClass1 {
public static void main(String[] args) {
System.out.println("Valores y vectores propios ");
double[][] p1={{1,2,3,4},{2,1,2,3},{3,2,1,2},{4,3,2,1}};
Matriz matriz=new Matriz(p1);
Matriz vectores=new Matriz(matriz.n);
double[] valores=new double[matriz.n];
try{
vectores=matriz.valoresPropios(valores, 20);
}catch(ValoresExcepcion ex){
System.out.println("Al calcular los valores propios
se ha producido una excepción\n "
+ex.getClass()+ " con el mensaje "+ ex.getMessage());
}
for(int i=0; i<matriz.n; i++){ //valores propios
System.out.print(valores[i]+" , ");
}
System.out.println("");
System.out.println(vectores); //vectores propios
}
}
Calcular los valores y vectores propios de la matriz simétrica
[
4
2
2
2
5
1
2
1
6
]
Press W. H., Teukolsky S. A., Vetterling W. T., Flannery B.
P. Numerical Recipes in C, Second edition. Chapter 11. Eigensystems. 11.1 Jacobi Transformations of a Symmetric Matrix. Cambridge University Press. Código en C adaptado por el
autor al lenguaje Java
Solución
public class Jacobi {
//el vector d son los valores propios
//Las columnas de la matriz v son los vectores propios
//devuelve el número de iteracciones
static int calcula(double[][] a, double[] d, double[][] v) {
int n=a[0].length;
int j,iq,ip,i;
double tresh,theta,tau,t,sm,s,h,g,c;
double[] b=new double[n]; //b=vector(1,n);
double[] z=new double[n]; //z=vector(1,n);
for (ip=0;ip<n;ip++) { //Initialize to the identity matrix.
for (iq=0;iq<n;iq++) v[ip][iq]=0.0;
v[ip][ip]=1.0;
}
for (ip=0;ip<n;ip++) { //Initialize b and d to the diagonal of a.
b[ip]=d[ip]=a[ip][ip];
z[ip]=0.0;
//This vector will accumulate terms of the form tapq as in equation
}
int nrot=0;
for (i=1;i<=50;i++) {
sm=0.0;
for (ip=0;ip<=n-2;ip++) { //Sum o -diagonal elements.
for (iq=ip+1;iq<n;iq++)
sm += Math.abs(a[ip][iq]);
}
if (sm == 0.0) {
//The normal return, which relies on quadratic convergence to machine underflow.
return nrot;
}
if (i < 4)
tresh=0.2*sm/(n*n);// ...on the rst three sweeps.
else
tresh=0.0; //...thereafter.
for (ip=0;ip<n-1;ip++) {
for (iq=ip+1;iq<n;iq++) {
g=100.0*Math.abs(a[ip][iq]);
//After four sweeps, skip the rotation if the o -diagonal element is small.
if (i > 4 && (float)(Math.abs(d[ip])+g) == (float)Math.abs(d[ip])
&& (float)(Math.abs(d[iq])+g) == (float)Math.abs(d[iq]))
a[ip][iq]=0.0;
else if (Math.abs(a[ip][iq]) > tresh) {
h=d[iq]-d[ip];
if ((float)(Math.abs(h)+g) == (float)Math.abs(h))
t=(a[ip][iq])/h; // t = 1=(2 )
else {
theta=0.5*h/(a[ip][iq]); //Equation (11.1.10).
t=1.0/(Math.abs(theta)+Math.sqrt(1.0+theta*theta));
if (theta < 0.0) t = -t;
}
c=1.0/Math.sqrt(1+t*t);
s=t*c;
tau=s/(1.0+c);
h=t*a[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
a[ip][iq]=0.0;
for (j=0;j<=ip-1;j++) {
g=a[j][ip];
h=a[j][iq];
a[j][ip]=g-s*(h+g*tau);
a[j][iq]=h+s*(g-h*tau);
}
for (j=ip+1;j<=iq-1;j++) {
g=a[ip][j];
h=a[j][iq];
a[ip][j]=g-s*(h+g*tau);
a[j][iq]=h+s*(g-h*tau);
}
for (j=iq+1;j<n;j++) {
g=a[ip][j];
h=a[iq][j];
a[ip][j]=g-s*(h+g*tau);
a[iq][j]=h+s*(g-h*tau);
}
for (j=0;j<n;j++) {
g=v[j][ip];
h=v[j][iq];
v[j][ip]=g-s*(h+g*tau);
v[j][iq]=h+s*(g-h*tau);
}
++nrot;
}
}
}
for (ip=0;ip<n;ip++) {
b[ip] += z[ip];
d[ip]=b[ip]; //Update d with the sum of tapq,
z[ip]=0.0; //and reinitialize z.
}
}
return nrot;
}
}
public class MyClass1 {
public static void main(String[] args) {
System.out.println("Valores y vectores propios ");
double[][] m={{4,2,2},{2,5,1},{2,1,6}};
double[][] vectores=new double[m[0].length][m[0].length];
double[] valores=new double[m[0].length];
Jacobi.calcula(m, valores, vectores);
System.out.println("Valores propios");
for(int i=0; i<m[0].length; i++){
System.out.print(valores[i]+" , ");
}
System.out.println("");
System.out.println("Vectores propios");
for(int i=0; i<m[0].length; i++){
for(int j=0; j<m[0].length; j++){
System.out.print(vectores[i][j]+" , ");
}
System.out.println();
}
}
}