package Util; import java.util.ArrayList; import java.util.Iterator; /** * Classe che modella una matrice triangolare espandibile dinamicamente * */ public class DTMatrix<E> { /** * Costruttore base */ public DTMatrix(){ this(minSize); } /** * Costruttore con parametro * @param size grandezza della matrice, che sarà size * (size + 1)/2 */ public DTMatrix(int size){ terms = new ArrayList<E>(); values = allocateMatrix(size); } /** * Alloca una matrice triangolare inferiore * @param size Grandezza della matrice * @return Una matrice triangolare inferiore */ protected double[][] allocateMatrix(int size) { double[][] tmp = new double[size][]; for(int i = 0; i < size; i++) tmp[i] = new double[i+1]; return tmp; } /** * Aumenta le dimensioni di una matrice * @param matrix La matrice iniziale * @return Una matrice grande il doppio, con gli stessi dati dell'originale */ protected double[][] growSize(double[][] matrix) { int newSize = matrix.length * 2; double[][] newMatrix = allocateMatrix(newSize); for(int i = 0; i < matrix.length; i++){ System.arraycopy(matrix[i], 0, newMatrix[i], 0, matrix[i].length); } return newMatrix; } /** * Metodo che controlla se la grandezza della matrice dei valori è * abbastanza grande, se non lo è ne aumenta la grandezza. */ protected void checkSize(){ if(terms.size() > values.length) values = growSize(values); } /** * Metodo che restituisce il valore associato al termine indicato * @param term Il termine di cui si vuole conoscere il valore associato * @return Il valore associato al termine term */ protected double getValue(E term){ int i; if(!terms.contains(term)) return -1; i = terms.indexOf(term); return values[i][i]; } /** * Metodo che restituisce il valore associato ai termini indicati * @param first Primo termine * @param second Secondo termine * @return Il valore associato a first e second */ protected double getValue(E first, E second){ int i,j; if(!(terms.contains(first) && terms.contains(second))) return -1; i = terms.indexOf(first); j = terms.indexOf(second); if (i < j) return values[j][i]; else return values[i][j]; } /** * Metodo che imposta un valore per un dato termine * @param term il valore di cui si vuole associare il valore * @param value il valore da associare a term */ protected void setValue(E term, double value){ int i; if(!terms.contains(term)){ terms.add(term); checkSize(); } i = terms.indexOf(term); values[i][i] = value; } /** * Metodo che associa un valore ad una coppia di termini * @param first il primo termine della coppia * @param second il secondo termine della coppia * @param value il valore da associare alla coppia */ protected void setValue(E first, E second, double value){ int i,j; if(!terms.contains(first)){ terms.add(first); checkSize(); } if(!terms.contains(second)){ terms.add(second); checkSize(); } i = terms.indexOf(first); j = terms.indexOf(second); if (i < j) values[j][i] = value; else values[i][j] = value; } /** * Metodo che incrementa il valore associato ad un termine * @param term termine il cui valore va incrementato * @param increment incremento */ protected void add(E term, double increment){ double value = 0; if(terms.contains(term)) value = getValue(term); value += increment; setValue(term, value); } /** * Metodo che incrementa il valore associato ad una coppia di termini * @param first primo termine * @param second secondo termine * @param increment incremento */ protected void add(E first, E second, double increment){ double value = 0; if(terms.contains(first) && terms.contains(second)) value = getValue(first, second); value += increment; setValue(first, second, value); } protected void normalizeBy(double value){ int i,j; for(i = 0; i < values.length; i++) for(j = 0; j < values[i].length; j++){ values[i][j] /= value; } } protected double values[][]; protected ArrayList<E> terms; private static final int minSize = 100; }