import java.awt.*; import javax.swing.*; import java.text.*; public class GElim extends JFrame { /** Crea un nuevo formulario GElim */ public GElim() { initComponents(); initMatrixDisplay(3,4); model = new Model(); } public void initMatrixDisplay(int i, int j){ matrixDisplay = new MatrixDisplay(i,j); getContentPane().add(matrixDisplay, BorderLayout.CENTER); pack(); } /** Este método es llamado desde el constructor para * inicializar el formulario. * ADVERTENCIA: NO modifique este código. El contenido de este método * siempre se regenera desde el Editor de formularios. */ private void initComponents() { bottomPanel = new javax.swing.JPanel(); outputPanel = new javax.swing.JPanel(); ouputLabel = new javax.swing.JLabel(); controlPanel = new javax.swing.JPanel(); pivotButton = new javax.swing.JButton(); backSolveButton = new javax.swing.JButton(); divideButton = new javax.swing.JButton(); solveButton = new javax.swing.JButton(); swapRow = new javax.swing.JPanel(); swapLabel1 = new javax.swing.JLabel(); swapText1 = new javax.swing.JTextField(); swapLabel2 = new javax.swing.JLabel(); swapText2 = new javax.swing.JTextField(); swapButton = new javax.swing.JButton(); rowOperationPanel = new javax.swing.JPanel(); rowOperationLabel1 = new javax.swing.JLabel(); mult1Text = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); rowOperation1Text = new javax.swing.JTextField(); plusLabel = new javax.swing.JLabel(); mult2Text = new javax.swing.JTextField(); jLabel4 = new javax.swing.JLabel(); rowOperation2Text = new javax.swing.JTextField(); rowOperationButton = new javax.swing.JButton(); topPanel = new javax.swing.JPanel(); buttonHolder = new javax.swing.JPanel(); numEquLabel = new javax.swing.JLabel(); numEquText = new javax.swing.JTextField(); setupButton = new javax.swing.JButton(); editPanel = new javax.swing.JPanel(); undoButton = new javax.swing.JButton(); saveButton = new javax.swing.JButton(); loadButton = new javax.swing.JButton(); demoButton = new javax.swing.JButton(); quitButton = new javax.swing.JButton(); setTitle("Sistemas de ecuaciones lineales"); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); bottomPanel.setLayout(new java.awt.GridLayout(4, 0)); outputPanel.setBorder(new javax.swing.border.EtchedBorder(null, java.awt.Color.black)); outputPanel.setBackground(java.awt.Color.white); outputPanel.add(ouputLabel); bottomPanel.add(outputPanel); pivotButton.setToolTipText("Realiza una resolución directa reduciendo a 0 todas las celdas por debajo de la seleccionada"); pivotButton.setText("Pivot en la selección"); pivotButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pivotButtonActionPerformed(evt); } }); controlPanel.add(pivotButton); backSolveButton.setToolTipText("Sustituye el valor de la celda seleccionada en las filas superiores."); backSolveButton.setText("Sust. inversa en la selección"); backSolveButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backSolveButtonActionPerformed(evt); } }); controlPanel.add(backSolveButton); divideButton.setToolTipText("Divide toda la fila entre el valor de la celda seleccionada"); divideButton.setText("Dividir por la selección"); divideButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { divideButtonActionPerformed(evt); } }); controlPanel.add(divideButton); solveButton.setToolTipText("Reduce la matriz a un \"formulario escalonado de fila reducida\""); solveButton.setText("Resolver"); solveButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { solveButtonActionPerformed(evt); } }); controlPanel.add(solveButton); bottomPanel.add(controlPanel); swapLabel1.setText("Cambiar filas:"); swapRow.add(swapLabel1); swapText1.setColumns(3); swapRow.add(swapText1); swapLabel2.setText("y"); swapRow.add(swapLabel2); swapText2.setColumns(3); swapRow.add(swapText2); swapButton.setToolTipText("Cambia la primera fila con nombre por la segunda"); swapButton.setText("Cambiar"); swapButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { swapButtonActionPerformed(evt); } }); swapRow.add(swapButton); bottomPanel.add(swapRow); rowOperationLabel1.setText("Operación de filas:"); rowOperationPanel.add(rowOperationLabel1); mult1Text.setColumns(4); rowOperationPanel.add(mult1Text); jLabel2.setText("Fila x"); rowOperationPanel.add(jLabel2); rowOperation1Text.setColumns(3); rowOperationPanel.add(rowOperation1Text); plusLabel.setText("+"); rowOperationPanel.add(plusLabel); mult2Text.setColumns(4); rowOperationPanel.add(mult2Text); jLabel4.setText("Fila x"); rowOperationPanel.add(jLabel4); rowOperation2Text.setColumns(3); rowOperationPanel.add(rowOperation2Text); rowOperationButton.setToolTipText("O multiplica una fila por una constante o sustituye la primera fila con nombre por una combinación con la segunda "); rowOperationButton.setText("Realizar"); rowOperationButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { rowOperationButtonActionPerformed(evt); } }); rowOperationPanel.add(rowOperationButton); bottomPanel.add(rowOperationPanel); getContentPane().add(bottomPanel, java.awt.BorderLayout.SOUTH); topPanel.setLayout(new java.awt.GridLayout(3, 0)); numEquLabel.setText("Número de variables y ecuaciones"); buttonHolder.add(numEquLabel); numEquText.setColumns(3); buttonHolder.add(numEquText); setupButton.setToolTipText("Construye una matriz NxN, siendo N = número de variables = número de ecuaciones"); setupButton.setText("Instalación"); setupButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { setupButtonActionPerformed(evt); } }); buttonHolder.add(setupButton); topPanel.add(buttonHolder); undoButton.setToolTipText("Invierte la acción anterior"); undoButton.setText("Deshacer"); undoButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { undoButtonActionPerformed(evt); } }); editPanel.add(undoButton); saveButton.setToolTipText("Guarda la matriz actual."); saveButton.setText("Guardar"); saveButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveButtonActionPerformed(evt); } }); editPanel.add(saveButton); loadButton.setToolTipText("Carga la matriz guardada"); loadButton.setText("Cargar"); loadButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { loadButtonActionPerformed(evt); } }); editPanel.add(loadButton); demoButton.setToolTipText("Carga la matriz guardada previamente"); demoButton.setText("Demo"); demoButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { demoButtonActionPerformed(evt); } }); editPanel.add(demoButton); quitButton.setToolTipText("Cierra el programa"); quitButton.setText("Salir"); quitButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { quitButtonActionPerformed(evt); } }); editPanel.add(quitButton); topPanel.add(editPanel); getContentPane().add(topPanel, java.awt.BorderLayout.NORTH); pack(); } private void backSolveButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ model.setCurrentMatrix(matrixDisplay.getMatrix()); if(model.backSolve_check1(matrixDisplay.getCurrentCol()) ) //la selección pertenece a la matriz b ouputLabel.setText("No es posible sustituir en b. Necesita seleccionar una celda en A"); else{ if(model.backSolve_check2(matrixDisplay.getCurrentRow(), matrixDisplay.getCurrentCol())) // la selección no es la única x distinta de cero de la fila ouputLabel.setText("El valor de x" + matrixDisplay.getCurrentCol()+ " sigue siendo desconocido. No es posible la sustitución inversa."); else{ model.backSolve_selection(matrixDisplay.getCurrentRow(), matrixDisplay.getCurrentCol()); matrixDisplay.setMatrix(model.getCurrentMatrix()); ouputLabel.setText(""); } } } catch(IllegalArgumentException e){ ouputLabel.setText("No es posible la resolución inversa en un 0"); } } private void quitButtonActionPerformed(java.awt.event.ActionEvent evt) { System.exit(0); } private void demoButtonActionPerformed(java.awt.event.ActionEvent evt) { Matrix demoMatrix = model.getDemoMatrix(); if(demoMatrix != null){ getContentPane().remove(matrixDisplay); matrixDisplay = new MatrixDisplay(demoMatrix.getNumRows(), demoMatrix.getNumCols()); getContentPane().add(matrixDisplay, BorderLayout.CENTER); pack(); matrixDisplay.setMatrix(demoMatrix); ouputLabel.setText("Demo cargada"); } else{ ouputLabel.setText("No hay demo disponible"); } } private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) { Matrix savedMatrix = model.getSavedMatrix(); if(savedMatrix != null){ getContentPane().remove(matrixDisplay); matrixDisplay = new MatrixDisplay(savedMatrix.getNumRows(), savedMatrix.getNumCols()); getContentPane().add(matrixDisplay, BorderLayout.CENTER); pack(); matrixDisplay.setMatrix(savedMatrix); ouputLabel.setText("Matriz cargada"); } else{ ouputLabel.setText("No se ha guardado nada"); } } private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) { model.setSavedMatrix(matrixDisplay.getMatrix()); ouputLabel.setText("Matriz guardada"); } private void undoButtonActionPerformed(java.awt.event.ActionEvent evt) { Matrix previousMatrix = model.getPreviousMatrix(); if(previousMatrix != null){ matrixDisplay.setMatrix(previousMatrix); ouputLabel.setText(""); } else{ ouputLabel.setText("No hay nada para deshacer"); } } private void rowOperationButtonActionPerformed(java.awt.event.ActionEvent evt) { int row1 = 1,row2 =1; double mult1=1, mult2=0; boolean flag = true; try{ row1 = Integer.parseInt(rowOperation1Text.getText()); } catch(NumberFormatException e){flag = false; ouputLabel.setText("Row Undefined"); } try{ if((rowOperation2Text.getText()).equals("")) row2=1; else row2 = Integer.parseInt(rowOperation2Text.getText()); } catch(NumberFormatException e){ouputLabel.setText("Entrada no válida"); flag = false;} try{ if((mult1Text.getText()).equals("")) mult1=1; else mult1 = Double.parseDouble(mult1Text.getText()); } catch(NumberFormatException e){ flag = false; ouputLabel.setText("Entrada no válida");} try{ if((mult2Text.getText()).equals("")) mult2=0; else mult2 = Double.parseDouble(mult2Text.getText()); } catch(NumberFormatException e){ flag = false; ouputLabel.setText("Entrada no válida");} if(flag){ try{ model.setCurrentMatrix(matrixDisplay.getMatrix()); model.row_operation(row1-1,mult1,row2-1,mult2); matrixDisplay.setMatrix(model.getCurrentMatrix()); ouputLabel.setText(""); } catch(IllegalArgumentException e){ ouputLabel.setText("Número de filas no válido"); } } } private void swapButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ int row1 = Integer.parseInt(swapText1.getText()); int row2 = Integer.parseInt(swapText2.getText()); if(row1 <=0 || row2<=0) ouputLabel.setText("Introduzca enteros mayores que 0"); else{ model.setCurrentMatrix(matrixDisplay.getMatrix()); model.swap_rows(row1-1, row2-1); matrixDisplay.setMatrix(model.getCurrentMatrix()); ouputLabel.setText(""); } } catch(IllegalArgumentException e){ ouputLabel.setText("Número de filas no válido"); } } private void divideButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ model.setCurrentMatrix(matrixDisplay.getMatrix()); model.divide_selection(matrixDisplay.getCurrentRow(), matrixDisplay.getCurrentCol()); matrixDisplay.setMatrix(model.getCurrentMatrix()); ouputLabel.setText(""); } catch(IllegalArgumentException e){ ouputLabel.setText("No es posible dividir por 0"); } } private void pivotButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ model.setCurrentMatrix(matrixDisplay.getMatrix()); model.pivot_selection(matrixDisplay.getCurrentRow(), matrixDisplay.getCurrentCol()); matrixDisplay.setMatrix(model.getCurrentMatrix()); ouputLabel.setText(""); } catch(IllegalArgumentException e){ ouputLabel.setText("No es posible un pivot en 0"); } } private void solveButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ model.setCurrentMatrix(matrixDisplay.getMatrix()); matrixDisplay.setMatrix(model.solve()); ouputLabel.setText("Matriz resuelta"); } catch(NumberFormatException e){ ouputLabel.setText("Matriz resuelta"); } } private void setupButtonActionPerformed(java.awt.event.ActionEvent evt) { try{ int numEqu = Integer.parseInt(numEquText.getText()); int numUnk = numEqu+1; if(numEqu <1 || numUnk<1) ouputLabel.setText("Introduzca un entero mayor que 1"); else{ getContentPane().remove(matrixDisplay); matrixDisplay = new MatrixDisplay(numEqu, numUnk); getContentPane().add(matrixDisplay, BorderLayout.CENTER); pack(); ouputLabel.setText(""); model.reset(numEqu,numUnk); } } catch(NumberFormatException e){ ouputLabel.setText("Introduzca enteros mayores que 1"); } } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } public static void main(String args[]) { new GElim().show(); } // Declaración de variables: no las modifique private javax.swing.JPanel bottomPanel; private javax.swing.JPanel outputPanel; private javax.swing.JLabel ouputLabel; private javax.swing.JPanel controlPanel; private javax.swing.JButton pivotButton; private javax.swing.JButton backSolveButton; private javax.swing.JButton divideButton; private javax.swing.JButton solveButton; private javax.swing.JPanel swapRow; private javax.swing.JLabel swapLabel1; private javax.swing.JTextField swapText1; private javax.swing.JLabel swapLabel2; private javax.swing.JTextField swapText2; private javax.swing.JButton swapButton; private javax.swing.JPanel rowOperationPanel; private javax.swing.JLabel rowOperationLabel1; private javax.swing.JTextField mult1Text; private javax.swing.JLabel jLabel2; private javax.swing.JTextField rowOperation1Text; private javax.swing.JLabel plusLabel; private javax.swing.JTextField mult2Text; private javax.swing.JLabel jLabel4; private javax.swing.JTextField rowOperation2Text; private javax.swing.JButton rowOperationButton; private javax.swing.JPanel topPanel; private javax.swing.JPanel buttonHolder; private javax.swing.JLabel numEquLabel; private javax.swing.JTextField numEquText; private javax.swing.JButton setupButton; private javax.swing.JPanel editPanel; private javax.swing.JButton undoButton; private javax.swing.JButton saveButton; private javax.swing.JButton loadButton; private javax.swing.JButton demoButton; private javax.swing.JButton quitButton; // Fin de la declaración de variables private MatrixDisplay matrixDisplay; private int currentRow; private int currentCol; Model model; } class Gauss{ public static void gaussian(Matrix a, Matrix b, Matrix x) { int i, j, n; n= a.getNumRows(); // Número de incógnitas Matrix q= new Matrix(n, n+1); for (i=0; i < n; i++) { for (j=0; j < n; j++) // Forma la matriz q // q(i,j)= a(i,j) q.setElement(i, j, a.getElement(i, j)); // q(i,n)= b(i,0) q.setElement(i, n, b.getElement(i, 0)); } forward_solve(q); // Realiza la eliminación gaussiana back_solve(q); // Realiza la sustitución inversa for (i=0; iMath.abs(q.getElement(maxr,i))) maxr= j; if (maxr != i) // Si la fila no es la actual, cambia a otra for (k=i; k <= n; k++) { t= q.getElement(i,k); // t= q(i,k) // q(i,k)= q(maxr, k) q.setElement(i,k, q.getElement(maxr, k)); q.setElement(maxr, k, t); // q(maxr, k)= t } for (j= i+1; j =i; k--) q.setElement(j, k, q.getElement(j,k)- q.getElement(i,k)*pivot); // q(j,k) -= q(i,k)*pivot; Actualiza la fila j por debajo de la diagonal } } } private static void back_solve(Matrix q) { int j, k, n; double t; // t- temporal n= q.getNumRows(); for (j=n-1; j >=0; j--) // Comienza en la última fila { t= 0.0; for (k= j+1; k < n; k++) // t += q(j,k)* q(k,n) t += q.getElement(j,k)* q.getElement(k,n); q.setElement(j, n, (q.getElement(j, n) -t)/q.getElement(j,j)); // q(j, n)= (q(j, n) -t)/q(j,j); } } public static void divide_selection(Matrix q, int pivotRow, int pivotCol){ int n; n = q.getNumCols(); double denom = q.getElement(pivotRow,pivotCol); for(int j=0; j=0; i--){ double pivot = -q.getElement(i,backSolveCol)/q.getElement(backSolveRow,backSolveCol); for(int j=0; j= 0.0000001 && j!= currentCol) //la selección no es la única x sin ceros de la fila flag = true; if(Math.abs(currentMatrix.getElement(currentRow, currentCol)) <= 0.0000001) //En caso de que la selección sea 0, no sabemos si la selección es conocida o no. //backSolve_selection(i,j) se encargará de ello. Devolverá un valor true. flag = false; return flag; } //Comprueba si la selección está en la matriz b public boolean backSolve_check1(int currentCol){ if (currentCol == (currentMatrix.getNumCols() -1)) return true; else return false; } public void swap_rows(int row1, int row2) throws IllegalArgumentException{ double tempValue; if(row1>= currentMatrix.getNumRows() || row2>= currentMatrix.getNumRows()) throw new IllegalArgumentException(); else{ for(int j=0; j= currentMatrix.getNumRows() || row2>= currentMatrix.getNumRows() || row1 < 0 || row2< 0) throw new IllegalArgumentException(); else{ for(int j=0; j< currentMatrix.getNumCols(); j++){ double addValue = currentMatrix.getElement(row2,j)*mult2; double newValue = currentMatrix.getElement(row1,j) * mult1 + addValue; currentMatrix.setElement(row1,j, newValue); } } } } class Matrix { private double[][] data; // Referencia a la matriz // Constructor para la matriz public Matrix(int m, int n) { data = new double[m][n]; } public Matrix() { // Constructor predeterminado data = new double[1][1]; } // Método para definir la identidad de Matrix public void setIdentity() { int i,j; int nrows = data.length; int ncols = data[0].length; for(i=0; i