Está en la página 1de 15

En esta página, definiremos la clase Vector y la clase Matriz cuadrada, las operaciones

entre matrices, suma y producto de dos matrices, el producto de una matriz por un
vector, el producto de una matriz por un escalar, la traza de una matriz y la matriz
traspuesta de una matriz dada.

Vectores y matrices
Un vector es un array unidimensional de números. Se define la clase Vector con dos
miembros dato, el número de datos que guarda y el array unidimensional que guarda
dichos datos.

public class Vector {


public int n;
double[] x;

La clase Vector y la clase Matriz están en el mismo paquete. El miembro dato x de la


clase Vector tiene el control de acceso por defecto, es decir, público dentro del mismo
paquete pero privados fuera del paquete. Más abajo, en esta página al definir las
funciones miembro de la clase Matriz que realizan operaciones entre matrices y
vectores veremos que, los objetos de la clase Vector necesitan acceder a su miembro
dato x.

Una matriz es un array bidimensional de números. En general, decimos que una matriz
tiene una dimensión m x n, cuando los números están dispuestos en m filas y n
columnas.

Se denominan matrices cuadradas a aquellas que tienen el mismo número de filas que
de columnas. Estas matrices tienen especial importancia y serán las que tratemos en
estas páginas.

public class Matriz{


public int n;
private double[][] x;

La clase Matriz tiene dos miembros dato, la dimensión de la matriz n, y un array


bidimensional x, que crearemos e inicializaremos en los constructores.

Los constructores
Vamos a definir dos constructores en la clase Vector, al primero se le pasa el número de
elementos que va a guardar e inicializan a cero todos sus elementos.

public Vector(int n) {
this.n=n;
x=new double[n];
for(int i=0; i<n; i++){
x[i]=0.0;
}
}

Para crear un vector v de dimensión tres se escribe

Vector v=new Vector(3);

Al segundo constructor, se le pasa el array unidiemensional, e inicializa el miembro dato


x con los valores que guardan los elementos de dicho array en una única y simple
operación de asignación

public Vector(double[] x) {
this.x=x;
n=x.length;
}

Para crear un vector v que guarde los datos del array v1 se escribe

double[] v1={1, 2, 3};


Vector v=new Vector(v1);

Para la clase Matriz necesitamos definir dos constructores, al primero se le pasa la


dimensión n de la matriz cuadrada, creando un array bidimensional de n filas y n
columnas, e inicializa todos sus elementos a cero.

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;
}
}
}

Para crear una matriz a de dimensión tres cuyos elementos son todos ceros, se escribe.

Matriz a=new Matriz(3);

Al segundo constructor, se le pasa un array bidimensional, e inicializa el miembro dato


x con los valores que guardan los elementos de dicho array en una única y simple
operación de asignación.

public Matriz(double[][] x) {
this.x=x;
n=x.length;
}

Para crear la matriz a


se crea un array bidimensional a1, y se le pasa al constructor de la clase Matriz

double[][] a1={{1, 2, 3},{-2, -4, -5},{3, 5, 6}};


Matriz a=new Matriz(a1);
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;
}
//otras funciones miembro
}
****************************************
public class Matriz{
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;
}
//otras funciones miembro
}

Mostrar un vector y una matriz


Para mostrar un vector redefinimos la función toString de la clase base Object, de la
cual deriva implícitamente Vector. Separamos sus elementos mediante el carácter
tabulador '\t'.

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;
}
Vamos añadiendo al string texto, los elementos del vector y el carácter separador entre
elementos, limitamos el número de decimales a tres mediante la función Math.round.
Para concluir la fila y pasar a la siguiente en la pantalla de texto, añadimos un carácter
retorno de carro '\n'. Mediante la operación + definida en la clase String podemos
concatenar fácilmente los distintos elementos y crear la representación textual del vector
que devuelve la función toString

Para mostrar el vector v en la pantalla de texto, basta escribir la sentencia

