/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math4.userguide;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextArea;

import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.simple.RandomSource;

import org.apache.commons.geometry.euclidean.twod.Vector2D;
import org.apache.commons.math4.random.HaltonSequenceGenerator;
import org.apache.commons.math4.random.RandomVectorGenerator;
import org.apache.commons.math4.random.SobolSequenceGenerator;
import org.apache.commons.math4.random.UncorrelatedRandomVectorGenerator;
import org.apache.commons.math4.random.UniformRandomGenerator;
import org.apache.commons.math4.util.FastMath;
import org.apache.commons.math4.util.Pair;
import org.apache.commons.math4.userguide.ExampleUtils.ExampleFrame;

/**
 * Plots 2D samples drawn from various pseudo / quasi-random generators.
 */
public class LowDiscrepancyGeneratorComparison {

    public static List<Vector2D> makeCircle(int samples, final RandomVectorGenerator generator) {
        List<Vector2D> points = new ArrayList<>();
        for (double i = 0; i < samples; i++) {
            double[] vector = generator.nextVector();
            Vector2D point = Vector2D.of(vector);
            points.add(point);
        }

        // normalize points first
        points = normalize(points);
        
        // now test if the sample is within the unit circle
        List<Vector2D> circlePoints = new ArrayList<>();
        for (Vector2D p : points) {
            double criteria = FastMath.pow(p.getX(), 2) + FastMath.pow(p.getY(), 2);
            if (criteria < 1.0) {
                circlePoints.add(p);
            }
        }

        return circlePoints;
    }

    public static List<Vector2D> makeRandom(int samples, RandomVectorGenerator generator) {
        List<Vector2D> points = new ArrayList<>();
        for (double i = 0; i < samples; i++) {
            double[] vector = generator.nextVector();
            Vector2D point = Vector2D.of(vector);
            points.add(point);
        }
        
        return normalize(points);
    }

    public static List<Vector2D> normalize(final List<Vector2D> input) {
        // find the mininum and maximum x value in the dataset
        double minX = Double.MAX_VALUE;
        double maxX = Double.MIN_VALUE;
        for (Vector2D p : input) {
            minX = FastMath.min(minX, p.getX());
            maxX = FastMath.max(maxX, p.getX());
        }
        
        double minY, maxY;
        
        // use the minimum to detect if we either have input values in the range [0, 1] or [-sqrt(3), sqrt(3)]
        if (FastMath.abs(minX) < 0.1) {
            minX = minY = 0.0;
            maxX = maxY = 1.0;
        } else {
            minX = minY = -FastMath.sqrt(3);
            maxX = maxY = FastMath.sqrt(3);            
        }

        double rangeX = maxX - minX;
        double rangeY = maxY - minY;
        List<Vector2D> points = new ArrayList<>();
        for (Vector2D p : input) {
            double[] arr = p.toArray();
            // normalize to the range [-1, 1]
            arr[0] = (arr[0] - minX) / rangeX * 2 - 1;
            arr[1] = (arr[1] - minY) / rangeY * 2 - 1;
            points.add(Vector2D.of(arr));
        }
        return points;
    }
    
    @SuppressWarnings("serial")
    public static class Display extends ExampleFrame {
        
        public Display() {
            setTitle("Commons-Math: Pseudo/Quasi-random examples");
            setSize(800, 800);
            
            setLayout(new GridBagLayout());
            
            int[] datasets = new int[] { 256, 1000, 2500, 1000 };
            List<Pair<String, RandomVectorGenerator>> generators = new ArrayList<Pair<String, RandomVectorGenerator>>();

            generators.add(new Pair<String, RandomVectorGenerator>("Uncorrelated\nUniform(JDK)",
                                                                   new UncorrelatedRandomVectorGenerator(2, new UniformRandomGenerator(RandomSource.create(RandomSource.JDK)))));
            generators.add(new Pair<String, RandomVectorGenerator>("Independent\nRandom(MT)", new RandomVectorGenerator() {

                final UniformRandomProvider[] rngs = new UniformRandomProvider[] {
                    RandomSource.create(RandomSource.MT, 123456789),
                    RandomSource.create(RandomSource.MT, 987654321)
                };
                
                public double[] nextVector() {
                    final double[] vector = new double[2];
                    vector[0] = rngs[0].nextDouble();
                    vector[1] = rngs[1].nextDouble();
                    return vector;
                }
                
            }));            
            generators.add(new Pair<String, RandomVectorGenerator>("HaltonSequence", new HaltonSequenceGenerator(2)));            
            generators.add(new Pair<String, RandomVectorGenerator>("SobolSequence", new SobolSequenceGenerator(2)));            
            
            GridBagConstraints c = new GridBagConstraints();
            c.fill = GridBagConstraints.VERTICAL;
            c.gridx = 1;
            c.gridy = 0;
            c.insets = new Insets(2, 2, 2, 2);

            for (Pair<String, RandomVectorGenerator> pair : generators) {
                JTextArea text = new JTextArea(pair.getFirst());
                text.setEditable(false);
                text.setOpaque(false);
                add(text, c);
                c.gridx++;
            }
            int saveY = ++c.gridy;
            
            c.gridx = 0;
            for (int type = 0; type < 4; type++) {
                JLabel text = new JLabel("n=" + String.valueOf(datasets[type]));
                text.setOpaque(false);
                add(text, c);
                c.gridy++;
            }

            c.gridy = saveY;
            for (int type = 0; type < 4; type++) {
                c.gridx = 1;

                for (Pair<String, RandomVectorGenerator> pair : generators) {
                    List<Vector2D> points = null;
                    int samples = datasets[type];
                    switch (type) {
                        case 0:
                            points = makeRandom(samples, pair.getValue());
                            break;
                        case 1:
                            points = makeRandom(samples, pair.getValue());
                            break;
                        case 2:
                            points = makeRandom(samples, pair.getValue());
                            break;
                        case 3:
                            points = makeCircle(samples, pair.getValue());
                            break;
                    }
                    add(new Plot(points), c);
                    c.gridx++;
                }

                c.gridy++;
            }            
        }
    }

    @SuppressWarnings("serial")
    public static class Plot extends JComponent {

        private static double PAD = 10;

        private List<Vector2D> points;

        public Plot(final List<Vector2D> points) {
            this.points = points;
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);

            int w = getWidth();
            int h = getHeight();

            g2.clearRect(0, 0, w, h);
            
            g2.setPaint(Color.black);
            g2.drawRect(0, 0, w - 1, h - 1);
            
            for (Vector2D point : points) {
                Vector2D p = transform(point, w, h);
                double[] arr = p.toArray();
                g2.draw(new Rectangle2D.Double(arr[0] - 1, arr[1] - 1, 2, 2));
            }
        }        
        
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(140, 140);
        }

        private Vector2D transform(Vector2D point, int width, int height) {
            double[] arr = point.toArray();
            return Vector2D.of(PAD + (arr[0] + 1) / 2.0 * (width - 2 * PAD),
                               height - PAD - (arr[1] + 1) / 2.0 * (height - 2 * PAD));
        }
    }

    public static void main(String[] args) {
        ExampleUtils.showExampleFrame(new Display());
    }
}
