/*-
 *  * Copyright 2016 Skymind, Inc.
 *  *
 *  *    Licensed 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.datavec.image.transform;

import javafx.util.Pair;
import org.bytedeco.javacpp.opencv_core;
import org.datavec.image.data.ImageWritable;
import org.datavec.image.transform.BaseImageTransform;
import org.datavec.image.transform.ImageTransform;

import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * Allows creation of image transform pipelines, either sequentially or randomly.
 *
 * Pipelines are defined as a list of tuples, where each transform is assigned
 * a probability between 0.0-1.0 of being invoked. Pipeline can also be randomly
 * shuffled with each transform, further increasing the available dataset.
 *
 * @author Justin Long (@crockpotveggies)
 */
public class CombinedImageTransform extends BaseImageTransform<opencv_core.Mat> {

    protected List<Pair<ImageTransform, Double>> transforms;
    protected boolean shuffle;

    public CombinedImageTransform(List<Pair<ImageTransform, Double>> transforms) {
        this(new Random(1234), transforms, false);
    }

    public CombinedImageTransform(List<Pair<ImageTransform, Double>> transforms, boolean shuffle) {
        this(new Random(1234), transforms, shuffle);
    }

    public CombinedImageTransform(long seed, List<Pair<ImageTransform, Double>> transforms) {
        this(new Random(seed), transforms, false);
    }

    public CombinedImageTransform(long seed, List<Pair<ImageTransform, Double>> transforms, boolean shuffle) {
        this(new Random(seed), transforms, shuffle);
    }

    public CombinedImageTransform(Random random, List<Pair<ImageTransform, Double>> transforms, boolean shuffle) {
        super(random);
        this.transforms = transforms;
        this.shuffle = shuffle;
    }

    /**
     * Takes an image and executes a pipeline of combined transforms.
     *
     * @param image  to transform, null == end of stream
     * @param random object to use (or null for deterministic)
     * @return transformed image
     */
    @Override
    public ImageWritable transform(ImageWritable image, Random random) {
        if(shuffle) Collections.shuffle(transforms);

        // execute each item in the pipeline
        ImageWritable output = image;
        for(Pair<ImageTransform, Double> tuple : transforms) {
            if(random.nextDouble() < tuple.getValue()) { // probability of execution
                output = tuple.getKey().transform(image);
            }
        }

        return output;
    }
}

@@ -992,16 +992,723 @@
 andom;%0A%0A
+/**%0A * Allows creation of image transform pipelines, either sequentially or randomly.%0A *%0A * Pipelines are defined as a list of tuples, where each transform is assigned%0A * a probability between 0.0-1.0 of being invoked. Pipeline can also be randomly%0A * shuffled with each transform, further increasing the available dataset.%0A *%0A * @author Justin Long (@crockpotveggies)%0A */%0Aimport javafx.util.Pair;%0Aimport org.bytedeco.javacpp.opencv_core;%0Aimport org.datavec.image.data.ImageWritable;%0Aimport org.datavec.image.transform.BaseImageTransform;%0Aimport org.datavec.image.transform.ImageTransform;%0Aimport org.nd4j.linalg.factory.Nd4j;%0A%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.Random;%0A%0A
 /**%0A * A
@@ -2246,16 +2246,66 @@
 shuffle;
+%0A    protected org.nd4j.linalg.api.rng.Random rng;
 %0A%0A    pu
@@ -2394,32 +2394,20 @@
    this(
-new Random(
 1234
-)
 , transf
@@ -2544,24 +2544,12 @@
 his(
-new Random(
 1234
-)
 , tr
@@ -2682,32 +2682,20 @@
    this(
-new Random(
 seed
-)
 , transf
@@ -2844,23 +2844,17 @@
 is(n
-ew Random(
+ull, 
 seed
-)
 , tr
@@ -2928,16 +2928,27 @@
  random,
+ long seed,
  List%3CPa
@@ -3024,16 +3024,72 @@
 per(
-random);
+null); // for perf reasons we ignore java Random, create our own
 %0A   
@@ -3151,24 +3151,88 @@
  = shuffle;%0A
+        this.rng = Nd4j.getRandom();%0A        rng.setSeed(seed);%0A
     %7D%0A%0A    /
@@ -3775,21 +3775,18 @@
     if(r
-andom
+ng
 .nextDou

Use Nd4j.getRandom().