codice:
Matrix Y = new Matrix(trainingclasse.length * (K-1),1);
//k rappresenta la y_i
for(int i=1;i<=K-1;i++){
//creo le sotto-matrici
Matrix y_k = new Matrix (trainingclasse.length,1);
for(int g=0;g<trainingclasse.length;g++){
if(trainingclasse[g][0]== i){
y_k.set(g, 0, 1);
}else{
y_k.set(g, 0, 0);
}
}
//Inserisco le sotto-matrici y_k nella matrice Y
Y.setMatrix((i-1) * trainingclasse.length, (i-1) * trainingclasse.length + (trainingclasse.length-1), 0, 0, y_k);
}
//stampa_matrice(Y);
/**
* Matrice Xtilde con N * (K-1) righe, e (p+1) * (K-1) colonne
*/
//Creo le sottomatrici X
Matrix X = new Matrix(training.length,training[0].length+1);
for(int righe=0;righe<training.length;righe++){
for(int colonne = 0; colonne < training[0].length; colonne++){
//il + 1 nell'indice delle colonne serve a shiftare i valori
//da inserire di una posizione
X.set(righe, colonne + 1, training[righe][colonne]);
}
X.set(righe, 0, 1.0d);
}
//(p+1) p è il numero di x che compongono il training, il +1 + il coefficiente di b0
//nel nostro caso la x è soltanto una
Matrix Xtilde = new Matrix (training.length * (K-1),(X.getColumnDimension()) * (K-1));
int num_righe_X,num_colonne_X;
num_righe_X=X.getRowDimension();
num_colonne_X=X.getColumnDimension();
for(int i=0; i < K-1; i++){
Xtilde.setMatrix(i * num_righe_X, i * num_righe_X + (num_righe_X-1), i * num_colonne_X, i * num_colonne_X + (num_colonne_X-1), X);
}
double distance;
int numIters=0;
//numero dei parametri
bt=new Matrix((K-1)*(training[0].length + 1),1);//matrice dei coefficienti
do{
/**
* Vettore P di dimensione N * (K-1),
* ottenuto concatenando k-1 vettori
*/
Matrix P = new Matrix(training.length * (K-1),1);
//Ciclo for per calcolare il denominatore
int indice_bt=0;
double esponente = 0;
for(int j=1;j<= (K - 1);j++){
Matrix p_k = new Matrix (training.length,1);
for(int i=0;i<training.length;i++){
//ciclo per calcolare il numeratore
for(int p=0;p<X.getColumnDimension();p++){
esponente = esponente + (bt.get(indice_bt + p,0)*X.get(i, p));
}
//numeratore
double numeratore = Math.exp(esponente);
//denominatore
int ind_bt=0;
double denominatore=0;
do{
for(int p=0;p<X.getColumnDimension();p++){
esponente = esponente + (bt.get(ind_bt + p,0)*X.get(i, p));
}
denominatore = denominatore + Math.exp(esponente);
ind_bt=ind_bt+X.getColumnDimension();
}while(ind_bt<bt.getRowDimension());
denominatore = 1 + denominatore;
double valore = numeratore/denominatore;
p_k.set(i, 0, valore);
}
P.setMatrix((j-1) * trainingclasse.length, (j-1) * trainingclasse.length + (trainingclasse.length-1), 0, 0, p_k);
indice_bt=indice_bt+X.getColumnDimension();
}
//stampa_matrice(P);
/**
* Matrice quadrata W di N * (K-1) righe e N * (K-1) colonne
*/
Matrix W = new Matrix((training.length * (K-1)),(training.length * (K-1)));
//costruisco la matrice W
for(int riga=0;riga<K-1;riga++){
for(int colonna=0;colonna<K-1;colonna++){
if(riga==colonna){ //if(k=m)
Matrix k_uguale_m = new Matrix (training.length ,training.length );
for(int i=0;i<training.length;i++){
//p_k(x_i;b_old)(1-p_k(x_i;b_old))
k_uguale_m.set(i, i, (P.getMatrix(riga * training.length, riga * training.length + (training.length-1), 0, 0).get(i, 0)) * (1-P.getMatrix(riga * training.length, riga * training.length + (training.length-1), 0, 0).get(i, 0)));
}
W.setMatrix(riga * training.length, riga * training.length + (training.length-1), colonna * training.length, colonna * training.length + (training.length-1), k_uguale_m);
}else{ //if(k!=m)
Matrix k_diverso_m = new Matrix (training.length ,training.length );
for(int i=0;i<training.length;i++){
//p_k(x_i;b_old) p_m(x_i;b_old)
k_diverso_m.set(i, i, (P.getMatrix(riga * training.length, riga * training.length + (training.length-1), 0, 0).get(i, 0)) * (P.getMatrix(colonna * training.length, colonna * training.length + (training.length-1), 0, 0).get(i, 0)));
}
W.setMatrix(riga * training.length, riga * training.length + (training.length-1), colonna * training.length, colonna * training.length + (training.length-1), k_diverso_m);
}
}
}
Matrix bprime= new Matrix((K-1)*(X.getColumnDimension()),1);
//(Xtilde.traspose * W * Xtilde).inverse
Matrix temp = Xtilde.transpose();
temp = temp.times(W);
temp = temp.times(Xtilde);
if (temp.det()==0){
break;}
temp = temp.inverse();
// temp * Xtilde.traspose
temp = temp.times(Xtilde.transpose());
// temp * (y-p)
temp = temp.times(Y.minus(P));
bprime= bt.plus(temp);
double xN=bt.normF();
double x1N=bprime.normF();
if (xN>x1N)
{
distance=Math.abs(bt.minus(bprime).normF()/x1N);
}
else
{
distance=Math.abs(bt.minus(bprime).normF()/xN);
}
numIters++;
bt=bprime;
} while (distance>threshold && numIters<maxIters);