Repository: Theano/Theano

Issue:
scan bug?
```
def lp(x, x2):
    return x
x = T.vector('x')
res, upd = theano.scan(lp, sequences = dict(input = x, taps = [-2, -1]))
f = theano.function([x], res, updates = upd)
print f([1, 2, 3, 4, 5])
```

And the result is [ 2.  3.  4.]
Shouldn't it be [1, 2, 3] ?



Discussion:
I can reproduce this with the master branch and I obtain the exact same results. I agree that I would expect the result to be [1,2,3] and I didn't find anything in the scan documentation to explain why it shouldn't be the case so I'll start to investigate in the code to better understand what's happening. 

Thanks a lot for reporting this issue.


Resolving patch:
diff --git a/theano/scan_module/scan.py b/theano/scan_module/scan.py
--- a/theano/scan_module/scan.py
+++ b/theano/scan_module/scan.py
@@ -500,20 +500,18 @@ def wrap_into_list(x):
                     nw_slice.name = nw_name
 
                 # We cut the sequence such that seq[i] to correspond to
-                # seq[i-k]
-                if maxtap < 0:
-                    offset = abs(maxtap)
+                # seq[i-k]. For the purposes of cutting the sequences, we
+                # need to pretend tap 0 is used to avoid cutting the sequences
+                # too long if the taps are all lower or all higher than 0.
+                maxtap_proxy = max(maxtap, 0)
+                mintap_proxy = min(mintap, 0)
+                start = (k - mintap_proxy)
+                if k == maxtap_proxy:
+                    nw_seq = seq['input'][start:]
                 else:
-                    offset = 0
-                if maxtap == mintap and maxtap != 0:
-                    if maxtap < 0:
-                        nw_seq = seq['input'][:maxtap]
-                    else:
-                        nw_seq = seq['input'][maxtap:]
-                elif maxtap - k != 0:
-                    nw_seq = seq['input'][offset + k - mintap: -(maxtap - k)]
-                else:
-                    nw_seq = seq['input'][offset + k - mintap:]
+                    end = -(maxtap_proxy - k)
+                    nw_seq = seq['input'][start:end]
+
                 if go_backwards:
                     nw_seq = nw_seq[::-1]
 


Test patch:
diff --git a/theano/scan_module/tests/test_scan.py b/theano/scan_module/tests/test_scan.py
--- a/theano/scan_module/tests/test_scan.py
+++ b/theano/scan_module/tests/test_scan.py
@@ -623,6 +623,20 @@ def test_using_taps_sequence(self):
         rval = theano.function([x], y, updates=updates)(inp)
         assert numpy.all(rval == inp[:-1])
 
+    def test_using_negative_taps_sequence(self):
+        # This test refers to a bug reported on github on May 22 2015 by
+        # user june-qijun
+        def lp(x, x2):
+            return x
+        x = tensor.fvector('x')
+        res, upd = theano.scan(lp,
+                               sequences=dict(input=x, taps=[-2, -1]))
+        f = theano.function([x], res, updates = upd)
+
+        output =  f([1, 2, 3, 4, 5])
+        expected_output = numpy.array([1, 2, 3], dtype="float32")
+        utt.assert_allclose(output, expected_output)
+
     def test_connection_pattern(self):
         """Test connection_pattern() in the presence of recurrent outputs
         with multiple taps.