package parody.optim;

import static org.junit.Assert.*;
import static parody.optim.Quadratic1DiffObjectiveFunction.VERTEX;

import java.util.Random;

import org.junit.Test;

import parody.util.Constants;

public class TestAdamOptimizer {

	@Test
	public void testOptimizer_quadratic() {
		Optimizer optim = new AdamOptimizer();
		optim.init(new NoisyQuadraticObjectiveFunction());
		double[] out = new double[VERTEX.length];
		boolean res = optim.optimize(out);
		assertTrue("The optimizer must converge", res);
		for(int i = 0; i < VERTEX.length; i++){
			assertEquals(VERTEX[i], out[i], Constants.VERY_COARSE_TOL);
		}
	}
	
	private class NoisyQuadraticObjectiveFunction extends Quadratic1DiffObjectiveFunction {
		
		public NoisyQuadraticObjectiveFunction(){
			random = new Random(1);
		}
		
		private Random random;		
		private double[] gradStds = new double[] { 0.05, 0.01 };
		
		@Override
		public void computeGradientAlways(double[] out){
			super.computeGradientAlways(out);
			for(int i = 0; i < VERTEX.length; i++){
				out[i] += random.nextGaussian()*gradStds[i];
			}
		}
		
	}

}
