1"""
2This module provides syntax shortcut for the Scan Op.
3
4See scan.py for details on scan.
5
6"""
7from __future__ import absolute_import, print_function, division
8__docformat__ = 'restructedtext en'
9__authors__ = ("Razvan Pascanu "
10               "Frederic Bastien "
11               "James Bergstra "
12               "Pascal Lamblin ")
13__copyright__ = "(c) 2010, Universite de Montreal"
14__contact__ = "Razvan Pascanu <r.pascanu@gmail>"
15
16
17import logging
18
19from theano.scan_module import scan
20
21# Logging function for sending warning or info
22_logger = logging.getLogger('theano.scan_module.scan_views')
23
24
25################ Declaration of Views for Scan #######################
26
27
28# The ``map`` view of Scan Op.
29
30
31def map(fn,
32        sequences,
33        non_sequences=None,
34        truncate_gradient=-1,
35        go_backwards=False,
36        mode=None,
37        name=None):
38    """
39    Similar behaviour as python's map.
40
41    Parameters
42    ----------
43    fn
44        The function that ``map`` applies at each iteration step
45        (see ``scan`` for more info).
46    sequences
47        List of sequences over which ``map`` iterates
48        (see ``scan`` for more info).
49    non_sequences
50        List of arguments passed to ``fn``. ``map`` will not iterate over
51        these arguments (see ``scan`` for more info).
52    truncate_gradient
53        See ``scan``.
54    go_backwards : bool
55        Decides the direction of iteration. True means that sequences are parsed
56        from the end towards the beginning, while False is the other way around.
57    mode
58        See ``scan``.
59    name
60        See ``scan``.
61
62    """
63    return scan(fn=fn,
64                     sequences=sequences,
65                     outputs_info=[],
66                     non_sequences=non_sequences,
67                     truncate_gradient=truncate_gradient,
68                     go_backwards=go_backwards,
69                     mode=mode,
70                     name=name)
71
72
73# The ``reduce`` view of Scan Op.
74def reduce(fn,
75           sequences,
76           outputs_info,
77           non_sequences=None,
78           go_backwards=False,
79           mode=None,
80           name=None):
81    """
82    Similar behaviour as python's reduce.
83
84    Parameters
85    ----------
86    fn
87        The function that ``reduce`` applies at each iteration step
88        (see ``scan``  for more info).
89    sequences
90        List of sequences over which ``reduce`` iterates
91        (see ``scan`` for more info).
92    outputs_info
93        List of dictionaries describing the outputs of
94        reduce (see ``scan`` for more info).
95    non_sequences
96        List of arguments passed to ``fn``. ``reduce`` will
97                          not iterate over these arguments (see ``scan`` for
98                          more info).
99    go_backwards : bool
100        Decides the direction of iteration. True means that sequences are parsed
101        from the end towards the beginning, while False is the other way around.
102    mode
103        See ``scan``.
104    name
105        See ``scan``.
106
107    """
108    rval = scan(fn=fn,
109                     sequences=sequences,
110                     outputs_info=outputs_info,
111                     non_sequences=non_sequences,
112                     go_backwards=go_backwards,
113                     truncate_gradient=-1,
114                     mode=mode,
115                     name=name)
116    if isinstance(rval[0], (list, tuple)):
117        return [x[-1] for x in rval[0]], rval[1]
118    else:
119        return rval[0][-1], rval[1]
120
121
122# The ``foldl`` view of Scan Op.
123def foldl(fn,
124          sequences,
125          outputs_info,
126          non_sequences=None,
127          mode=None,
128          name=None):
129    """
130    Similar behaviour as haskell's foldl.
131
132    Parameters
133    ----------
134    fn
135        The function that ``foldl`` applies at each iteration step
136        (see ``scan`` for more info).
137    sequences
138        List of sequences over which ``foldl`` iterates
139        (see ``scan`` for more info).
140    outputs_info
141        List of dictionaries describing the outputs of reduce
142        (see ``scan`` for more info).
143    non_sequences
144        List of arguments passed to `fn`. ``foldl`` will not iterate over
145        these arguments (see ``scan`` for more info).
146    mode
147        See ``scan``.
148    name
149        See ``scan``.
150
151    """
152    return reduce(fn=fn,
153                  sequences=sequences,
154                  outputs_info=outputs_info,
155                  non_sequences=non_sequences,
156                  go_backwards=False,
157                  mode=mode,
158                  name=name)
159
160
161# The ``foldl`` view of Scan Op.
162def foldr(fn,
163          sequences,
164          outputs_info,
165          non_sequences=None,
166          mode=None,
167          name=None):
168    """
169    Similar behaviour as haskell' foldr.
170
171    Parameters
172    ----------
173    fn
174        The function that ``foldr`` applies at each iteration step
175        (see ``scan`` for more info).
176    sequences
177        List of sequences over which ``foldr`` iterates
178        (see ``scan`` for more info).
179    outputs_info
180        List of dictionaries describing the outputs of reduce
181        (see ``scan`` for more info).
182    non_sequences
183        List of arguments passed to `fn`. ``foldr`` will not iterate over these
184        arguments (see ``scan`` for more info).
185    mode
186        See ``scan``.
187    name
188        See ``scan``.
189
190    """
191    return reduce(fn=fn,
192                  sequences=sequences,
193                  outputs_info=outputs_info,
194                  non_sequences=non_sequences,
195                  go_backwards=True,
196                  mode=mode,
197                  name=name)
198