# ----------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2013-2016, Numenta, Inc.  Unless you have an agreement
# with Numenta, Inc., for a separate license for this software code, the
# following terms and conditions apply:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero Public License for more details.
#
# You should have received a copy of the GNU Affero Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# http://numenta.org/licenses/
# ----------------------------------------------------------------------


# The build prepends this module verbatim to each nupic.bindings python
# extension proxy module to load pycapnp's extension shared library in global
# scope before loading our own extension DLL (that doesn't contain capnproto
# code) so that our capnproto references will resolve against capnproto included
# in pycapnp. This ensures that the methods of the same capnproto build that
# creates the capnproto objects in nupic will be used on those objects from both
# nupic and nupic.bindings shared objects.


def _nupic_bindings_load_capnp_shared_object():
  import platform
  # Windows nupic.bindings extensions include CAPNP_LITE capnproto subset and
  # must not depend on pycapnp
  if platform.system() != "Windows":
    import ctypes, imp, os
    capnpPackageDir = imp.find_module('capnp')[1]
    capnpDLLPath=os.path.join(capnpPackageDir, 'lib', 'capnp.so')
    ctypes.CDLL(capnpDLLPath, ctypes.RTLD_GLOBAL)

_nupic_bindings_load_capnp_shared_object()

del _nupic_bindings_load_capnp_shared_object
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.





from sys import version_info
if version_info >= (2,6,0):
    def swig_import_helper():
        from os.path import dirname
        import imp
        fp = None
        try:
            fp, pathname, description = imp.find_module('_experimental', [dirname(__file__)])
        except ImportError:
            import _experimental
            return _experimental
        if fp is not None:
            try:
                _mod = imp.load_module('_experimental', fp, pathname, description)
            finally:
                fp.close()
            return _mod
    _experimental = swig_import_helper()
    del swig_import_helper
else:
    import _experimental
del version_info
try:
    _swig_property = property
except NameError:
    pass # Python < 2.2 doesn't have 'property'.
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
    if (name == "thisown"): return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name,None)
    if method: return method(self,value)
    if (not static):
        self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)

def _swig_setattr(self,class_type,name,value):
    return _swig_setattr_nondynamic(self,class_type,name,value,0)

def _swig_getattr(self,class_type,name):
    if (name == "thisown"): return self.this.own()
    method = class_type.__swig_getmethods__.get(name,None)
    if method: return method(self)
    raise AttributeError(name)

def _swig_repr(self):
    try: strthis = "proxy of " + self.this.__repr__()
    except: strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

try:
    _object = object
    _newclass = 1
except AttributeError:
    class _object : pass
    _newclass = 0


def _swig_setattr_nondynamic_method(set):
    def set_attr(self,name,value):
        if (name == "thisown"): return self.this.own(value)
        if hasattr(self,name) or (name == "this"):
            set(self,name,value)
        else:
            raise AttributeError("You cannot add attributes to %s" % self)
    return set_attr


try:
    import weakref
    weakref_proxy = weakref.proxy
except:
    weakref_proxy = lambda x: x


import os

_EXPERIMENTAL = _experimental

uintDType = "uint32"

import numpy

# Without this, Python scripts that haven't imported nupic.bindings.algorithms
# will get a SwigPyObject rather than a SWIG-wrapped Connections instance
# when accessing the ExtendedTemporalMemory's connections.
import nupic.bindings.algorithms

