code: package ch.uzh.ifi.ce.cabne.BR;
  
  import java.util.List;
  import java.util.TreeMap;
  
  import ch.uzh.ifi.ce.cabne.algorithm.BNESolverContext;
  import ch.uzh.ifi.ce.cabne.helpers.UtilityHelpers;
  import ch.uzh.ifi.ce.cabne.pointwiseBR.Optimizer;
  import ch.uzh.ifi.ce.cabne.strategy.Strategy;
  import ch.uzh.ifi.ce.cabne.strategy.UnivariatePWLStrategy;
  
  public class PWLBRCalculator implements BRCalculator<Double, Double> {
  	BNESolverContext<Double, Double> context;
  	
  
  	public PWLBRCalculator(BNESolverContext<Double, Double> context) {
  		this.context = context;
  	}
  
  
  	public Result<Double, Double> computeBR(int i, List<Strategy<Double, Double>> s) {
  		int nPoints = Integer.parseInt(context.config.get("gridsize"));
  		
  		TreeMap<Double, Double> pointwiseBRs = new TreeMap<>();
  		double epsilonAbs = 0.0;
  		double epsilonRel = 0.0;
  
  		double maxValue = s.get(i).getMaxValue();
  		
  		for (int j = 0; j<=nPoints; j++) {
  			double v = maxValue * ((double) j) / (nPoints);
  			Double oldbid = s.get(i).getBid(v);
  			Optimizer.Result<Double> result = context.optimizer.findBR(i, v, oldbid, s);
  			epsilonAbs = Math.max(epsilonAbs, UtilityHelpers.absoluteLoss(result.oldutility, result.utility));
  			epsilonRel = Math.max(epsilonRel, UtilityHelpers.relativeLoss(result.oldutility, result.utility));
  						
  			Double newbid = context.updateRule.update(v, oldbid, result.bid, result.oldutility, result.utility);
  			pointwiseBRs.put(v,  newbid);			
  		}
  		
  		return new Result<Double, Double>(new UnivariatePWLStrategy(pointwiseBRs), epsilonAbs, epsilonRel);
  	}
  
  }
  