package org.nd4j.linalg.api.activation;


import org.nd4j.linalg.api.complex.IComplexNDArray;
import org.nd4j.linalg.api.complex.IComplexNumber;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.ops.ElementWiseOp;
import org.nd4j.linalg.util.ComplexUtil;

/**
 * Tanh with a hard range of -1 < tanh(x) < 1
 * @author Adam Gibson
 */
public class HardTanh extends BaseActivationFunction {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8484119406683594852L;


    /**
     * The class used for transformation
     *
     * @return the class used for transformation
     */
    @Override
    public Class<? extends ElementWiseOp> transformClazz() {
        return org.nd4j.linalg.ops.transforms.HardTanh.class;
    }

    /**
     * Name of the function
     *
     * @return the name of the function
     */
    @Override
    public String type() {
        return "hardtanh";
    }



	@Override
	public INDArray applyDerivative(INDArray input) {
		if(input instanceof IComplexNDArray) {
            for(int i = 0; i < input.length(); i++) {

                IComplexNumber val = (IComplexNumber) input.getScalar(i).element();
                if(val.realComponent().doubleValue() < -1 )
                     val.set(-1,val.imaginaryComponent().doubleValue());
                else if(val.realComponent().doubleValue() > 1)
                    val.set(1,val.imaginaryComponent().doubleValue());
                else
                    val = Nd4j.createDouble(1, 0).subi(ComplexUtil.pow(ComplexUtil.tanh(val), 2));

                input.put(i, Nd4j.scalar(val));
            }
        }
        else {
            for(int i = 0; i < input.length(); i++) {

                double val = (double) input.getScalar(i).element();
                if(val < -1 )
                    val = -1;
                else if(val > 1)
                    val = 1;
                else
                    val = 1 - Math.pow(Math.tanh(val),2);
                input.put(i, Nd4j.scalar(val));
            }
        }

		
		return input;
		
	}

}

@@ -441,24 +441,35 @@
  %7B%0A%0A
-%09/**%0A%09 * %0A%09 */%0A%09
+    /**%0A     *%0A     */%0A    
 priv
@@ -959,17 +959,20 @@
    %7D%0A%0A%0A%0A
-%09
+    
 @Overrid
@@ -973,17 +973,20 @@
 verride%0A
-%09
+    
 public I
@@ -1027,18 +1027,24 @@
 nput) %7B%0A
-%09%09
+        
 if(input
@@ -1070,24 +1070,138 @@
 xNDArray) %7B%0A
+            IComplexNDArray n2 = (IComplexNDArray) input;%0A            IComplexNDArray n2Linear = n2.linearView();%0A
             
@@ -1211,37 +1211,40 @@
 (int i = 0; i %3C 
-input
+n2Linear
 .length(); i++) 
@@ -1287,52 +1287,29 @@
 l = 
-(IComplexNumber) input.getScalar(i).element(
+n2Linear.getComplex(i
 );%0A 
@@ -1359,33 +1359,32 @@
 eValue() %3C -1 )%0A
- 
                 
@@ -1714,38 +1714,34 @@
     
-input.put(i, Nd4j.s
+n2Linear.putS
 calar(
+i, 
 val)
-)
 ;%0A  
@@ -1777,16 +1777,67 @@
  else %7B%0A
+            INDArray linear = input.linearView();%0A%0A
         
@@ -1859,21 +1859,22 @@
  0; i %3C 
+l
 in
-put
+ear
 .length(
@@ -1904,57 +1904,32 @@
     
-double
+float
  val = 
-(double) input.getScalar(i).elemen
+linear.ge
 t(
+i
 );%0A 
@@ -2099,16 +2099,24 @@
 al = 1 -
+ (float)
  Math.po
@@ -2156,38 +2156,31 @@
     
+l
 in
-put
+ear
 .put
-(i, Nd4j.s
+S
 calar(
+i,
 val)
-)
 ;%0A  
@@ -2206,13 +2206,17 @@
  %7D%0A%0A
-%09%09%0A%09%09
+%0A        
 retu
@@ -2229,12 +2229,13 @@
 ut;%0A
-%09%09%0A%09
+%0A    
 %7D%0A%0A%7D

fix linear indexing in hardtanh