class ExtendedTemporalMemory(object):
    """Proxy of C++ nupic::experimental::extended_temporal_memory::ExtendedTemporalMemory class"""
    thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr
    def __init__(self, *args): 
        """
        __init__(self) -> ExtendedTemporalMemory
        __init__(self, columnDimensions, cellsPerColumn=32, activationThreshold=13, initialPermanence=0.21, 
            connectedPermanence=0.50, minThreshold=10, maxNewSynapseCount=20, permanenceIncrement=0.10, 
            permanenceDecrement=0.10, predictedSegmentDecrement=0.0, 
            formInternalBasalConnections=True, learnOnOneCell=False, seed=42, maxSegmentsPerCell=255, 
            maxSynapsesPerSegment=255) -> ExtendedTemporalMemory
        """
        this = _experimental.new_ExtendedTemporalMemory(*args)
        try: self.this.append(this)
        except: self.this = this
    def initialize(self, *args, **kwargs):
        """
        initialize(self, columnDimensions={ 2048 }, cellsPerColumn=32, activationThreshold=13, initialPermanence=0.21, 
            connectedPermanence=0.50, minThreshold=10, maxNewSynapseCount=20, 
            permanenceIncrement=0.10, permanenceDecrement=0.10, predictedSegmentDecrement=0.0, 
            formInternalBasalConnections=True, learnOnOneCell=False, seed=42, 
            maxSegmentsPerCell=255, maxSynapsesPerSegment=255)
        """
        return _experimental.ExtendedTemporalMemory_initialize(self, *args, **kwargs)

    __swig_destroy__ = _experimental.delete_ExtendedTemporalMemory
    def version(self):
        """version(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_version(self)

    def seed_(self, *args, **kwargs):
        """seed_(self, seed)"""
        return _experimental.ExtendedTemporalMemory_seed_(self, *args, **kwargs)

    def reset(self):
        """reset(self)"""
        return _experimental.ExtendedTemporalMemory_reset(self)

    def activateCells(self, *args, **kwargs):
        """
        activateCells(self, activeColumnsSize, activeColumns, prevActiveExternalCellsBasalSize, prevActiveExternalCellsBasal, 
            activeExternalCellsApicalSize, activeExternalCellsApical, 
            learn)
        """
        return _experimental.ExtendedTemporalMemory_activateCells(self, *args, **kwargs)

    def activateDendrites(self, *args, **kwargs):
        """
        activateDendrites(self, activeExternalCellsBasalSize, activeExternalCellsBasal, activeExternalCellsApicalSize, 
            activeExternalCellsApical, learn=True)
        """
        return _experimental.ExtendedTemporalMemory_activateDendrites(self, *args, **kwargs)

    def compute(self, *args, **kwargs):
        """
        compute(self, activeColumnsSize, activeColumns, prevActiveExternalCellsBasalSize=0, prevActiveExternalCellsBasal=0, 
            activeExternalCellsBasalSize=0, activeExternalCellsBasal=0, 
            prevActiveExternalCellsApicalSize=0, prevActiveExternalCellsApical=0, 
            activeExternalCellsApicalSize=0, activeExternalCellsApical=0, learn=True)
        """
        return _experimental.ExtendedTemporalMemory_compute(self, *args, **kwargs)

    def numberOfCells(self):
        """numberOfCells(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_numberOfCells(self)

    def getActiveBasalSegments(self):
        """getActiveBasalSegments(self) -> ConnectionsSegmentVector"""
        return _experimental.ExtendedTemporalMemory_getActiveBasalSegments(self)

    def getMatchingBasalSegments(self):
        """getMatchingBasalSegments(self) -> ConnectionsSegmentVector"""
        return _experimental.ExtendedTemporalMemory_getMatchingBasalSegments(self)

    def getActiveApicalSegments(self):
        """getActiveApicalSegments(self) -> ConnectionsSegmentVector"""
        return _experimental.ExtendedTemporalMemory_getActiveApicalSegments(self)

    def getMatchingApicalSegments(self):
        """getMatchingApicalSegments(self) -> ConnectionsSegmentVector"""
        return _experimental.ExtendedTemporalMemory_getMatchingApicalSegments(self)

    def getColumnDimensions(self):
        """getColumnDimensions(self) -> VectorOfUInt32"""
        return _experimental.ExtendedTemporalMemory_getColumnDimensions(self)

    def numberOfColumns(self):
        """numberOfColumns(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_numberOfColumns(self)

    def getCellsPerColumn(self):
        """getCellsPerColumn(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_getCellsPerColumn(self)

    def getActivationThreshold(self):
        """getActivationThreshold(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_getActivationThreshold(self)

    def setActivationThreshold(self, *args, **kwargs):
        """setActivationThreshold(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setActivationThreshold(self, *args, **kwargs)

    def getInitialPermanence(self):
        """getInitialPermanence(self) -> nupic::algorithms::connections::Permanence"""
        return _experimental.ExtendedTemporalMemory_getInitialPermanence(self)

    def setInitialPermanence(self, *args, **kwargs):
        """setInitialPermanence(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setInitialPermanence(self, *args, **kwargs)

    def getConnectedPermanence(self):
        """getConnectedPermanence(self) -> nupic::algorithms::connections::Permanence"""
        return _experimental.ExtendedTemporalMemory_getConnectedPermanence(self)

    def setConnectedPermanence(self, *args, **kwargs):
        """setConnectedPermanence(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setConnectedPermanence(self, *args, **kwargs)

    def getMinThreshold(self):
        """getMinThreshold(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_getMinThreshold(self)

    def setMinThreshold(self, *args, **kwargs):
        """setMinThreshold(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setMinThreshold(self, *args, **kwargs)

    def getMaxNewSynapseCount(self):
        """getMaxNewSynapseCount(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_getMaxNewSynapseCount(self)

    def setMaxNewSynapseCount(self, *args, **kwargs):
        """setMaxNewSynapseCount(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setMaxNewSynapseCount(self, *args, **kwargs)

    def getFormInternalBasalConnections(self):
        """getFormInternalBasalConnections(self) -> bool"""
        return _experimental.ExtendedTemporalMemory_getFormInternalBasalConnections(self)

    def setFormInternalBasalConnections(self, *args, **kwargs):
        """setFormInternalBasalConnections(self, formInternalBasalConnections)"""
        return _experimental.ExtendedTemporalMemory_setFormInternalBasalConnections(self, *args, **kwargs)

    def getLearnOnOneCell(self):
        """getLearnOnOneCell(self) -> bool"""
        return _experimental.ExtendedTemporalMemory_getLearnOnOneCell(self)

    def setLearnOnOneCell(self, *args, **kwargs):
        """setLearnOnOneCell(self, learnOnOneCell)"""
        return _experimental.ExtendedTemporalMemory_setLearnOnOneCell(self, *args, **kwargs)

    def getPermanenceIncrement(self):
        """getPermanenceIncrement(self) -> nupic::algorithms::connections::Permanence"""
        return _experimental.ExtendedTemporalMemory_getPermanenceIncrement(self)

    def setPermanenceIncrement(self, *args, **kwargs):
        """setPermanenceIncrement(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setPermanenceIncrement(self, *args, **kwargs)

    def getPermanenceDecrement(self):
        """getPermanenceDecrement(self) -> nupic::algorithms::connections::Permanence"""
        return _experimental.ExtendedTemporalMemory_getPermanenceDecrement(self)

    def setPermanenceDecrement(self, *args, **kwargs):
        """setPermanenceDecrement(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setPermanenceDecrement(self, *args, **kwargs)

    def getPredictedSegmentDecrement(self):
        """getPredictedSegmentDecrement(self) -> nupic::algorithms::connections::Permanence"""
        return _experimental.ExtendedTemporalMemory_getPredictedSegmentDecrement(self)

    def setPredictedSegmentDecrement(self, *args, **kwargs):
        """setPredictedSegmentDecrement(self, arg2)"""
        return _experimental.ExtendedTemporalMemory_setPredictedSegmentDecrement(self, *args, **kwargs)

    def _validateCell(self, *args, **kwargs):
        """_validateCell(self, cell) -> bool"""
        return _experimental.ExtendedTemporalMemory__validateCell(self, *args, **kwargs)

    def save(self, *args, **kwargs):
        """save(self, outStream)"""
        return _experimental.ExtendedTemporalMemory_save(self, *args, **kwargs)

    def load(self, *args, **kwargs):
        """load(self, inStream)"""
        return _experimental.ExtendedTemporalMemory_load(self, *args, **kwargs)

    def read(self, *args):
        """
        read(self)
        read(self, proto)
        """
        return _experimental.ExtendedTemporalMemory_read(self, *args)

    def persistentSize(self):
        """persistentSize(self) -> nupic::UInt"""
        return _experimental.ExtendedTemporalMemory_persistentSize(self)

    def printParameters(self):
        """printParameters(self)"""
        return _experimental.ExtendedTemporalMemory_printParameters(self)

    def columnForCell(self, *args, **kwargs):
        """columnForCell(self, cell) -> nupic::Int"""
        return _experimental.ExtendedTemporalMemory_columnForCell(self, *args, **kwargs)

    def printState(self, *args):
        """
        printState(self, state)
        printState(self, state)
        """
        return _experimental.ExtendedTemporalMemory_printState(self, *args)

    basalConnections = _swig_property(_experimental.ExtendedTemporalMemory_basalConnections_get, _experimental.ExtendedTemporalMemory_basalConnections_set)
    apicalConnections = _swig_property(_experimental.ExtendedTemporalMemory_apicalConnections_get, _experimental.ExtendedTemporalMemory_apicalConnections_set)
    def __init__(self,
                 columnDimensions=(2048,),
                 cellsPerColumn=32,
                 activationThreshold=13,
                 initialPermanence=0.21,
                 connectedPermanence=0.50,
                 minThreshold=10,
                 maxNewSynapseCount=20,
                 permanenceIncrement=0.10,
                 permanenceDecrement=0.10,
                 predictedSegmentDecrement=0.00,
                 formInternalBasalConnections=True,
                 maxSegmentsPerCell=255,
                 maxSynapsesPerSegment=255,
                 seed=42,
                 learnOnOneCell=False):
      self.this = _EXPERIMENTAL.new_ExtendedTemporalMemory(
        columnDimensions, cellsPerColumn, activationThreshold,
        initialPermanence, connectedPermanence,
        minThreshold, maxNewSynapseCount, permanenceIncrement,
        permanenceDecrement, predictedSegmentDecrement,
        formInternalBasalConnections, learnOnOneCell, seed, maxSegmentsPerCell,
        maxSynapsesPerSegment)

      self.activeExternalCellsBasal = numpy.array([], dtype=uintDType)
      self.activeExternalCellsApical = numpy.array([], dtype=uintDType)
      self.connections = self.basalConnections

    def __getstate__(self):
      # Save the local attributes but override the C++ temporal memory with the
      # string representation.
      d = dict(self.__dict__)
      d["this"] = self.getCState()
      return d

    def __setstate__(self, state):
      # Create an empty C++ temporal memory and populate it from the serialized
      # string.
      self.this = _EXPERIMENTAL.new_ExtendedTemporalMemory()
      if isinstance(state, str):
        self.loadFromString(state)
        self.valueToCategory = {}
      else:
        self.loadFromString(state["this"])
        # Use the rest of the state to set local Python attributes.
        del state["this"]
        self.__dict__.update(state)


    def activateCells(self,
                      activeColumns,
                      prevActiveExternalCellsBasal,
                      prevActiveExternalCellsApical,
                      learn=True):
      """
      Calculate the active cells, using the current active columns and dendrite
      segments. Grow and reinforce synapses.

      @param activeColumns (iterable)
      Indices of active columns.

      @param prevActiveExternalCellsBasal (iterable)
      External cells that were used to calculate the current basal segment
      excitation.

      @param prevActiveExternalCellsApical (iterable)
      External cells that were used to calculate the current apical segment
      excitation.

      @param learn (boolean)
      Whether to grow / reinforce / punish synapses.
      """
      columnsArray = numpy.array(sorted(activeColumns), dtype=uintDType)
      basalArray = numpy.array((sorted(prevActiveExternalCellsBasal)
                                if prevActiveExternalCellsBasal is not None
                                  else []),
                               dtype=uintDType)
      apicalArray = numpy.array((sorted(prevActiveExternalCellsApical)
                                if prevActiveExternalCellsApical is not None
                                  else []),
                               dtype=uintDType)

      self.convertedActivateCells(columnsArray, basalArray, apicalArray, learn)


    def activateDendrites(self,
                          activeExternalCellsBasal,
                          activeExternalCellsApical,
                          learn=True):
      """
      Calculate dendrite segment activity, using the current active cells.

      @param activeExternalCellsBasal (iterable)
      Active external cells for activating basal dendrites.

      @param activeExternalCellsApical (iterable)
      Active external cells for activating apical dendrites.

      @param learn (boolean)
      If true, segment activations will be recorded. This information is used
      during segment cleanup.
      """
      basalArray = numpy.array((sorted(activeExternalCellsBasal)
                                if activeExternalCellsBasal is not None
                                  else []),
                               dtype=uintDType)
      apicalArray = numpy.array((sorted(activeExternalCellsApical)
                                if activeExternalCellsApical is not None
                                  else []),
                               dtype=uintDType)

      self.convertedActivateDendrites(basalArray, apicalArray, learn)


    def compute(self,
                activeColumns,
                activeExternalCells=None,
                activeApicalCells=None,
                formInternalConnections=True,
                learn=True):
      """
      Perform one time step of the Temporal Memory algorithm.

      This method calls activateCells, then calls activateDendrites. Using
      the TemporalMemory via its compute method ensures that you'll always
      be able to call getPredictiveCells to get predictions for the next
      time step.

      @param activeColumns (iterable)
      Indices of active columns.

      @param activeExternalCellsBasal (iterable)
      Active external cells that should be used for activating basal dendrites
      in this timestep.

      @param activeExternalCellsApical (iterable)
      Active external cells that should be used for activating apical dendrites
      in this timestep.

      @param formInternalConnections (boolean)
      Whether to grow synapses to other cells within this temporal memory.

      @param learn (boolean)
      Whether or not learning is enabled.
      """
      activeColumnsArray = numpy.array(sorted(activeColumns), dtype=uintDType)
      activeExternalCellsBasal = numpy.array((sorted(activeExternalCells)
                                              if activeExternalCells is not None
                                              else []),
                                             dtype=uintDType)
      activeExternalCellsApical = numpy.array((sorted(activeApicalCells)
                                               if activeApicalCells is not None
                                               else []),
                                              dtype=uintDType)

      _EXPERIMENTAL.ExtendedTemporalMemory_setFormInternalBasalConnections(
        self, formInternalConnections)

      self.convertedCompute(
        activeColumnsArray,
        self.activeExternalCellsBasal,
        activeExternalCellsBasal,
        self.activeExternalCellsApical,
        activeExternalCellsApical,
        learn)

      self.activeExternalCellsBasal = activeExternalCellsBasal
      self.activeExternalCellsApical = activeExternalCellsApical

    def reset(self):
      self.activeExternalCellsBasal = numpy.array([], dtype=uintDType)
      self.activeExternalCellsApical = numpy.array([], dtype=uintDType)
      _EXPERIMENTAL.ExtendedTemporalMemory_reset(self)

    @classmethod
    def read(cls, proto):
      instance = cls()
      instance.convertedRead(proto)
      return instance

    def getActiveCells(self):
        """getActiveCells(self) -> PyObject *"""
        return _experimental.ExtendedTemporalMemory_getActiveCells(self)

    def getPredictiveCells(self):
        """getPredictiveCells(self) -> PyObject *"""
        return _experimental.ExtendedTemporalMemory_getPredictiveCells(self)

    def getWinnerCells(self):
        """getWinnerCells(self) -> PyObject *"""
        return _experimental.ExtendedTemporalMemory_getWinnerCells(self)

    def cellsForColumn(self, *args, **kwargs):
        """cellsForColumn(self, columnIdx) -> PyObject *"""
        return _experimental.ExtendedTemporalMemory_cellsForColumn(self, *args, **kwargs)

    def convertedActivateCells(self, *args, **kwargs):
        """
        convertedActivateCells(self, py_activeColumns, py_prevActiveExternalCellsBasal, py_prevActiveExternalCellsApical, 
            learn)
        """
        return _experimental.ExtendedTemporalMemory_convertedActivateCells(self, *args, **kwargs)

    def convertedActivateDendrites(self, *args, **kwargs):
        """convertedActivateDendrites(self, py_activeExternalCellsBasal, py_activeExternalCellsApical, learn)"""
        return _experimental.ExtendedTemporalMemory_convertedActivateDendrites(self, *args, **kwargs)

    def convertedCompute(self, *args, **kwargs):
        """
        convertedCompute(self, py_activeColumns, py_prevActiveExternalCellsBasal, py_activeExternalCellsBasal, py_prevActiveExternalCellsApical, 
            py_activeExternalCellsApical, learn)
        """
        return _experimental.ExtendedTemporalMemory_convertedCompute(self, *args, **kwargs)

    def write(self, *args):
        """
        write(self)
        write(self, proto)
        write(self, pyBuilder)
        """
        return _experimental.ExtendedTemporalMemory_write(self, *args)

    def convertedRead(self, *args, **kwargs):
        """convertedRead(self, pyReader)"""
        return _experimental.ExtendedTemporalMemory_convertedRead(self, *args, **kwargs)

    def loadFromString(self, *args, **kwargs):
        """loadFromString(self, inString)"""
        return _experimental.ExtendedTemporalMemory_loadFromString(self, *args, **kwargs)

    def getCState(self):
        """getCState(self) -> PyObject *"""
        return _experimental.ExtendedTemporalMemory_getCState(self)

ExtendedTemporalMemory_swigregister = _experimental.ExtendedTemporalMemory_swigregister
ExtendedTemporalMemory_swigregister(ExtendedTemporalMemory)