Vector v=new Vector(v1);


System.out.println(v);

Mostrar una matriz en la pantalla de texto es difícil, ya que Java no dispone de una
función que sitúe el cursor de texto en una posición de la pantalla, como lo hace la
función gotoxy disponible en los lenguajes C/C++. La única alternativa que nos queda
es mostrar los elementos de una fila unos a continuación de los otros separados por un
tabulador, después otra fila y así hasta mostrar todos los elementos de la matriz.

Para mostrar los elementos de la matriz, redefinimos la función toString de la clase base
Object, de la cual deriva implícitamente Matriz. Separamos los elementos de una fila
mediante el carácter tabulador '\t', y limitamos el número de decimales a tres mediante
la función Math.round. Cuando se acaba una fila se inserta un retorno de carro '\n' y se
continua con la siguiente fila, y así sucesivamente.

for(int j=0; j<n; j++){


texto+="\t "+(double)Math.round(1000*x[i][j])/1000;
}
texto+="\n";

Vamos añadiendo al string texto, los elementos de la matriz y los caracteres separadores
entre elementos y entre filas de elementos.

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;
}

Para mostrar una matriz a en la pantalla de texto basta escribir la sentencia

Matriz a=new Matriz(a1);


System.out.println(a);

public class Vector {


public int n; //dimensión
double[] x;
//...
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 class Matriz{
public int n; //dimensión
private double[][] x;
//...
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;
}
}

Copia de una matriz dada


Cuando calculamos la matriz inversa de una dada, pasamos una matriz en el único
parámetro de la función estática denominada inversa. En el cuerpo de dicha función se
realizan operaciones con los elementos de dicha matriz. Dado que en Java se pasan por
valor las referencias a objetos, la matriz original resulta modificada en el curso de la
llamada a la función inversa.

Si queremos mantener la matriz original, hacemos una copia de dicha matriz en el


cuerpo de la función y realizamos las operaciones con la matriz copia dejando la
original sin modificar.

Para realizar una copia hemos de implementar el interface Cloneable, y redefinir la


función miembro clone de la clase base Object, de la cual derivan todas las clases en
Java. El primer paso es la llamada a la función clone de la clase base Object.

public class Matriz implements Cloneable{


public int n; //dimensión
private double[][] x;
//..........
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;
}
}

Para obtener una copia a de una matriz d se escribe.

Matriz a=(Matriz)d.clone();

La promoción (casting) es necesaria ya que clone devuelve una referencia a un objeto de


la clase base Object.

Traza de una matriz


Se denomina traza de una matriz cuadrada a la suma de los elementos de su diagonal
principal.

public double traza(){


double tr=0.0;
for(int i=0; i<n; i++){
tr+=x[i][i];
}
return tr;
}

Para obtener la traza de la matriz a de la sección anterior se escribe

double traza=a.traza();

Operaciones con matrices y vectores


Suma de dos matrices cuadradas

Cuando se suman dos matrices de las mismas dimensiones


Se obtiene otra matriz c en la que sus elementos cij son las suma de los correspondientes
elementos de las matrices a y b, es decir

cij=aij+bij

Para sumar dos matrices, se define una función miembro estática denominada suma.
Dentro de la función, se crea una matriz temporal resultado, con la misma dimensión de
las matrices que intervienen en la operación, y se guardan en sus elementos el resultado
de la suma de las matrices a y b. Finalmente, la función suma devuelve la matriz
resultado.

public static Matriz suma(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++){
resultado.x[i][j]=a.x[i][j]+b.x[i][j];
}
}
return resultado;
}

Veamos ahora como se llama a la función que suma dos matrices.

double[][] a1={{1, 2, 3},{4,5,6},{7,8,9}};


Matriz a=new Matriz(a1);
double[][] b1={{1, 0, -1},{2,1,3},{-1, 0, 2}};
Matriz b=new Matriz(b1);
Matriz re=Matriz.suma(a, b);
System.out.println("matriz "+re);

