protected double objectiveFunction(double[] x){
      double nll = 0; // -LogLikelihood
      int dim = m_NumPredictors+1; // Number of variables per class
	    
      for(int i=0; i<cls.length; i++){ // ith instance

	double[] exp = new double[m_NumClasses-1];
	int index;
	for(int offset=0; offset<m_NumClasses-1; offset++){ 
	  index = offset * dim;
	  for(int j=0; j<dim; j++)
	    exp[offset] += m_Data[i][j]*x[index + j];
	}
	double max = exp[Utils.maxIndex(exp)];
	double denom = Math.exp(-max);
	double num;
	if (cls[i] == m_NumClasses - 1) { // Class of this instance
	  num = -max;
	} else {
	  num = exp[cls[i]] - max;
	}
	for(int offset=0; offset<m_NumClasses-1; offset++){
	  denom += Math.exp(exp[offset] - max);
	}
		
	nll -= weights[i]*(num - Math.log(denom)); // Weighted NLL
      }
	    
      // Ridge: note that intercepts NOT included
      for(int offset=0; offset<m_NumClasses-1; offset++){
	for(int r=1; r<dim; r++)
	  nll += m_Ridge*x[offset*dim+r]*x[offset*dim+r];
      }
	    
      return nll;
    }