diff --git a/.travis/travis_build_linux.sh b/.travis/travis_build_linux.sh index 5530f9a7948b0a9bc1663c81ab30abcb265eb441..3a2ebbfa48f5022d52eb5af6bec4e001ce91025d 100755 --- a/.travis/travis_build_linux.sh +++ b/.travis/travis_build_linux.sh @@ -20,20 +20,22 @@ set -o nounset # Treat unset variables as an error set -e -PYTHON2="/usr/bin/python2" -PYTHON3=`which python3` #MAKEFLAGS="-j 4" +PYTHON2="/usr/bin/python2" # Bug: `which python` returns /opt/bin/python* etc on travis. For which numpy # many not be available. Therefore, it is neccessary to use fixed path for # python executable. +PYTHON3="/usr/bin/python3" ( # Old makefile based flow. $PYTHON2 -m compileall -q . if type $PYTHON3 > /dev/null; then $PYTHON3 -m compileall -q . ; fi - # Traditional make. - make + ## DEPRECATED: No longer testing make file. + + ## Traditional make. + #make ## CMAKE based flow mkdir -p _GSL_BUILD && cd _GSL_BUILD && \ cmake -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" .. diff --git a/VERSION b/VERSION deleted file mode 100644 index 93738075c8d40e9ffc625dbd7b2f96b6ee4111d0..0000000000000000000000000000000000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -3.1.1-129-g669b981 \ No newline at end of file diff --git a/basecode/global.cpp b/basecode/global.cpp index ec5a523e78e911755e12565e854af321b5172ada..b54fc979131dce4103a106281a28ab23ef0d7375 100644 --- a/basecode/global.cpp +++ b/basecode/global.cpp @@ -87,7 +87,7 @@ namespace moose { * * @param x */ - void mtseed( unsigned int x ) + void mtseed( int x ) { moose::__rng_seed__ = x; moose::rng.setSeed( x ); diff --git a/basecode/global.h b/basecode/global.h index 9b06b2820245f1ef4d8fd0639be1b3e6f42a5a13..40b2dba5758c8c848e49ecca9a7b92257b4c9d9f 100644 --- a/basecode/global.h +++ b/basecode/global.h @@ -109,7 +109,7 @@ namespace moose * * @param seed */ - void mtseed( unsigned int seed ); + void mtseed( int seed ); /** * @brief Generate a random double between 0 and 1 diff --git a/biophysics/ReadSwc.cpp b/biophysics/ReadSwc.cpp index 9894e0472bf64628f75971fc76ae95f6d2c3ddf6..3fde18ec6c22e432c8d6d7fb405d57aab376b4c1 100644 --- a/biophysics/ReadSwc.cpp +++ b/biophysics/ReadSwc.cpp @@ -23,6 +23,7 @@ static const double MinRadius = 0.04; ReadSwc::ReadSwc( const string& fname ) { + bool verbose = false; ifstream fin( fname.c_str() ); if ( !fin ) { cerr << "ReadSwc:: could not open file " << fname << endl; @@ -52,12 +53,13 @@ ReadSwc::ReadSwc( const string& fname ) cleanZeroLength(); parseBranches(); } - cout << "ReadSwc: " << fname << " : NumSegs = " << segs_.size() << + cout << "ReadSwc: " << fname << " : " << (valid ? "OK" : "FAILED" )<< + ", # Branches = " << branches_.size() << + ". # Segs = " << segs_.size() << ", bad = " << badSegs << - ", Validated = " << valid << - ", numBranches = " << branches_.size() << endl; - diagnostics(); + if ( verbose ) + diagnostics(); } bool ReadSwc::validate() const diff --git a/pymoose/CMakeLists.txt b/pymoose/CMakeLists.txt index 83397de45054b7cc470f3c144ec6632ad3978c05..af4e8e749a827b113267d557ba89f7071277ff14 100644 --- a/pymoose/CMakeLists.txt +++ b/pymoose/CMakeLists.txt @@ -1,6 +1,8 @@ add_definitions(-DPYMOOSE) include_directories(../basecode ../msg) +find_package( PythonInterp REQUIRED ) + set(PYMOOSE_SRCS moosemodule.cpp vec.cpp @@ -18,10 +20,18 @@ EXEC_PROGRAM(${PYTHON_EXECUTABLE} except Exception: pass'" OUTPUT_VARIABLE PYTHON_SO_EXTENSION ) + +message( STATUS "Python path ${PYTHON_EXECUTABLE}" ) message( STATUS "Python so extension ${PYTHON_SO_EXTENSION}" ) find_package(NumPy REQUIRED) -include_directories(${NUMPY_INCLUDE_DIRS}) +find_package(PythonLibs REQUIRED) + +include_directories( ${NUMPY_INCLUDE_DIRS} ) +include_directories( ${PYTHON_INCLUDE_DIRS} ) + +message( STATUS "Python include dir : ${PYTHON_INCLUDE_DIRS} " ) + add_definitions(-DUSE_NUMPY) add_definitions(-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION) @@ -34,7 +44,12 @@ execute_process( COMMAND ${PYTHON_EXECUTABLE}-config --libs OUTPUT_VARIABLE PYTHON_LIBRARIES OUTPUT_STRIP_TRAILING_WHITESPACE ) + +if( NOT PYTHON_INCLUDE_FLAGS ) + set( PYTHON_INCLUDE_FLAGS "-I ${PYTHON_INCLUDE_DIRS} " ) +endif( ) message( STATUS "Python include flags: ${PYTHON_INCLUDE_FLAGS}" ) + set_target_properties(_moose PROPERTIES COMPILE_DEFINITIONS "PYMOOSE" COMPILE_FLAGS "${PYTHON_INCLUDE_FLAGS}" @@ -43,11 +58,6 @@ set_target_properties(_moose PROPERTIES SUFFIX ".so" ) -#if(NOT(PYTHON_SO_EXTENSION STREQUAL "")) -# set_target_properties(_moose PROPERTIES -# SUFFIX ${PYTHON_SO_EXTENSION}) -#endif() - # see issue #80 if(HDF5_LIBRARY_DIRS) set_target_properties( _moose PROPERTIES LINK_FLAGS "-L${HDF5_LIBRARY_DIRS}" ) diff --git a/python/moose/SBML/readSBML.py b/python/moose/SBML/readSBML.py index 220442975ced71ad8a5af13e63e256f03eac3a0f..255d96783e4d576b8cbc1430b1d2ba10898b08f3 100644 --- a/python/moose/SBML/readSBML.py +++ b/python/moose/SBML/readSBML.py @@ -66,11 +66,12 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): '\n\t easy_install python-libsbml' '\n\t apt-get install python-libsbml' ) - return None + return moose.element('/') if not os.path.isfile(filepath): print('%s is not found ' % filepath) - return None + return moose.element('/') + with open(filepath, "r") as filep: filep = open(filepath, "r") diff --git a/python/moose/plot_utils.py b/python/moose/plot_utils.py index b2740954dc10103f0c6e6f266ce08cb4cedeb315..94c8577e7491f4550f72774303f10e7a9872af1e 100644 --- a/python/moose/plot_utils.py +++ b/python/moose/plot_utils.py @@ -135,7 +135,7 @@ def plotTables(tables, outfile=None, **kwargs): subplot = kwargs.get('subplot', True) for i, tname in enumerate(tables): if subplot: - plt.subplot(len(tables), 1, i) + plt.subplot(len(tables), 1, i+1) yvec = tables[tname].vector xvec = np.linspace(0, moose.Clock('/clock').currentTime, len(yvec)) plt.plot(xvec, yvec, label=tname) @@ -165,7 +165,7 @@ def plotVector(vec, xvec = None, **options): :param vec: Given vector. :param **kwargs: Optional to pass to maplotlib. """ - + ax = options[ 'ax' ] assert type(vec) == np.ndarray, "Expected type %s" % type(vec) legend = options.get('legend', True) @@ -176,28 +176,29 @@ def plotVector(vec, xvec = None, **options): xx = xvec[:] assert len(xx) == len(vec), "Expecting %s got %s" % (len(vec), len(xvec)) + ax.plot(xx, vec, label=options.get('label', '')) - plt.plot(xx, vec, label=options.get('label', '')) if legend: # This may not be available on older version of matplotlib. try: - plt.legend(loc='best', framealpha=0.4) + ax.legend(loc='best', framealpha=0.4) except: - plt.legend(loc='best') + ax.legend(loc='best') if xvec is None: - plt.xlabel('Time (sec)') + ax.set_xlabel('Time (sec)') else: - plt.xlabel(options.get('xlabel', '')) + ax.set_xlabel(options.get('xlabel', '')) - plt.ylabel = options.get('ylabel', '') - plt.title(options.get('title', '')) + ax.set_ylabel = options.get('ylabel', '') + ax.set_title(options.get('title', '')) if(options.get('legend', True)): try: - plt.legend(loc='best', framealpha=0.4, prop={'size' : 9}) + ax.legend(loc='best', framealpha=0.4, prop={'size' : 9}) except: - plt.legend(loc='best', prop={'size' : 9}) + ax.legend(loc='best', prop={'size' : 9}) + return ax def saveRecords(records, xvec = None, **kwargs): @@ -267,7 +268,7 @@ def plotRecords(records, xvec = None, **kwargs): yvec = dataDict[k].vector plotVector(yvec, xvec, label=k, **kwargs) else: - plt.subplot(len(dataDict), 1, i) + kwargs[ 'ax' ] = plt.subplot(len(dataDict), 1, i) yvec = dataDict[k].vector plotVector(yvec, xvec, label=k, **kwargs) @@ -286,9 +287,13 @@ def plotRecords(records, xvec = None, **kwargs): else: plt.show() +def plot_records( data_dict, xvec = None, **kwargs ): + """Renamed (deprecated) + """ + return plot_tables( data_dict, xvec, **kwargs ) -def plot_records(data_dict, xvec = None, **kwargs): - """plot_records Plot given dictionary. +def plot_tables(data_dict, xvec = None, **kwargs): + """plot_tables plots moose.Table stored in a dictionary. :param data_dict: :param xvec: If None, use moose.Clock to generate xvec. @@ -300,7 +305,12 @@ def plot_records(data_dict, xvec = None, **kwargs): subplot = kwargs.get('subplot', False) filters = [ x.lower() for x in kwargs.get('filter', [])] - plt.figure(figsize=(10, 1.5*len(data_dict))) + ax = kwargs.get( 'ax', None ) + if ax is None: + plt.figure(figsize=(10, 1.5*len(data_dict))) + if not subplot: + ax = plt.subplot( 1, 1, 1 ) + for i, k in enumerate(data_dict): pu.info("+ Plotting for %s" % k) plotThis = False @@ -312,10 +322,10 @@ def plot_records(data_dict, xvec = None, **kwargs): if plotThis: if not subplot: - yvec = data_dict[k] + yvec = data_dict[k].vector plotVector(yvec, xvec, label=k, **kwargs) else: - plt.subplot(len(data_dict), 1, i) + ax = plt.subplot(len(data_dict), 1, i) yvec = data_dict[k] plotVector(yvec, xvec, label=k, **kwargs) if subplot: diff --git a/python/rdesigneur/rdesigneur.py b/python/rdesigneur/rdesigneur.py index ed38fce962dc452e9a32d275c9fd353b6d075f18..632e7ead2a16364e4f6e4154d82a1f75ea6b5a14 100644 --- a/python/rdesigneur/rdesigneur.py +++ b/python/rdesigneur/rdesigneur.py @@ -80,6 +80,7 @@ class rdesigneur: useGssa = True, combineSegments = True, stealCellFromLibrary = False, + verbose = True, diffusionLength= 2e-6, meshLambda = -1.0, #This is a backward compatibility hack temperature = 32, @@ -111,6 +112,7 @@ class rdesigneur: self.useGssa = useGssa self.combineSegments = combineSegments self.stealCellFromLibrary = stealCellFromLibrary + self.verbose = verbose self.diffusionLength= diffusionLength if meshLambda > 0.0: print("Warning: meshLambda argument is deprecated. Please use 'diffusionLength' instead.\nFor now rdesigneur will accept this argument.") @@ -201,7 +203,8 @@ class rdesigneur: self._buildMoogli() self._buildStims() self._configureClocks() - self._printModelStats() + if self.verbose: + self._printModelStats() self._savePlots() except BuildError as msg: @@ -315,7 +318,8 @@ class rdesigneur: return True if moose.exists( '/library/' + protoVec[0] ): #moose.copy('/library/' + protoVec[0], '/library/', protoVec[1]) - print('renaming /library/' + protoVec[0] + ' to ' + protoVec[1]) + if self.verbose: + print('renaming /library/' + protoVec[0] + ' to ' + protoVec[1]) moose.element( '/library/' + protoVec[0]).name = protoVec[1] #moose.le( '/library' ) return True @@ -596,6 +600,7 @@ class rdesigneur: def _buildMoogli( self ): knownFields = { 'Vm':('CompartmentBase', 'getVm', 1000, 'Memb. Potential (mV)', -80.0, 40.0 ), + 'initVm':('CompartmentBase', 'getInitVm', 1000, 'Init. Memb. Potl (mV)', -80.0, 40.0 ), 'Im':('CompartmentBase', 'getIm', 1e9, 'Memb. current (nA)', -10.0, 10.0 ), 'inject':('CompartmentBase', 'getInject', 1e9, 'inject current (nA)', -10.0, 10.0 ), 'Gbar':('ChanBase', 'getGbar', 1e9, 'chan max conductance (nS)', 0.0, 1.0 ), diff --git a/synapse/CMakeLists.txt b/synapse/CMakeLists.txt index bb47b9779b8f3d9c7393cd01f44c27f803ee4248..2b7d36221cd5c50d3afa67766da3f403a1cd75c2 100644 --- a/synapse/CMakeLists.txt +++ b/synapse/CMakeLists.txt @@ -1,5 +1,18 @@ cmake_minimum_required(VERSION 2.8) + include_directories( ../basecode ../utility ../kinetics) include_directories( ../external/muparser/include/ ) -file(GLOB SYNAPSE_SRCS *.cpp) + +set( SYNAPSE_SRCS + GraupnerBrunel2012CaPlasticitySynHandler.cpp + RollingMatrix.cpp + SeqSynHandler.cpp + SimpleSynHandler.cpp + STDPSynapse.cpp + STDPSynHandler.cpp + Synapse.cpp + SynHandlerBase.cpp + testSynapse.cpp + ) + add_library(synapse ${SYNAPSE_SRCS} ) diff --git a/synapse/RollingMatrix.cpp b/synapse/RollingMatrix.cpp index f4f5193feab6dc2746ec65c94bdaf8e324b55b15..01818a83f98d356536ca787c696a3f67cac6e03d 100644 --- a/synapse/RollingMatrix.cpp +++ b/synapse/RollingMatrix.cpp @@ -72,7 +72,7 @@ double RollingMatrix::dotProduct( const vector< double >& input, unsigned int index = (row + currentStartRow_) % nrows_; const SparseVector& sv = rows_[index]; unsigned int i2 = input.size()/2; - unsigned int istart = (startColumn <= i2) ? 0 : startColumn - i2; + unsigned int istart = (startColumn >= i2) ? 0 : i2-startColumn; unsigned int colstart = (startColumn <= i2) ? 0 : startColumn - i2; unsigned int iend = (sv.size()-startColumn > i2 ) ? input.size() : i2 - startColumn + sv.size(); diff --git a/synapse/SeqSynHandler.cpp b/synapse/SeqSynHandler.cpp index e6ca94f8e8bccadd54293ee9267d136bce0cfcb9..f31f91171120706a2c54f1ffc7ecadbe151409af 100644 --- a/synapse/SeqSynHandler.cpp +++ b/synapse/SeqSynHandler.cpp @@ -8,6 +8,7 @@ **********************************************************************/ #include <queue> +#include "global.h" #include "header.h" #include "Synapse.h" #include "SynEvent.h" @@ -105,6 +106,29 @@ const Cinfo* SeqSynHandler::initCinfo() &SeqSynHandler::setSequenceScale, &SeqSynHandler::getSequenceScale ); + static ValueFinfo< SeqSynHandler, vector< unsigned int > > synapseOrder( + "synapseOrder", + "Mapping of synapse input order to spatial order on syn array." + "Entries in this vector are indices which must remain smaller " + "than numSynapses. The system will fix up if you mess up. " + "It does not insist on unique mappings, but these are " + "desirable as outcome is undefined for repeated entries.", + &SeqSynHandler::setSynapseOrder, + &SeqSynHandler::getSynapseOrder + ); + static ValueFinfo< SeqSynHandler, int > synapseOrderOption( + "synapseOrderOption", + "How to do the synapse order remapping. This rule stays in " + "place and guarantees safe mappings even if the number of " + "synapses is altered. Options:\n" + "-2: User ordering.\n" + "-1: Sequential ordering, 0 to numSynapses-1.\n" + "0: Random ordering using existing system seed.\n" + ">0: Random ordering using seed specified by this number\n" + "Default is -1, sequential ordering.", + &SeqSynHandler::setSynapseOrderOption, + &SeqSynHandler::getSynapseOrderOption + ); static ReadOnlyValueFinfo< SeqSynHandler, double > seqActivation( "seqActivation", "Reports summed activation of synaptic channel by sequence", @@ -141,9 +165,11 @@ const Cinfo* SeqSynHandler::initCinfo() &historyTime, // Field &sequenceScale, // Field &baseScale, // Field - &seqActivation, // Field + &synapseOrder, // Field + &synapseOrderOption, // Field + &seqActivation, // ReadOnlyField &plasticityScale, // Field - &weightScaleVec, // Field + &weightScaleVec, // ReadOnlyField &kernel, // ReadOnlyField &history // ReadOnlyField }; @@ -172,10 +198,11 @@ SeqSynHandler::SeqSynHandler() kernelWidth_( 5 ), historyTime_( 2.0 ), seqDt_ ( 1.0 ), - sequenceScale_( 1.0 ), baseScale_( 0.0 ), + sequenceScale_( 1.0 ), plasticityScale_( 0.0 ), - seqActivation_( 0.0 ) + seqActivation_( 0.0 ), + synapseOrderOption_( -1 ) // sequential ordering { history_.resize( numHistory(), 0 ); } @@ -208,6 +235,7 @@ void SeqSynHandler::vSetNumSynapses( const unsigned int v ) history_.resize( numHistory(), v ); latestSpikes_.resize( v, 0.0 ); weightScaleVec_.resize( v, 0.0 ); + refillSynapseOrder( v ); updateKernel(); } @@ -227,6 +255,65 @@ Synapse* SeqSynHandler::vGetSynapse( unsigned int i ) } ////////////////////////////////////////////////////////////////////// + +// Checks for numbers bigger than the size. Replaces with +// values within the range that have not yet been used. +void SeqSynHandler::fixSynapseOrder() +{ + unsigned int sz = synapseOrder_.size(); + vector< unsigned int > availableEntries( sz ); + iota( availableEntries.begin(), availableEntries.end(), 0 ); + for( unsigned int i = 0; i < sz; ++i ) { + if ( synapseOrder_[i] < sz ) + availableEntries[ synapseOrder_[i] ] = sz; + } + vector< unsigned int > ae; + for( unsigned int i = 0; i < sz; ++i ) + if ( availableEntries[i] < sz ) + ae.push_back( availableEntries[i] ); + + auto jj = ae.begin(); + for( unsigned int i = 0; i < sz; ++i ) { + if ( synapseOrder_[i] >= sz ) + synapseOrder_[i] = *jj++; + } +} + +// Beautiful snippet from Lukasz Wiklendt on StackOverflow. Returns order +// of entries in a vector. +template <typename T> vector<size_t> sort_indexes(const vector<T> &v) { + // initialize original index locations + vector<size_t> idx(v.size()); + iota(idx.begin(), idx.end(), 0); + // sort indexes based on comparing values in v + sort(idx.begin(), idx.end(), + [&v](size_t i1, size_t i2) {return v[i1] < v[i2];}); + return idx; +} + +void SeqSynHandler::refillSynapseOrder( unsigned int newSize ) +{ + if ( synapseOrderOption_ <= -2 ) { // User order + synapseOrder_.resize( newSize, newSize ); + fixSynapseOrder(); + } else if ( synapseOrderOption_ == -1 ) { // Ordered + synapseOrder_.resize( newSize ); + for ( unsigned int i = 0 ; i < newSize; ++i ) + synapseOrder_[i] = i; + } else { + synapseOrder_.resize( newSize ); + if ( synapseOrderOption_ > 0 ) { // Specify seed explicitly + moose::mtseed( synapseOrderOption_ ); + } + vector< double > x; + for ( unsigned int i = 0; i < newSize; ++i ) + x.push_back( moose::mtrand() ); + auto idx = sort_indexes< double >( x ); + for ( unsigned int i = 0; i < newSize; ++i ) + synapseOrder_[i] = idx[i]; + } +} + void SeqSynHandler::updateKernel() { if ( kernelEquation_ == "" || seqDt_ < 1e-9 || historyTime_ < 1e-9 ) @@ -362,6 +449,29 @@ vector< double > SeqSynHandler::getHistory() const return ret; } +void SeqSynHandler::setSynapseOrder( vector< unsigned int > v ) +{ + synapseOrder_ = v; + fixSynapseOrder(); + synapseOrderOption_ = -2; // Set the flag to say it is User defined. +} + +vector< unsigned int > SeqSynHandler::getSynapseOrder() const +{ + return synapseOrder_; +} + +void SeqSynHandler::setSynapseOrderOption( int v ) +{ + synapseOrderOption_ = v; + refillSynapseOrder( synapseOrder_.size() ); +} + +int SeqSynHandler::getSynapseOrderOption() const +{ + return synapseOrderOption_; +} + ///////////////////////////////////////////////////////////////////// void SeqSynHandler::addSpike(unsigned int index, double time, double weight) @@ -373,7 +483,9 @@ void SeqSynHandler::addSpike(unsigned int index, double time, double weight) // slice. For now, to get it going for LIF neurons, this will do. // Even in the general case we will probably have a very wide window // for the latestSpikes slice. - latestSpikes_[index] += weight; + // + // Here we reorder the entries in latestSpikes by the synapse order. + latestSpikes_[ synapseOrder_[index] ] += weight; } unsigned int SeqSynHandler::addSynapse() diff --git a/synapse/SeqSynHandler.h b/synapse/SeqSynHandler.h index 73578b0420bbec7c877726bf7aa0831725b5b455..45217ba0c4c6e052de5ae11cbc47d35714554a8b 100644 --- a/synapse/SeqSynHandler.h +++ b/synapse/SeqSynHandler.h @@ -59,6 +59,10 @@ class SeqSynHandler: public SynHandlerBase double getBaseScale() const; void setSequenceScale( double v ); double getSequenceScale() const; + void setSynapseOrder( vector< unsigned int> v ); + vector< unsigned int> getSynapseOrder() const; + void setSynapseOrderOption( int v ); + int getSynapseOrderOption() const; double getSeqActivation() const; // summed activation of syn chan void setPlasticityScale( double v ); double getPlasticityScale() const; @@ -69,6 +73,8 @@ class SeqSynHandler: public SynHandlerBase //////////////////////////////////////////////////////////////// // Utility func int numHistory() const; + void refillSynapseOrder( unsigned int newSize ); + void fixSynapseOrder(); //////////////////////////////////////////////////////////////// static const Cinfo* initCinfo(); private: @@ -116,8 +122,23 @@ class SeqSynHandler: public SynHandlerBase vector< double > latestSpikes_; /////////////////////////////////////////// - vector< vector< double > > kernel_; //Kernel for seq selectivity - RollingMatrix history_; // Rows = time; cols = synInputs + vector< vector< double > > kernel_; ///Kernel for seq selectivity + RollingMatrix history_; /// Rows = time; cols = synInputs + /** + * Remaps synapse order to avoid correlations based on presynaptic + * object Id order, or on connection building order. This + * undesirable ordering occurs even when random synaptic + * projections are used. User can alter as preferred. This is + * simply a look up table so that the incoming synapse index is + * remapped: index_on_Handler = synapseOrder_[original_syn_index] + * This must only have numbers from zero to numSynapses, and should + * normally have all the numbers. + */ + vector< unsigned int > synapseOrder_; + + /// Options: -2: User. -1: ordered. 0: random by system seed. + /// > 0: Random by seed specified by this number + int synapseOrderOption_; vector< Synapse > synapses_; priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > events_; diff --git a/synapse/testSynapse.cpp b/synapse/testSynapse.cpp index 944525ff8506c78105c2ccf811d8e9a78c2c13fd..b39b87bd654e47cd3b03dfd7f8af665b31068715 100644 --- a/synapse/testSynapse.cpp +++ b/synapse/testSynapse.cpp @@ -99,32 +99,44 @@ void testRollingMatrix() for ( int i = 0; i < nr; ++i ) input[i] = i + 1; - assert( doubleEq( rm.dotProduct( input, 0, 0 ), 0.0 ) ); - assert( doubleEq( rm.dotProduct( input, 1, 0 ), 1.0 ) ); - assert( doubleEq( rm.dotProduct( input, 2, 0 ), 4.0 ) ); - assert( doubleEq( rm.dotProduct( input, 3, 0 ), 9.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 0 ), 16.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 1 ), 12.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 2 ), 8.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 3 ), 4.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 4 ), 0.0 ) ); - + assert( doubleEq( rm.dotProduct( input, 0, 5 ), 0.0 ) ); + assert( doubleEq( rm.dotProduct( input, 1, 5 ), 1.0 ) ); + assert( doubleEq( rm.dotProduct( input, 2, 5 ), 4.0 ) ); + assert( doubleEq( rm.dotProduct( input, 3, 5 ), 9.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 5 ), 16.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 6 ), 12.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 7 ), 8.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 8 ), 4.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 9 ), 0.0 ) ); + + // Note that the input and the row are aligned at col=5, the + // middle of the input vector. rm.sumIntoRow( input, 0 ); // input == [1234500000] vector< double > corr; rm.correl( corr, input, 4 ); // rm[4] == [00040000] - assert( doubleEq( corr[0], 16.0 ) ); - assert( doubleEq( corr[1], 12.0 ) ); - assert( doubleEq( corr[2], 8.0 ) ); - assert( doubleEq( corr[3], 4.0 ) ); - assert( doubleEq( corr[4], 0.0 ) ); + assert( doubleEq( corr[0], 0.0 ) ); + assert( doubleEq( corr[1], 0.0 ) ); + assert( doubleEq( corr[2], 0.0 ) ); + assert( doubleEq( corr[3], 0.0 ) ); + assert( doubleEq( corr[4], 20.0 ) ); + assert( doubleEq( corr[5], 16.0 ) ); + assert( doubleEq( corr[6], 12.0 ) ); + assert( doubleEq( corr[7], 8.0 ) ); + assert( doubleEq( corr[8], 4.0 ) ); + assert( doubleEq( corr[9], 0.0 ) ); corr.assign( corr.size(), 0 ); rm.correl( corr, input, 0 ); // rm[0] == [1234500000] - assert( doubleEq( corr[0], 55.0 ) ); - assert( doubleEq( corr[1], 40.0 ) ); - assert( doubleEq( corr[2], 26.0 ) ); - assert( doubleEq( corr[3], 14.0 ) ); - assert( doubleEq( corr[4], 5.0 ) ); + assert( doubleEq( corr[0], 0.0 ) ); + assert( doubleEq( corr[1], 5.0 ) ); + assert( doubleEq( corr[2], 14.0 ) ); + assert( doubleEq( corr[3], 26.0 ) ); + assert( doubleEq( corr[4], 40.0 ) ); + assert( doubleEq( corr[5], 55.0 ) ); + assert( doubleEq( corr[6], 40.0 ) ); + assert( doubleEq( corr[7], 26.0 ) ); + assert( doubleEq( corr[8], 14.0 ) ); + assert( doubleEq( corr[9], 5.0 ) ); cout << "." << flush; } @@ -158,14 +170,12 @@ void testSeqSynapse() cout << "." << flush; - // FIXME: See issue BhallaLab/moose-core#174 - // ssh.setResponseScale( 1.0 ); + ssh.setBaseScale( 1.0 ); + ssh.setSequenceScale( 1.0 ); for ( int i = 0; i < numSyn; ++i ) { ssh.addSpike( i, 0.0, 1.0 ); } - - // FIXME: See issue BhallaLab/moose-core#174 - // ssh.setWeightScale( 1.0 ); + ssh.setPlasticityScale( 1.0 ); ProcInfo p; Eref sheller( Id().eref() ); @@ -177,14 +187,13 @@ void testSeqSynapse() // Here we correlate the vector [1,1,1,1,1,1,1,1,1,1,1] with // the kernel [4,1,-1,-1,-1] // Other lines are zeros. - // Should really make the kernel mapping symmetrical. - assert( doubleEq( ssh.getSeqActivation(), 28.0 ) ); + assert( doubleEq( ssh.getSeqActivation(), 14.0 ) ); vector< double > wts = ssh.getWeightScaleVec(); - for ( int i = 0; i < numSyn-4; ++i ) + for ( int i = 2; i < numSyn-2; ++i ) assert( doubleEq( wts[i], 2.0 ) ); - assert( doubleEq( wts[6], 3 ) ); // Edge effects. Last -1 vanishes. - assert( doubleEq( wts[7], 4 ) ); // Edge effects. - assert( doubleEq( wts[8], 5 ) ); // Edge effects. + assert( doubleEq( wts[0], -3 ) ); // Edge effects. + assert( doubleEq( wts[1], -2 ) ); // Edge effects. + assert( doubleEq( wts[8], 3 ) ); // Edge effects. assert( doubleEq( wts[9], 4 ) ); // Edge effects. cout << "." << flush;