Producto de dos matrices

La regla para multiplicar dos matrices es bastante más complicada que para sumar dos
matrices de las mismas dimensiones. En general, se pueden multiplicar dos matrices de
dimensiones m x n y n x q, dando como resultado una matriz de dimensiones m x q. En
este apartado nos circunscribiremos exclusivamente a matrices cuadradas de dimensión
n.

Los elementos cij se obtienen multiplicando los elementos aik de la fila i por los
elementos akj de la columna j, y sumando los resultados.

La codificación se realiza empleando un tripe bucle for, guardando en los elementos de


la la matriz local resultado la suma de los productos de la fórmula anterior.
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;
}

Otras variantes de la operación producto son:

El producto de un escalar (número real) por una matriz que da como resultado otra
matriz cuyos elementos están todos multiplicados por dicho escalar. Se define también
la operación conmutativa

public 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;
}

Al multiplicar una matriz cuadrada de dimensión n, por un vector columna de la misma


dimensión obtenemos otro vector columna. Cada elemento del vector resultante se
obtiene multiplicando los elementos de una fila de la matriz por los correspondientes
elementos del vector columna y se suman los resultados. La codificación de esta
función producto es la siguiente:

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;
}

Al multiplicar un vector fila por una matriz cuadrada de la misma dimensión obtenemos
otro vector fila. El código es semejante al de la función producto definida previamente.

public static Vector producto(Vector v, Matriz a){


int n=v.n;
Vector b=new Vector(n);
for(int j=0; j<n; j++){
for(int k=0; k<n; k++){
b.x[j]+=v.x[k]*a.x[k][j];
}
}
return b;
}

Matriz traspuesta
Una matriz traspuesta de otra matriz es aquella que tiene los mismos elementos pero
dispuestos en forma distinta. Las columnas de la matriz original se transforman en filas
de la matriz traspuesta. La definición de la función estática traspuesta no reviste
dificultad alguna

public static Matriz traspuesta(Matriz a){


int n=a.n;
Matriz resultado=new Matriz(a.n);
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
resultado.x[i][j]=a.x[j][i];
}
}
return resultado;
}

Para hallar la matriz traspuesta de la matriz a se escribe

double[][] a1={{1, 2, 3},{4,5,6},{7,8,9}};


Matriz a=new Matriz(a1);
Matriz tras=Matriz.traspuesta(a);
System.out.println("matriz traspuesta"+tras);

char matriz[X][Y]; à Bidimensional de tipo carácter. Podéis observar su representación grafica a la


derecha. Como podéis apreciar en esta matriz, X adquiere el valor de 7 al igual que Y que también vale
7. En este caso de matriz se requiere de dos índices para poder acceder o guardar datos. Un ejemplo de
almacenamiento de un carácter en esta matriz seria: matriz[4][4]=10; Esto almacenaría el valor 10 en
la casilla que se encuentra en la posición X=4, Y=4. No me digáis que nunca habéis jugado a hundir la
flota de MB xD.
#include <stdio.h>
#include <conio.h>

main()
{
cha r matr i z [7/]*[7Dec
] ; la ramos una matr i z de 7*7 ca rac te res * /
i n t c ,d ; / * Contadores * /

for(c=0;c<=6;c++)
{
for(d=0;d<=6;d++)
{
printf("Caracter para guardar en matriz[%d][%d]: ",c,d);
scanf("%c",&matriz[c][d]);
getchar ( ) ;
}
}

for(c=0;c<=6;c++)
{
for(d=0;d<=6;d++)
{
printf("\nValor matriz[%d][%d]=%c",c,d,matriz[c][d]);
}
}
getch();
}
Tutorial

Este tutorial se divide en las siguientes secciones:

• Matrices en general

• Declarar matrices

• Inicializar matrices

• Acceso a miembros de matrices

• Las matrices son objetos

