# Logistic Regression 
import numpy as np; 

def f_rlog(w,Xh,y,mu): 
  # w: weights (N+1)x1 vector
  # P: number of samples
  # Xh: data (N+1)xP matrix (last row is one)
  # y: labels Px1 vector
  # mu: regularization parameter

  P = Xh.shape[1]; 

  val1 = (1.0/P)*np.sum(np.log(1 + np.exp(-np.matmul(w.T,Xh)*y)));
  val2 = (mu/2.0)*np.sum(w*w);
  val3 = val1 + val2; 

  return val3; 

def test_01():
  
  N = 2; P = 3; mu = 0.1; 
  Xh = np.zeros((N+1,P));
  Xh[N,:] = 1.0; 
  Xh[0:N,0:P] = np.array([[1,2,3],[4,5,6]]);
  print("Xh = \n" + str(Xh));

  y = np.zeros((P,1));
  y[0:P,0] = np.array([-1,1,1]); 
  print("y = \n" + str(y));

  w = np.zeros((N+1,1));
  w[0:N+1,0] = np.array([0.25,0.5,0.75]); 
  print("w = \n" + str(w));

  print(""); 
  f_rlog_val = f_rlog(w,Xh,y,mu);
  print("f_rlog = \n" + str(f_rlog_val));
  print(""); 



# run tests
if __name__ == "__main__":
  print("="*80);
  print("Tests logistic regression loss function.");
  print("-"*80); 

  test_01(); 

  print("-"*80);
  print("Done.");
  print("="*80);


