Repository: deeplearning4j/deeplearning4j
Issue: SpecifiedIndex and put(): changes not reflected (1.0.0M1)

#### Issue Description

Please describe your issue, along with:
- expected behavior
When setting a value using `INDArray.put(SpecifiedIndex, element)`, the changes should be reflected in the original array as well as the returned array. 
- encountered behavior
Changes are not reflected in the array (and hence neither in the returned array).

#### Version Information
1.0.0-M1.1
Please indicate relevant versions, including, if relevant:

* Deeplearning4j version
nd4j-native 1.0.0-M1.1
* platform information (OS, etc)
Linux
* CUDA version, if used
None
* NVIDIA driver version, if in use
#N/A

#### Contributing
Happy to fix it - let me know what approaches have been attempted/considered previously.

In BaseNDArray:

```
@Override 
public INDArray put(INDArrayIndex[] indices, Number element) { 
    Nd4j.getCompressor().autoDecompress(this); 
    INDArray get = get(indices); 
    for (int i = 0; i < get.length(); i++) get.putScalar(i, element.doubleValue()); 
    return this; 
}
```
Here, the get is not a view but a detached copy, and therefore the changes done in `get.putScalar` is not propagated to the original array.

Using
```
INDArray original = ...; 
original.put(INDArrayIndex[] indices, INDArray element)
```
does solve the issue by copying item-by-item from the element array to the original array, but requires element to be of the same size as the original array - which could waste RAM. 

Test case (Kotlin):
```
val a1 = Nd4j.arange(12.0).reshape(2L, 3, 2).castTo(DataType.INT16); 
println("Original");
println(a1); 
val indices = arrayOf(all(), indices(0, 2), point(1));
a1.put(indices, Nd4j.onesLike(a1).muli(-1).castTo(DataType.INT16)); 
println("a1.put(arrayOf(all(), indices(0,2), point(1)), Nd4j.onesLike(a1).muli(-1).castTo(DataType.INT16))"); 
println(a1);
```

Is there a better solution?

First reported in https://github.com/deeplearning4j/nd4j/issues/611

Changed files:
nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/api/ndarray/BaseNDArray.java
nd4j/nd4j-backends/nd4j-tests/src/test/java/org/nd4j/linalg/api/indexing/IndexingTestsC.java

diff --git a/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/api/ndarray/BaseNDArray.java b/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/api/ndarray/BaseNDArray.java
index 9e057e5814..729d24fc5f 100644
--- a/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/api/ndarray/BaseNDArray.java
+++ b/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/api/ndarray/BaseNDArray.java
@@ -2182,14 +2182,14 @@ public abstract class BaseNDArray implements INDArray, Iterable {
 
             INDArrayIndex[] destinationIndices = indices.clone();  //Shallow clone
             INDArrayIndex[] sourceIndices = indices.clone();
-            for( int i=0; i<indices.length; i++){
+            for( int i = 0; i < indices.length; i++) {
                 INDArrayIndex idx = indices[i];
-                if(idx instanceof SpecifiedIndex){
+                if(idx instanceof SpecifiedIndex) {
                     numSpecified++;
                     long[] idxs = ((SpecifiedIndex) idx).getIndexes();
                     specifiedIdxs.add(idxs);
                     specifiedIdxDims.add(i);
-                } else if(idx instanceof PointIndex){
+                } else if(idx instanceof PointIndex) {
                     //Example: [2,3,3].put(point(1), ..., [1,x,y]) -> can't use point(1) on [1,x,y]
                     sourceIndices[i] = NDArrayIndex.point(0);
                 }
@@ -2202,9 +2202,9 @@ public abstract class BaseNDArray implements INDArray, Iterable {
             }
 
             NdIndexIterator iter = new NdIndexIterator(counts);
-            while(iter.hasNext()){
+            while(iter.hasNext()) {
                 long[] iterationIdxs = iter.next();
-                for(int i=0; i<iterationIdxs.length; i++ ){
+                for(int i = 0; i < iterationIdxs.length; i++) {
                     long[] indicesForDim = specifiedIdxs.get(i);
                     destinationIndices[dims[i]] = NDArrayIndex.point(indicesForDim[(int)iterationIdxs[i]]);
                     sourceIndices[dims[i]] = NDArrayIndex.point(iterationIdxs[i]);
@@ -2212,7 +2212,7 @@ public abstract class BaseNDArray implements INDArray, Iterable {
 
                 INDArray sourceView = element.get(sourceIndices);
                 INDArray destinationView = this.get(destinationIndices);
-                destinationView.assign(sourceView);
+                return destinationView.assign(sourceView);
             }
         }
         return this;
diff --git a/nd4j/nd4j-backends/nd4j-tests/src/test/java/org/nd4j/linalg/api/indexing/IndexingTestsC.java b/nd4j/nd4j-backends/nd4j-tests/src/test/java/org/nd4j/linalg/api/indexing/IndexingTestsC.java
index 08ee5b9cd0..02b15daf6d 100644
--- a/nd4j/nd4j-backends/nd4j-tests/src/test/java/org/nd4j/linalg/api/indexing/IndexingTestsC.java
+++ b/nd4j/nd4j-backends/nd4j-tests/src/test/java/org/nd4j/linalg/api/indexing/IndexingTestsC.java
@@ -51,6 +51,15 @@ public class IndexingTestsC extends BaseNd4jTestWithBackends {
 
 
 
+    @ParameterizedTest
+    @MethodSource("org.nd4j.linalg.BaseNd4jTestWithBackends#configs")
+    public void testSpecifiedIndexPut(Nd4jBackend backend) {
+        INDArray arr = Nd4j.arange(12.0).reshape(2,3,2);
+        INDArrayIndex[] indices = {NDArrayIndex.all(),NDArrayIndex.indices(0,2),NDArrayIndex.point(1)};
+        INDArray put  = arr.put(indices,Nd4j.onesLike(arr.muli(-1)));
+        assertNotEquals(arr,put);
+    }
+
 
     @ParameterizedTest
     @MethodSource("org.nd4j.linalg.BaseNd4jTestWithBackends#configs")