• Usar foreach con matrices

Matrices en general

En las matrices de C#, los índices empiezan en cero. Las matrices de C# funcionan de forma similar a
como lo hacen en la mayoría de los lenguajes populares; existen, sin embargo, algunas diferencias que
se deben conocer.

Cuando se declara una matriz, los corchetes ([]) deben ir después del tipo, no después del identificador.
Colocar los corchetes después del identificador no es sintácticamente válido en C#.

int[] table; // not int table[];

Otro detalle es que el tamaño de la matriz no forma parte de su tipo, como ocurre en el lenguaje C. Esto
permite declarar una matriz y asignarle cualquier matriz de objetos int, independientemente de la
longitud de la matriz.

int[] numbers; // declare numbers as an int array of any size


numbers = new int[10]; // numbers is a 10-element array
numbers = new int[20]; // now it's a 20-element array

Declarar matrices

C# admite matrices de una dimensión, matrices multidimensionales (matrices rectangulares) y matrices


de matrices (matrices escalonadas). El siguiente ejemplo muestra cómo declarar diferentes tipos de
matrices:

Matrices unidimensionales:

int[] numbers;

Matrices multidimensionales:

string[,] names;

Matrices de matrices (escalonadas):


byte[][] scores;

La declaración de matrices (como se muestra arriba) no crea realmente las matrices. En C#, las
matrices son objetos (se explica más adelante en este tutorial) cuyas instancias deben crearse. Los
siguientes ejemplos muestran cómo crear matrices:

Matrices unidimensionales:

int[] numbers = new int[5];

Matrices multidimensionales:

string[,] names = new string[5,4];

Matrices de matrices (escalonadas):

byte[][] scores = new byte[5][];


for (int x = 0; x < scores.Length; x++)
{
scores[x] = new byte[4];
}

También se pueden utilizar matrices más grandes. Por ejemplo, se puede utilizar una matriz rectangular
de tres dimensiones:

int[,,] buttons = new int[4,5,3];

Incluso, se pueden combinar matrices rectangulares y escalonadas. Por ejemplo, el siguiente código
declara una matriz unidimensional que contiene matrices tridimensionales de matrices bidimensionales
de tipo int:

int[][,,][,] numbers;

Ejemplo

El siguiente es un programa completo en C# que declara y crea instancias de las matrices comentadas
anteriormente.

// arrays.cs
using System;
class DeclareArraysSample
{
public static void Main()
{
// Single-dimensional array
int[] numbers = new int[5];

// Multidimensional array
string[,] names = new string[5,4];

// Array-of-arrays (jagged array)


byte[][] scores = new byte[5][];

// Create the jagged array


for (int i = 0; i < scores.Length; i++)
{
scores[i] = new byte[i+3];
}

// Print length of each row


for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine("Length of row {0} is {1}", i, scores[i].Length);
}
}
}
Resultado
Length of row 0 is 3
Length of row 1 is 4
Length of row 2 is 5
Length of row 3 is 6
Length of row 4 is 7

Inicializar matrices

C# proporciona métodos simples y sencillos para inicializar matrices en el momento de la declaración


encerrando los valores iniciales entre llaves ({}). Los siguientes ejemplos muestran diferentes modos de
inicializar diferentes tipos de matrices.

Nota Si no inicializa una matriz en el momento de la declaración, sus miembros se inicializan


automáticamente con el valor inicial predeterminado para el tipo de matriz. Además, si declara la matriz
como campo de un tipo, se establecerá con el valor predeterminado null cuando cree la instancia del
tipo.

Matrices unidimensionales
int[] numbers = new int[5] {1, 2, 3, 4, 5};
string[] names = new string[3] {"Matt", "Joanne", "Robert"};

El tamaño de la matriz se puede omitir, como se indica a continuación:

int[] numbers = new int[] {1, 2, 3, 4, 5};


string[] names = new string[] {"Matt", "Joanne", "Robert"};

