int StochasticReleaseTestProbe::outputState(double timed) {
    // Set conn.  Can't do that in initStochasticReleaseTestProbe because we need to search for a conn with the given post, and connections' postLayerName is not necessarily set.
    if (conn==NULL) {
        HyPerCol * hc = getTargetLayer()->getParent();
        int numconns = hc->numberOfConnections();
        for (int c=0; c<numconns; c++) {
            if (!strcmp(hc->getConnection(c)->getPostLayerName(),getTargetLayer()->getName())) {
                assert(conn==NULL); // Only one connection can go to this layer for this probe to work
                BaseConnection * baseConn = hc->getConnection(c);
                conn = dynamic_cast<HyPerConn *>(baseConn);
            }
        }
        assert(conn!=NULL);
    }
    assert(conn->numberOfAxonalArborLists()==1);
    assert(conn->xPatchSize()==1);
    assert(conn->yPatchSize()==1);
    assert(conn->getNumDataPatches()==conn->fPatchSize());
    int status = StatsProbe::outputState(timed);
    assert(status==PV_SUCCESS);
    HyPerLayer * l = getTargetLayer();
    HyPerCol * hc = l->getParent();
    int nf = l->getLayerLoc()->nf;
    if (timed>0.0) {
        for (int f=0; f < nf; f++) {
            if (computePValues(hc->getCurrentStep(), f)!=PV_SUCCESS) status = PV_FAILURE;
        }
        assert(status == PV_SUCCESS);
        if (hc->columnId()==0 && hc->simulationTime()+hc->getDeltaTime()/2>=hc->getStopTime()) {
            // This is the last timestep
            // sort the p-values and apply Holm-Bonferroni method since there is one for each timestep and each feature.
            long int num_steps = hc->getFinalStep() - hc->getInitialStep();
            long int N = num_steps * nf;
            qsort(pvalues, (size_t) N, sizeof(*pvalues), compar);
            while(N>0 && isnan(pvalues[N-1])) {
                N--;
            }
            for (long int k=0; k<N; k++) {
                if (pvalues[k]*(N-k)<0.05) {
                    pvErrorNoExit().printf("layer \"%s\" FAILED: p-value %ld out of %ld (ordered by size) with Holm-Bonferroni correction = %f\n", getTargetLayer()->getName(), k, N, pvalues[k]*(N-k));
                    status = PV_FAILURE;
                }
            }
        }

    }
    assert(status==PV_SUCCESS);
    return status;
}
Ejemplo n.º 2
0
int customexit(HyPerCol * hc, int argc, char * argv[]) {
   HyPerLayer * layer = hc->getLayerFromName("comparison");
   assert(layer!=NULL);
   assert(layer->getNumProbes()>0);
   RequireAllZeroActivityProbe * probe = NULL;
   for (int k=0; k<layer->getNumProbes(); k++) {
      LayerProbe * p = layer->getProbe(k);
      probe = dynamic_cast<RequireAllZeroActivityProbe *>(p);
      if (probe != NULL) { break; }
   }
   assert(probe!=NULL);
   int status = PV_SUCCESS;
   if (probe->getNonzeroFound()) {
      if (hc->columnId()==0) {
         fprintf(stderr, "comparison layer had a nonzero activity at time %f\n", probe->getNonzeroTime());
         status = PV_FAILURE;
      }
   }
   return status;
}
int StochasticReleaseTestProbe::computePValues(long int step, int f) {
   int status = PV_SUCCESS;
   assert(step >=0 && step < INT_MAX);
   int nf = getTargetLayer()->getLayerLoc()->nf;
   assert(f >= 0 && f < nf);
   int idx = (step-1)*nf + f;
   pvwdata_t wgt = conn->get_wDataStart(0)[f*(nf+1)]; // weights should be one-to-one weights

   HyPerLayer * pre = conn->preSynapticLayer();
   const pvdata_t * preactPtr = pre->getLayerData();
   const PVLayerLoc * preLoc = pre->getLayerLoc();
   const int numPreNeurons = pre->getNumNeurons();
   bool found=false;
   pvdata_t preact = 0.0f;
   for (int n=f; n<numPreNeurons; n+=nf) {
      int nExt = kIndexExtended(n, preLoc->nx, preLoc->ny, preLoc->nf, preLoc->halo.lt, preLoc->halo.rt, preLoc->halo.dn, preLoc->halo.up);
      pvdata_t a = preactPtr[nExt];
      if (a!=0.0f) {
         if (found) {
            assert(preact==a);
         }
         else {
            found = true;
            preact = a;
         }
      }
   }
   preact *= getParent()->getDeltaTime();
   if (preact < 0.0f) preact = 0.0f;
   if (preact > 1.0f) preact = 1.0f;

   const PVLayerLoc * loc = getTargetLayer()->getLayerLoc();
   const pvdata_t * activity = getTargetLayer()->getLayerData();
   int nnzf = 0;
   const int numNeurons = getTargetLayer()->getNumNeurons();
   for (int n=f; n<numNeurons; n+=nf) {
      int nExt = kIndexExtended(n, loc->nx, loc->ny, loc->nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up);
      assert(activity[nExt]==0 || activity[nExt]==wgt);
      if (activity[nExt]!=0) nnzf++;
   }
   HyPerLayer * l = getTargetLayer();
   HyPerCol * hc = l->getParent();
   MPI_Allreduce(MPI_IN_PLACE, &nnzf, 1, MPI_INT, MPI_SUM, hc->icCommunicator()->communicator());
   if (hc->columnId()==0) {
      const int neuronsPerFeature = l->getNumGlobalNeurons()/nf;
      double mean = preact * neuronsPerFeature;
      double stddev = sqrt(neuronsPerFeature*preact*(1-preact));
      double numdevs = (nnzf-mean)/stddev;
      pvalues[idx] = erfc(fabs(numdevs)/sqrt(2));
      fprintf(outputstream->fp, "    Feature %d, nnz=%5d, expectation=%7.1f, std.dev.=%5.1f, discrepancy of %f deviations, p-value %f\n",
              f, nnzf, mean, stddev, numdevs, pvalues[idx]);
   }
   assert(status==PV_SUCCESS);
   return status;
}
Ejemplo n.º 4
0
int checkComparisonNonzero(HyPerCol * hc, int argc, char * argv[]) {
   int status = PV_FAILURE;
   int numLayers = hc->numberOfLayers();
   int layerIndex;
   HyPerLayer * layer;
   for( layerIndex=0; layerIndex<numLayers; layerIndex++ ) {
      layer = hc->getLayer(layerIndex);
      if( !strcmp(hc->getLayer(layerIndex)->getName(), "Comparison") ) break;
   }
   if( layerIndex >= numLayers) {
      pvErrorNoExit().printf("%s: couldn't find layer \"Comparison\".", argv[0]);
      return PV_FAILURE;
   }
   pvdata_t * V = layer->getV();
   for( int k=0; k<layer->getNumNeurons(); k++ ) {
      if( V[k] ) {
         status = PV_SUCCESS;
         break;
      }
   }
   return status;
}
int OjaKernelSpikeRateProbe::allocateDataStructures() {
   targetOjaKernelConn = dynamic_cast<OjaKernelConn *>(getTargetConn());
   if (targetOjaKernelConn == NULL) {
      if (getParent()->columnId()==0) {
         fprintf(stderr, "LCATraceProbe error: connection \"%s\" must be an LCALIFLateralConn.\n", getTargetConn()->getName());
      }
      abort();
   }
   HyPerLayer * targetLayer = NULL;
   if (isInputRate) {
      targetLayer = targetOjaKernelConn->preSynapticLayer();
   }
   else {
      targetLayer = targetOjaKernelConn->postSynapticLayer();
   }
   const PVLayerLoc * loc = targetLayer->getLayerLoc();
   int x_local = xg - loc->kx0;
   int y_local = yg - loc->ky0;
   bool inBounds = (x_local >= 0 && x_local < loc->nx && y_local >= 0 && y_local < loc->ny);
   if(inBounds ) { // if inBounds
      int krestricted = kIndex(x_local, y_local, feature, loc->nx, loc->ny, loc->nf);
      if (isInputRate) {
         int kextended = kIndexExtended(krestricted, loc->nx, loc->ny, loc->nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up);
         spikeRate = &targetOjaKernelConn->getInputFiringRate(arbor)[kextended];
      }
      else {
         spikeRate = &targetOjaKernelConn->getOutputFiringRate()[krestricted];
      }
   }
   else {
      outputstream = NULL;
   }
   //This is now being done in BaseConnectionProbe
   //getTargetConn()->insertProbe(this);

   return PV_SUCCESS;
}
Ejemplo n.º 6
0
int PursuitLayer::recvSynapticInput(HyPerConn * conn, const PVLayerCube * activity, int arborID) {
    if (parent->simulationTime()<nextUpdate) return PV_SUCCESS;
    nextUpdate += updatePeriod;
    recvsyn_timer->start();

    assert(arborID >= 0);

    if (conn->usingSharedWeights() == false) {
        fprintf(stderr, "Error: PursuitLayer can only be the postsynaptic layer of a connection using shared weights (this condition should be removed eventually).\n");
        abort();
    }

    HyPerLayer * pre = conn->preSynapticLayer();
    const PVLayerLoc * pre_loc = pre->getLayerLoc();
    if (pre_loc->nx != getLayerLoc()->nx || pre_loc->ny != getLayerLoc()->ny) {
        fprintf(stderr, "Error: PursuitLayer requires incoming connections to be one-to-one.\n");
        abort();
    }


#ifdef DEBUG_OUTPUT
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    //printf("[%d]: HyPerLayr::recvSyn: neighbor=%d num=%d actv=%p this=%p conn=%p\n", rank, neighbor, numExtended, activity, this, conn);
    printf("[%d]: HyPerLayr::recvSyn: neighbor=%d num=%d actv=%p this=%p conn=%p\n", rank, 0, numExtended, activity, this, conn);
    fflush(stdout);
#endif // DEBUG_OUTPUT


    const int numExtended = activity->numItems;
    for (int kPre = 0; kPre < numExtended; kPre++) {
        float a = activity->data[kPre];
        if (a == 0.0f) continue;

        PVPatch * weights = conn->getWeights(kPre, arborID);

        // WARNING - assumes every value in weights maps into a valid value in GSyn
        //         - assumes patch stride sf is 1

        int nk  = conn->fPatchSize() * weights->nx;
        int ny  = weights->ny;
        int sy  = conn->getPostNonextStrides()->sy; // stride in layer
        int syw = conn->yPatchStride();             // stride in patch
        pvdata_t * gSynPatchHead = this->getChannel(conn->getChannel());
        pvdata_t * gSynPatchStart = gSynPatchHead + conn->getGSynPatchStart(kPre, arborID);
        pvwdata_t * data = conn->get_wData(arborID,kPre);
        for (int y = 0; y < ny; y++) {
            (conn->accumulateFunctionPointer)(nk, gSynPatchStart + y*sy, a, data + y*syw, NULL);
        }
    }

    // Set |w(:,:,f)|^2.  Since this is a one-to-one connection with one presynaptic feature,
    // only have to do once for each feature of a single (x,y) site and then copy.
    int nxp = conn->xPatchSize();
    int nyp = conn->yPatchSize();
    int nfp = conn->fPatchSize();
    int num_weights = nxp*nyp*nfp;
    assert(zUnitCellSize(pre->getXScale(), getXScale())==1);
    assert(zUnitCellSize(pre->getYScale(), getYScale())==1);
    assert(conn->getNumDataPatches()==1);

    for (int kf=0; kf<nfp; kf++) {
        pvwdata_t * weight = conn->get_wDataHead(arborID, 0);
        pvdata_t sum = 0.0;
        for (int k=0; k<num_weights; k+=nfp) {
            pvwdata_t w = weight[k + kf]; // Assumes stride in features is 1.
            //TODO-CER-2014.4.4 - convert weights
            sum += w*w;
        }
        wnormsq[kf] = sum;
    }

    pvdata_t * gSynStart = GSyn[conn->getChannel()];

    int nx = getLayerLoc()->nx;
    int ny = getLayerLoc()->ny;
    int nxy = nx*ny;

    // TODO: Can I compute energyDropsBestFeature and minLocationsBestFeature without storing all the energyDrops and minimumLocations?

    for (int kxy=0; kxy<nxy; kxy++) {
        for (int kf=0; kf<nfp; kf++) {
            int k=kxy*nfp+kf; // Assumes stride in features is 1.
            minimumLocations[k] = gSynStart[k]/wnormsq[kf];
            energyDrops[k] = -gSynStart[k]*minimumLocations[k]/2;
        }
    }

    for (int kxy=0; kxy<nxy; kxy++) {
        minFeatures[kxy] = -1;
        energyDropsBestFeature[kxy] = FLT_MAX;
        int index0 = kxy*nfp; // assumes stride in features is 1.
        if (foundFeatures[kxy]>=0) {
            energyDropsBestFeature[kxy] = energyDrops[kxy*nfp+foundFeatures[kxy]];
            minFeatures[kxy] = foundFeatures[kxy];
        }
        else {
            for (int kf=0; kf<nfp; kf++) {
                if (energyDrops[index0+kf] < energyDropsBestFeature[kxy]) {
                    minFeatures[kxy] = kf;
                    energyDropsBestFeature[kxy] = energyDrops[index0+kf];
                }
            }
        }
    }

    for (int kxy=0; kxy<nxy; kxy++) {
        assert(minFeatures[kxy]>=0 && minFeatures[kxy]<nfp);
        int baseindex = kxy*nfp;
        minLocationsBestFeature[kxy] = minimumLocations[baseindex+minFeatures[kxy]];
    }

    bool mask[nxy];
    memset(mask, false, nxy*sizeof(*mask));

    pvdata_t smallestEnergyDrop;
    int minloc;

    while (constrainMinima(), minloc = filterMinEnergies(mask, &smallestEnergyDrop), smallestEnergyDrop<FLT_MAX) {
        assert(foundFeatures[minloc]<0 || foundFeatures[minloc]==minFeatures[minloc]);
        foundFeatures[minloc] = minFeatures[minloc];
        gSynSparse[minloc] += minLocationsBestFeature[minloc];
        if (gSynSparse[minloc] < 1e-4) {
            gSynSparse[minloc]=0;
            foundFeatures[minloc] = -1;
        }

        int minlocx = kxPos(minloc,nx,ny,1);
        int maskstartx = minlocx-(nxp-1);
        if (maskstartx<0) maskstartx=0;
        int maskstopx = minlocx+nxp;
        if (maskstopx>nx) maskstopx=nx;
        int minlocy = kyPos(minloc,nx,ny,1);
        int maskstarty = minlocy-(nyp-1);
        if (maskstarty<0) maskstarty=0;
        int maskstopy = minlocy+nyp;
        if (maskstopy>ny) maskstopy=ny;
        for (int ky=maskstarty; ky<maskstopy; ky++) {
            for (int kx=maskstartx; kx<maskstopx; kx++) {
                mask[kIndex(kx,ky,0,nx,ny,1)]=true;
            }
        }
    }


    recvsyn_timer->stop();

    updateReady = true;

    return 0;
}
Ejemplo n.º 7
0
int main(int argc, char* argv[])
{
   int status = 0;

   PV_Init* initObj = new PV_Init(&argc, &argv);
   initObj->initialize(argc, argv);

   // create the managing hypercolumn
   //
   HyPerCol* hc = new HyPerCol("test_constant_input column", argc, argv, initObj);

   // create the image
   //
   TestImage * image = new TestImage("test_constant_input image", hc);

   // create the layers
   //
   HyPerLayer * retina = new Retina("test_constant_input retina", hc);

   // create the connections
   //
   HyPerConn * conn = new HyPerConn("test_constant_input connection", hc);
   const int nxp = conn->xPatchSize();
   const int nyp = conn->yPatchSize();
   const PVLayerLoc * imageLoc = image->getLayerLoc();
   const PVLayerLoc * retinaLoc = image->getLayerLoc();
   const int nfPre = imageLoc->nf;
    
   float sumOfWeights = (float) (nxp*nyp*nfPre);
   if (imageLoc->nx > retinaLoc->nx) { sumOfWeights *= imageLoc->nx/retinaLoc->nx;}
   if (imageLoc->ny > retinaLoc->ny) { sumOfWeights *= imageLoc->ny/retinaLoc->ny;}
   
   hc->run();

   const int rank = hc->columnId();
#ifdef DEBUG_OUTPUT
   printf("[%d]: column: ", rank);
   printLoc(hc->getImageLoc());
   printf("[%d]: image : ", rank);
   printLoc(image->getImageLoc());
   printf("[%d]: retina: ", rank);
   printLoc(*retina->getLayerLoc());
   printf("[%d]: l1    : ", rank);
   printLoc(*l1->getLayerLoc());
#endif

   status = checkLoc(hc, image->getLayerLoc());
   if (status != PV_SUCCESS) {
      fprintf(stderr, "[%d]: test_constant_input: ERROR in image loc\n", rank);
      exit(status);
   }

   status = checkLoc(hc, retina->getLayerLoc());
   if (status != PV_SUCCESS) {
      fprintf(stderr, "[%d]: test_constant_input: ERROR in retina loc\n", rank);
      exit(status);
   }

   status = checkInput(image->getLayerLoc(), image->getActivity(), image->getConstantVal(), true);
   if (status != PV_SUCCESS) {
      fprintf(stderr, "[%d]: test_constant_input: ERROR in image data\n", rank);
      exit(status);
   }

   float retinaVal = sumOfWeights * image->getConstantVal();

   status = checkInput(retina->getLayerLoc(), retina->getActivity(), retinaVal, false);
   if (status != 0) {
      fprintf(stderr, "[%d]: test_constant_input: ERROR in retina data\n", rank);
      exit(status);
   }

   status = checkInput(retina->getLayerLoc(), retina->getLayerData(), retinaVal, true);
   if (status != 0) {
      fprintf(stderr, "[%d]: test_constant_input: ERROR in retina data\n", rank);
      exit(status);
   }

   delete hc;
   delete initObj;

   return status;
}
Ejemplo n.º 8
0
int main(int argc, char * argv[])
{
   PV_Init * initObj = new PV_Init(&argc, &argv, false/*allowUnrecognizedArguments*/);
   PV::HyPerCol * hc = new PV::HyPerCol("test_cocirc column", initObj);
   
   const char * preLayerName = "test_cocirc pre";
   const char * postLayerName = "test_cocirc post";
   
   PV::Example * pre = new PV::Example(preLayerName, hc);
   assert(pre);
   PV::Example * post = new PV::Example(postLayerName, hc);
   assert(post);
   PV::HyPerConn * cHyPer = new HyPerConn("test_cocirc hyperconn", hc);
   assert(cHyPer);
   PV::HyPerConn * cCocirc = new HyPerConn("test_cocirc cocircconn", hc);
   assert(cCocirc);
   
   PV::Example * pre2 = new PV::Example("test_cocirc pre 2", hc);
   assert(pre2);
   PV::Example * post2 = new PV::Example("test_cocirc post 2", hc);
   assert(post2);
   PV::HyPerConn * cHyPer1to2 = new HyPerConn("test_cocirc hyperconn 1 to 2", hc);
   assert(cHyPer1to2);
   PV::HyPerConn * cCocirc1to2 = new HyPerConn("test_cocirc cocircconn 1 to 2", hc);
   assert(cCocirc1to2);
   PV::HyPerConn * cHyPer2to1 = new HyPerConn("test_cocirc hyperconn 2 to 1", hc);
   assert(cHyPer2to1);
   PV::HyPerConn * cCocirc2to1 = new HyPerConn("test_cocirc cocircconn 2 to 1", hc);
   assert(cCocirc2to1);

   hc->ensureDirExists(hc->getOutputPath());
   
   for (int l=0; l<hc->numberOfLayers(); l++) {
      HyPerLayer * layer = hc->getLayer(l);
      int status = layer->communicateInitInfo();
      assert(status==PV_SUCCESS);
      layer->setInitInfoCommunicatedFlag();
   }   
   for (int c=0; c<hc->numberOfConnections(); c++) {
      BaseConnection * conn = hc->getConnection(c);
      int status = conn->communicateInitInfo();
      assert(status==PV_SUCCESS);
      conn->setInitInfoCommunicatedFlag();
   }
   
   for (int l=0; l<hc->numberOfLayers(); l++) {
      HyPerLayer * layer = hc->getLayer(l);
      int status = layer->allocateDataStructures();
      assert(status==PV_SUCCESS);
      layer->setDataStructuresAllocatedFlag();
   }
   
   for (int c=0; c<hc->numberOfConnections(); c++) {
      BaseConnection * conn = hc->getConnection(c);
      int status = conn->allocateDataStructures();
      assert(status==PV_SUCCESS);
      conn->setDataStructuresAllocatedFlag();
   }

   const int axonID = 0;
   int num_pre_extended = pre->clayer->numExtended;
   assert(num_pre_extended == cHyPer->getNumWeightPatches());

   int status = 0;
   for (int kPre = 0; kPre < num_pre_extended; kPre++) {
      status = check_cocirc_vs_hyper(cHyPer, cCocirc, kPre, axonID);
      assert(status==0);
      status = check_cocirc_vs_hyper(cHyPer1to2, cCocirc1to2, kPre, axonID);
      assert(status==0);
      status = check_cocirc_vs_hyper(cHyPer2to1, cCocirc2to1, kPre, axonID);
      assert(status==0);
   }

   delete hc;
   delete initObj;
   return 0;
}
Ejemplo n.º 9
0
int RescaleLayerTestProbe::outputState(double timed)
{
   int status = StatsProbe::outputState(timed);
   if (timed==getParent()->getStartTime()) { return PV_SUCCESS; }
   float tolerance = 2.0e-5f;
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   bool isRoot = icComm->commRank() == 0;

   RescaleLayer * targetRescaleLayer = dynamic_cast<RescaleLayer *>(getTargetLayer());
   assert(targetRescaleLayer);

   if (targetRescaleLayer->getRescaleMethod()==NULL) {
      fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" does not have rescaleMethod set.  Exiting.\n", name, targetRescaleLayer->getName());
      status = PV_FAILURE;
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "maxmin")) {
      if (!isRoot) { return PV_SUCCESS; }
      for(int b = 0; b < parent->getNBatch(); b++){
         float targetMax = targetRescaleLayer->getTargetMax();
         if (fabs(fMax[b]-targetMax)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has max %f instead of target max %f\n", getName(), targetRescaleLayer->getName(), fMax[b], targetMax);
            status = PV_FAILURE;
         }
         float targetMin = targetRescaleLayer->getTargetMin();
         if (fabs(fMin[b]-targetMin)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has min %f instead of target min %f\n", getName(), targetRescaleLayer->getName(), fMin[b], targetMin);
            status = PV_FAILURE;
         }

         // Now, check whether rescaled activity and original V are colinear.
         PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
         PVHalo const * rescaleHalo = &rescaleLoc->halo;
         int nk = rescaleLoc->nx * rescaleLoc->nf;
         int ny = rescaleLoc->ny;
         int rescaleStrideYExtended = (rescaleLoc->nx + rescaleHalo->lt + rescaleHalo->rt) * rescaleLoc->nf;
         int rescaleExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b * targetRescaleLayer->getNumExtended() + rescaleExtendedOffset;
         PVLayerLoc const * origLoc = targetRescaleLayer->getOriginalLayer()->getLayerLoc();
         PVHalo const * origHalo = &origLoc->halo;
         assert(nk == origLoc->nx * origLoc->nf);
         assert(ny == origLoc->ny);
         int origStrideYExtended = (origLoc->nx + origHalo->lt + origHalo->rt) * origLoc->nf;
         int origExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * origData = targetRescaleLayer->getOriginalLayer()->getLayerData() + b * targetRescaleLayer->getOriginalLayer()->getNumExtended() + origExtendedOffset;

         bool iscolinear = colinear(nk, ny, origStrideYExtended, rescaleStrideYExtended, origData, rescaledData, tolerance, NULL, NULL, NULL);
         if (!iscolinear) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": Rescale layer \"%s\" data is not a linear rescaling of original membrane potential.\n", getName(), targetRescaleLayer->getName());
            status = PV_FAILURE;
         }
      }
   }
   //l2 norm with a patch size of 1 (default) should be the same as rescaling with meanstd with target mean 0 and std of 1/sqrt(patchsize)
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "meanstd") || !strcmp(targetRescaleLayer->getRescaleMethod(), "l2")) {
      if (!isRoot) { return PV_SUCCESS; }
      for(int b = 0; b < parent->getNBatch(); b++){
         float targetMean, targetStd;
         if(!strcmp(targetRescaleLayer->getRescaleMethod(), "meanstd")){
            targetMean = targetRescaleLayer->getTargetMean();
            targetStd = targetRescaleLayer->getTargetStd();
         }
         else{
            targetMean = 0;
            targetStd = 1/sqrt((float)targetRescaleLayer->getL2PatchSize());
         }

         if (fabs(avg[b]-targetMean)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has mean %f instead of target mean %f\n", getName(), targetRescaleLayer->getName(), (double)avg[b], targetMean);
            status = PV_FAILURE;
         }
         if (sigma[b]>tolerance && fabs(sigma[b]-targetStd)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has std.dev. %f instead of target std.dev. %f\n", getName(), targetRescaleLayer->getName(), (double)sigma[b], targetStd);
            status = PV_FAILURE;
         }

         // Now, check whether rescaled activity and original V are colinear.
         PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
         PVHalo const * rescaleHalo = &rescaleLoc->halo;
         int nk = rescaleLoc->nx * rescaleLoc->nf;
         int ny = rescaleLoc->ny;
         int rescaleStrideYExtended = (rescaleLoc->nx + rescaleHalo->lt + rescaleHalo->rt) * rescaleLoc->nf;
         int rescaleExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b*targetRescaleLayer->getNumExtended() + rescaleExtendedOffset;
         PVLayerLoc const * origLoc = targetRescaleLayer->getOriginalLayer()->getLayerLoc();
         PVHalo const * origHalo = &origLoc->halo;
         assert(nk == origLoc->nx * origLoc->nf);
         assert(ny == origLoc->ny);
         int origStrideYExtended = (origLoc->nx + origHalo->lt + origHalo->rt) * origLoc->nf;
         int origExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * origData = targetRescaleLayer->getOriginalLayer()->getLayerData() + b*targetRescaleLayer->getOriginalLayer()->getNumExtended() + origExtendedOffset;

         bool iscolinear = colinear(nk, ny, origStrideYExtended, rescaleStrideYExtended, origData, rescaledData, tolerance, NULL, NULL, NULL);
         if (!iscolinear) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": Rescale layer \"%s\" data is not a linear rescaling of original membrane potential.\n", getName(), targetRescaleLayer->getName());
            status = PV_FAILURE;
         }
      }
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "pointmeanstd")) {
      PVLayerLoc const * loc = targetRescaleLayer->getLayerLoc();
      int nf = loc->nf;
      if (nf<2) { return PV_SUCCESS; }
      PVHalo const * halo = &loc->halo;
      float targetMean = targetRescaleLayer->getTargetMean();
      float targetStd = targetRescaleLayer->getTargetStd();
      int numNeurons = targetRescaleLayer->getNumNeurons();
      for(int b = 0; b < parent->getNBatch(); b++){
         pvpotentialdata_t const * originalData = targetRescaleLayer->getV() + b*targetRescaleLayer->getNumNeurons();
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b*targetRescaleLayer->getNumExtended();
         for (int k=0; k<numNeurons; k+=nf) {
            int kExtended = kIndexExtended(k, loc->nx, loc->ny, loc->nf, halo->lt, halo->rt, halo->dn, halo->up);
            double pointmean = 0.0;
            for (int f=0; f<nf; f++) {
               pointmean += rescaledData[kExtended+f];
            }
            pointmean /= nf;
            double pointstd = 0.0;
            for (int f=0; f<nf; f++) {
               double d = rescaledData[kExtended+f]-pointmean;
               pointstd += d*d;
            }
            pointstd /= nf;
            pointstd = sqrt(pointstd);
            if (fabs(pointmean-targetMean)>tolerance) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, has mean %f instead of target mean %f\n",
                     getName(), targetRescaleLayer->getName(), getParent()->columnId(), k, pointmean, targetMean);
               status = PV_FAILURE;
            }
            if (pointstd>tolerance && fabs(pointstd-targetStd)>tolerance) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, has std.dev. %f instead of target std.dev. %f\n",
                     getName(), targetRescaleLayer->getName(), getParent()->columnId(), k, pointstd, targetStd);
               status = PV_FAILURE;
            }
            bool iscolinear = colinear(nf, 1, 0, 0, &originalData[k], &rescaledData[kExtended], tolerance, NULL, NULL, NULL);
            if (!iscolinear) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, is not a linear rescaling.\n",
                     getName(), targetRescaleLayer->getName(), parent->columnId(), k);
               status = PV_FAILURE;
            }
         }
      }
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "zerotonegative")) {
      int numNeurons = targetRescaleLayer->getNumNeurons();
      assert(numNeurons == targetRescaleLayer->getOriginalLayer()->getNumNeurons());
      PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
      PVHalo const * rescaleHalo = &rescaleLoc->halo;
      int nf = rescaleLoc->nf;
      HyPerLayer * originalLayer = targetRescaleLayer->getOriginalLayer();
      PVLayerLoc const * origLoc = originalLayer->getLayerLoc();
      PVHalo const * origHalo = &origLoc->halo;
      assert(origLoc->nf == nf);

      for(int b = 0; b < parent->getNBatch(); b++){
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b * targetRescaleLayer->getNumExtended();
         pvadata_t const * originalData = originalLayer->getLayerData() + b * originalLayer->getNumExtended();
         for (int k=0; k<numNeurons; k++) {
            int rescale_kExtended = kIndexExtended(k, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
            int orig_kExtended = kIndexExtended(k, origLoc->nx, origLoc->ny, origLoc->nf, origHalo->lt, origHalo->rt, origHalo->dn, origHalo->up);
            pvadata_t observedval = rescaledData[rescale_kExtended];
            pvpotentialdata_t correctval = originalData[orig_kExtended] ? observedval : -1.0;
            if (observedval != correctval) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", rank %d, restricted neuron %d has value %f instead of expected %f\n.",
                     this->getName(), targetRescaleLayer->getName(), parent->columnId(), k, observedval, correctval);
               status = PV_FAILURE;
            }
         }
      }
   }
   else {
      assert(0);  // All allowable rescaleMethod values are handled above.
   }
   if (status == PV_FAILURE) {
      exit(EXIT_FAILURE);
   }
   return status;
}