También se puede omitir el operador new si se utiliza un inicializador como el siguiente:

int[] numbers = {1, 2, 3, 4, 5};


string[] names = {"Matt", "Joanne", "Robert"};

Matrices multidimensionales
int[,] numbers = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };
string[,] siblings = new string[2, 2] { {"Mike","Amy"}, {"Mary","Albert"} };

El tamaño de la matriz se puede omitir, como se indica a continuación:

int[,] numbers = new int[,] { {1, 2}, {3, 4}, {5, 6} };


string[,] siblings = new string[,] { {"Mike","Amy"}, {"Mary","Albert"} };

También se puede omitir el operador new si se utiliza un inicializador como el siguiente:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };


string[,] siblings = { {"Mike", "Amy"}, {"Mary", "Albert"} };

Matriz escalonada (matriz de matrices)

Las matrices escalonadas se pueden inicializar como en el siguiente ejemplo:

int[][] numbers = new int[2][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };

El tamaño de la primera matriz se puede omitir, como se indica a continuación:

int[][] numbers = new int[][] { new int[] {2,3,4}, new int[] {5,6,7,8,9} };

O bien

int[][] numbers = { new int[] {2,3,4}, new int[] {5,6,7,8,9} };

Observe que no existe sintaxis de inicialización para los elementos de una matriz escalonada.

Acceso a miembros de matrices


El acceso a los miembros de una matriz es sencillo y similar al de los miembros de una matriz de C o
C++. Por ejemplo, el siguiente código crea una matriz denominada numbers y, a continuación, asigna un
5 al quinto elemento de la matriz:

int[] numbers = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};


numbers[4] = 5;

El siguiente código declara una matriz multidimensional y asigna el valor 5 al miembro ubicado en [1,
1]:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10} };
numbers[1, 1] = 5;

La siguiente es una declaración de una matriz escalonada de una sola dimensión que contiene dos
elementos. El primer elemento es una matriz de dos enteros, mientras que el segundo es una matriz de
tres enteros:

int[][] numbers = new int[][] { new int[] {1, 2}, new int[] {3, 4, 5}
};

La siguiente instrucción asigna 58 al primer elemento de la primera matriz y 667 al segundo elemento
de la segunda matriz:

numbers[0][0] = 58;
numbers[1][1] = 667;

Las matrices son objetos

En C#, las matrices son realmente objetos. System.Array es el tipo base abstracto de todos los tipos
de matrices. Las propiedades y otros miembros de la clase System.Array se pueden utilizar cuando sea
necesario. Un ejemplo de esto sería utilizar la propiedad Length para obtener la longitud de una matriz.
El siguiente código asigna la longitud de la matriz numbers, que es 5, a una variable denominada
LengthOfNumbers:

int[] numbers = {1, 2, 3, 4, 5};


int LengthOfNumbers = numbers.Length;

La clase System.Array proporciona muchos otros métodos y propiedades útiles, como métodos para
ordenar, buscar y copiar matrices.

Usar foreach con matrices

C# dispone de la instrucción foreach. Esta instrucción proporciona un modo simple y limpio de iterar en
los elementos de una matriz. Por ejemplo, el siguiente código crea una matriz denominada numbers y la
recorre mediante la instrucción foreach:

int[] numbers = {4, 5, 6, 1, 2, 3, -2, -1, 0};


foreach (int i in numbers)
{
System.Console.WriteLine(i);
}

Con matrices multidimensionales, se puede utilizar el mismo método para recorrer los elementos, por
ejemplo:

int[,] numbers = new int[3, 2] {{9, 99}, {3, 33}, {5, 55}};
foreach(int i in numbers)
{
Console.Write("{0} ", i);
}

El resultado de este ejemplo es:

9 99 3 33 5 55
Sin embargo, con matrices multidimensionales, utilizar un bucle for anidado proporciona más control
sobre los elementos de la matriz.