// Run numTrials simulations with numFish fish.
// For each simulation, use r for the ratio of orientation to attraction.
// Return the mean elongation value (computed across simulations)
// the std. dev. of the elongation values,
// the mean polarization, and the std. dev. of polarization values
int runSimulations(int numFish, int numTrials, float r,
                   float *mean_elongation, float *mean_polarization,
                   float *std_elongation, float *std_polarization ) {

  int numFrames = 3000; // assume 3000 frames for each simulation
  float *elo=(float*)malloc(sizeof(float)*numTrials);
  float *pol=(float*)malloc(sizeof(float)*numTrials);
  //zero elo and pol out just in case yo
  memset(elo,0,sizeof(float)*numTrials);
  memset(pol,0,sizeof(float)*numTrials);
  int i;
  params par[TH];
  pthread_t th[TH];
  //data not provided? run random trials:
  //paralize here:
  int chunk, lastchunk=0;
  int threads=TH;
  //extension 1-see readme
  //if num trials< threads
  if(numTrials<TH){
	  chunk=1;
	  threads=numTrials;
  }
  else if(numTrials % TH !=0){
	 //example: numtrials=11, th=8,
	 //chunk=2, threads=6, lastchunk=1
	 chunk=ceil((double)numTrials/(double)(TH-1));
	 threads=ceil((double)numTrials/(double)chunk);
	 lastchunk=numTrials-(threads-1)*chunk;
  }
  else chunk=numTrials/TH;
  for(i=0;i<threads;i++){
	 par[i].elo=elo;
	 par[i].pol=pol;
	 par[i].numFish=numFish;
	 par[i].numFrames=numFrames;
	 par[i].r=r;
	 par[i].start=i*chunk;
	 if(i==threads-1)
		 par[i].end=lastchunk==0 ? (i+1)*chunk : (i*chunk)+lastchunk;
	 else
		 par[i].end=(i+1)*chunk;
	 pthread_create(&th[i],NULL,runRandSimWithParams,&par[i]);
  }
  for(i=0;i<threads;i++){
	 pthread_join(th[i],NULL);
  }
  *mean_elongation=mean(elo,numTrials);
  *mean_polarization=mean(pol,numTrials);
  *std_elongation=std(elo,numTrials);
  *std_polarization=std(pol,numTrials);
  free(elo);
  free(pol);
  return 0;
} // end runSimulations
void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
  assert_different_registers(Rmark, Roop, Rbox, Rscratch);

  Label done, cas_failed, slow_int;

  // The following move must be the first instruction of emitted since debug
  // information may be generated for it.
  // Load object header.
  ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop);

  verify_oop(Roop);

  // Save object being locked into the BasicObjectLock...
  std(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);

  if (UseBiasedLocking) {
    biased_locking_enter(CCR0, Roop, Rmark, Rscratch, R0, done, &slow_int);
  }

  // ... and mark it unlocked.
  ori(Rmark, Rmark, markOopDesc::unlocked_value);

  // Save unlocked object header into the displaced header location on the stack.
  std(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox);

  // Compare object markOop with Rmark and if equal exchange Rscratch with object markOop.
  assert(oopDesc::mark_offset_in_bytes() == 0, "cas must take a zero displacement");
  cmpxchgd(/*flag=*/CCR0,
           /*current_value=*/Rscratch,
           /*compare_value=*/Rmark,
           /*exchange_value=*/Rbox,
           /*where=*/Roop/*+0==mark_offset_in_bytes*/,
           MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
           MacroAssembler::cmpxchgx_hint_acquire_lock(),
           noreg,
           &cas_failed,
           /*check without membar and ldarx first*/true);
  // If compare/exchange succeeded we found an unlocked object and we now have locked it
  // hence we are done.
  b(done);

  bind(slow_int);
  b(slow_case); // far

  bind(cas_failed);
  // We did not find an unlocked object so see if this is a recursive case.
  sub(Rscratch, Rscratch, R1_SP);
  load_const_optimized(R0, (~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place));
  and_(R0/*==0?*/, Rscratch, R0);
  std(R0/*==0, perhaps*/, BasicLock::displaced_header_offset_in_bytes(), Rbox);
  bne(CCR0, slow_int);

  bind(done);
}
inline void MacroAssembler::st_long( Register d, Register s1, RegisterOrConstant s2 ) {
#ifdef _LP64
  stx(d, s1, s2);
#else
  std(d, s1, s2);
#endif
}
inline void MacroAssembler::st_long( Register d, const Address& a, int offset ) {
#ifdef _LP64
  stx(d, a, offset);
#else
  std(d, a, offset);
#endif
}
Float HierarchicalClustering::computeClusterVariance( const ClusterInfo &cluster, const MatrixFloat &data ){
    
    VectorFloat mean(N,0);
    VectorFloat std(N,0);
    
    //Compute the mean
    UINT numSamples = cluster.getNumSamplesInCluster();
    for(UINT j=0; j<N; j++){
        for(UINT i=0; i<numSamples; i++){
            UINT index = cluster[i];
            mean[j] += data[ index ][j];
        }
        mean[j] /= Float( numSamples );
    }
    
    //Compute the std dev
    for(UINT j=0; j<N; j++){
        for(UINT i=0; i<numSamples; i++){
            std[j] += grt_sqr( data[ cluster[i] ][j] - mean[j] );
        }
        std[j] = grt_sqrt( std[j] / Float( numSamples-1 ) );
    }
    
    Float variance = 0;
    for(UINT j=0; j<N; j++){
        variance += std[j];
    }
    return variance/N;
}
示例#6
0
文件: sa.c 项目: drigz/5R1
int main(int argc, char **argv)
{
    if (argc != 8)
    {
        printf("needs 7 args\n");
        return 1;
    }

    int n_iters = atoi(argv[1]);

    if (strcmp(argv[2], "uniform") == 0)
        step_method = uniform;
    else if (strcmp(argv[2], "gaussian") == 0)
        step_method = gaussian;
    else if (strcmp(argv[2], "parks") == 0)
        step_method = parks;
    else
    {
        printf("unknown step method\n");
        return 1;
    }

    init_step_size = atof(argv[3]);
    penalty_weight = atof(argv[4]);
    
    if (strcmp(argv[5], "kirkpatrick") == 0)
        initial_temp_method = kirkpatrick;
    else if (strcmp(argv[5], "white") == 0)
        initial_temp_method = white;
    else
    {
        initial_temp_method = constant;
        initial_temp = atof(argv[5]);
    }

    temp_length = atoi(argv[6]);
    
    if (strcmp(argv[7], "huang") == 0)
        temp_decay_method = huang;
    else
    {
        temp_decay_method = exponential;
        temp_decay = atof(argv[7]);
    }

    real results[n_iters];

    for (int i=0; i<n_iters; i++)
    {
        results[i] = sa(i);
        //printf("%g\n", results[i]);
    }

    real m = mean(results, n_iters);
    real s = std(results, n_iters);

    printf("%g %g\n", m, s);

    return 0;
}
inline void MacroAssembler::store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
  if (UseCompressedOops) {
    Register compressedOop = encode_heap_oop_not_null((tmp != noreg) ? tmp : d, d);
    stw(compressedOop, offs, s1);
  } else {
    std(d, offs, s1);
  }
}
void test_std() {
  printf("\nTesting Std. Dev.\n");
  int N = 1000;
  float *array = createAscendingArray(N);
  float s = std(array,N);
  printf("std of (0..%d) is %f and should be 288.819458\n",N-1,s);
  free(array);
}
// Run numTrials simulations with numFish fish.
// For each simulation, use r for the ratio of orientation to attraction.
// Return the mean elongation value (computed across simulations)
// the std. dev. of the elongation values,
// the mean polarization, and the std. dev. of polarization values
int runSimulations(int numFish, int numTrials, float r,
        float *mean_elongation, float *mean_polarization,
        float *std_elongation, float *std_polarization ,float attr) {

    int numtasks, rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

    int numFrames = 3000; // assume 3000 frames for each simulation
    float *elo,*pol;
    if(rank==0){
        elo=(float*)malloc(sizeof(float)*numTrials); 
        pol=(float*)malloc(sizeof(float)*numTrials); 
    }
    float *eloTrd=(float*)malloc(sizeof(float)*(numTrials/numtasks));
    float *polTrd=(float*)malloc(sizeof(float)*(numTrials/numtasks));
    int i;
    //data not provided? run random trials:
    for(i=0;i<numTrials/numtasks;i++){
        runRandomSimulationWithStatistics(numFish,r,numFrames,(eloTrd+i),
                (polTrd+i),attr); 
    }
    MPI_Barrier(MPI_COMM_WORLD);
    //gather:
    MPI_Gather(eloTrd, numTrials/numtasks, MPI_FLOAT,
             elo, numTrials/numtasks, MPI_FLOAT,
            0, MPI_COMM_WORLD);
    MPI_Gather(polTrd, numTrials/numtasks, MPI_FLOAT,
             pol, numTrials/numtasks, MPI_FLOAT,
            0, MPI_COMM_WORLD);
    //rank0:
    if(rank==0){
        *mean_elongation=mean(elo,numTrials);
        *mean_polarization=mean(pol,numTrials);
        *std_elongation=std(elo,numTrials);
        *std_polarization=std(pol,numTrials);
        free(elo);
        free(pol);
    }
    free(eloTrd);
    free(polTrd);
} // end runSimulations
示例#10
0
文件: math.c 项目: liuyang1/test
bool unit_func(double (*f)(double), double (*std)(double),
               const char *funcname, double x) {
    double r = f(x);
    double e = std(x);
    double d = r - e;
    bool ret = fabs(d) < 0.0001;
    if (!ret) {
        printf("%s_p(%f) = %f %s(%f) = %f, diff=%f\n", funcname, x, r, funcname, x, e, d);
    }
    return ret;
}
示例#11
0
void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
  // Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry.
  const Register return_pc = R20;
  mflr(return_pc);

  // Make sure there is enough stack space for this method's activation.
  assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
  generate_stack_overflow_check(bang_size_in_bytes);

  std(return_pc, _abi(lr), R1_SP);     // SP->lr = return_pc
  push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
}
示例#12
0
 Apply *stdFunc(const LocationRange &loc, const String &name, AST *a, AST *b)
 {
     return make<Apply>(
         loc,
         EF,
         make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
         EF,
         Apply::Args{{a, EF}, {b, EF}},
         false,  // trailingComma
         EF,
         EF,
         true  // tailstrict
     );
 }
示例#13
0
 Apply *stdFunc(const String &name, AST *v)
 {
     return make<Apply>(
         v->location,
         EF,
         make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
         EF,
         Apply::Args{{v, EF}},
         false,  // trailingComma
         EF,
         EF,
         true  // tailstrict
     );
 }
示例#14
0
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
  assert_different_registers(obj, klass, len, t1, t2);
  if (UseBiasedLocking && !len->is_valid()) {
    ld(t1, in_bytes(Klass::prototype_header_offset()), klass);
  } else {
    load_const_optimized(t1, (intx)markOopDesc::prototype());
  }
  std(t1, oopDesc::mark_offset_in_bytes(), obj);
  store_klass(obj, klass);
  if (len->is_valid()) {
    stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
  } else if (UseCompressedClassPointers) {
    // Otherwise length is in the class gap.
    store_klass_gap(obj);
  }
}
void test_std() {
    int i, n;
    double *vals;
    double res;

    n = 10;
    vals = (double*)malloc(n*sizeof(double));

    for (i = 0; i < n; i++) {
    	vals[i] = i+1;
    }

    res = std(vals, n);
    printf("STD: Expected %g got %g\n", 2.8722813232690143, res);

    /* clean up */
    free(vals);
}
void SliceMacroParticle::Write(std::ostream& os) const
{
	PScoord i,j;

	WR_MP(q);
	WR_MP(ct());
	WR_MP(dp());
	for(i=0; i<4; i++)
	{
		WR_MP(mean(i));
	}
	for(i=0; i<4; i++)
	{
		WR_MP(std(i));
	}
	for(i=1; i<4; i++)
	{
		for(j=0; j<i; j++)
		{
			WR_MP(sig(i,j));
		}
	}
	os<<'\n';
}
示例#17
0
/*     _ub _extra */
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
static struct __sFILEX usual_extra[FOPEN_MAX - 3];
static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };

static struct __sFILEX __sFX[3];

/*
 * We can't make this 'static' until 6.0-current due to binary
 * compatibility concerns.  This also means we cannot change the
 * sizeof(FILE) until that time either and must continue to use the
 * __sFILEX stuff to add to FILE.
 */
FILE __sF[3] = {
    std(__SRD, STDIN_FILENO),
    std(__SWR, STDOUT_FILENO),
    std(__SWR | __SNBF, STDERR_FILENO)
};

/*
 * The following kludge is done to ensure enough binary compatibility
 * with future versions of libc.  Or rather it allows us to work with
 * libraries that have been built with a newer libc that defines these
 * symbols and expects libc to provide them.  We only have need to support
 * i386 because it is the only "old" system we have deployed.
 */
FILE* __stdinp = &__sF[0];
FILE* __stdoutp = &__sF[1];
FILE* __stderrp = &__sF[2];
示例#18
0
/*
* Parameters: 
* SNPs [nIndividuals by nSNPs]:
*                       Matrix stored in column-major order. 
*                       This will hold the result.
*                       NaNs will be set to 0.0 in the result.
*/
void SUFFIX(ImputeAndZeroMeanSNPs)( 
	REAL *SNPs, 
	const size_t nIndividuals, 
	const size_t nSNPs, 
	const bool betaNotUnitVariance,
	const REAL betaA,
	const REAL betaB
	)
{
	bool seenSNC = false; //Keep track of this so that only one warning message is reported
#ifdef ORDERF

	for ( size_t iSnp = 0; iSnp < nSNPs; ++iSnp )
	{

		REAL n_observed = 0.0;
		REAL sum_s  = 0.0;      //the sum of a SNP over all observed individuals
		REAL sum2_s = 0.0;      //the sum of the squares of the SNP over all observed individuals

		size_t end = nIndividuals;
		size_t delta = 1;
		for( size_t ind = 0; ind < end; ind+=delta )
		{
			if (SNPs[ind] == SNPs[ind])
			{
				//check for not NaN
				sum_s += SNPs[ ind ];
				sum2_s+= SNPs[ ind ] * SNPs[ ind ];
				++n_observed;
			}
		}

		if ( n_observed < 1.0 )
		{
			printf( "No individual observed for the SNP.\n");
		}

		REAL mean_s  = sum_s  / n_observed;    //compute the mean over observed individuals for the current SNP
		REAL mean2_s = sum2_s / n_observed;    //compute the mean of the squared SNP

		//When beta standardization is being done, check that data is 0,1,2
		if (betaNotUnitVariance && sum_s <= (REAL)0.0)
		{
			REAL freqT = sum_s/n_observed;
			fprintf(stderr, "Observed SNP freq is %.2f. for a SNPs[:][%i]\n", freqT, iSnp );
			exit(1);
		}


		//The SNP frequency
		REAL freq = (sum_s) / (n_observed * (REAL)2.0);   //compute snp-freq as in the Visscher Height paper (Nat Gen, Yang et al 2010).

		if ((freq != freq) || betaNotUnitVariance && ((freq >= (REAL)1.0) || (freq <= (REAL)0.0)))
		{
			if (!seenSNC)
			{
				seenSNC = true;
				fprintf(stderr, "Illegal SNP frequency: %.2f for SNPs[:][%i]\n", freq, iSnp);
			}
		}


		REAL variance = mean2_s-mean_s * mean_s;        //By the Cauchy Shwartz inequality this should always be positive
		REAL std = sqrt( variance );                    //The SNP frequency

		bool isSNC = false;
		if ( (std != std) || (std <= (REAL)0.0) )
		{
			// a std == 0.0 means all SNPs have the same value (no variation or Single Nucleotide Constant (SNC))
			//   however ALL SNCs should have been removed in previous filtering steps
			//   This test now prevents a divide by zero error below
			std = 1.0;
			isSNC = true;
			if (!seenSNC)
			{
				seenSNC = true;
				fprintf(stderr, "std=.%2f has illegal value for SNPs[:][%i]\n", std, iSnp );
			}

		}

		if (betaNotUnitVariance && freq > .5)
		{
			freq = 1.0 - freq;
		}

		for( size_t ind = 0; ind < end; ind+=delta )
		{
			//check for NaN
			if ( (SNPs[ ind ]!=SNPs[ ind ]) || isSNC)
			{
				SNPs[ ind ] = 0.0;
			}
			else
			{
				SNPs[ ind ] -= mean_s;     //subtract the mean from the data
				if (betaNotUnitVariance )
				{
					REAL rT = SUFFIX(BetaPdf)( freq, betaA, betaB );
					//fprintf(stderr, "BetaPdf(%f,%f,%f)=%f\n",  freq, betaA, betaB, rT);
					SNPs[ ind ] *= rT;
				}
				else
				{
					SNPs[ ind ] /= std;        //unit variance as well
				}

			}
		}

		SNPs += nIndividuals;
	}

#else //Order C


	// Make one pass through the data (by individual, because that is how it is laid out), collecting statistics
	std::vector<REAL> n_observed(nSNPs); //                                                C++ inits to 0's
	std::vector<REAL> sum_s(nSNPs);      //the sum of a SNP over all observed individuals. C++ inits to 0's
	std::vector<REAL> sum2_s(nSNPs);     //the sum of the squares of the SNP over all observed individuals.     C++ inits to 0's

	for( size_t ind = 0; ind < nIndividuals; ++ind)
	{
		size_t rowStart = ind * nSNPs;
		for ( size_t iSnp = 0; iSnp < nSNPs; ++iSnp )
		{
			REAL value = SNPs[rowStart+iSnp];
			if ( value == value )
			{
				sum_s[iSnp] += value;
				sum2_s[iSnp] += value * value;
				++n_observed[iSnp];
			}
		}
	}


	std::vector<REAL> mean_s(nSNPs);  //compute the mean over observed individuals for the current SNP
	std::vector<REAL> mean2_s(nSNPs); //compute the mean of the squared SNP
	std::vector<REAL> std(nSNPs); //the standard deviation
	std::vector<REAL> freq(nSNPs); //The SNP frequency
	std::vector<bool> isSNC(nSNPs); // Is this a SNC (C++ inits to false)

	for ( size_t iSnp = 0; iSnp < nSNPs; ++iSnp )
	{
		if ( n_observed[iSnp] < 1.0 )
		{
			printf( "No individual observed for the SNP.\n");
		}

		mean_s[iSnp]  = sum_s[iSnp]  / n_observed[iSnp];    //compute the mean over observed individuals for the current SNP
		mean2_s[iSnp] = sum2_s[iSnp] / n_observed[iSnp];    //compute the mean of the squared SNP

		//When beta standardization is being done, check that data is 0,1,2
		if (betaNotUnitVariance && sum_s[iSnp] <= (REAL)0.0)
		{
			REAL freqT = sum_s[iSnp]/n_observed[iSnp];
			fprintf(stderr, "Observed SNP freq is %.2f. for a SNPs[:][%i]\n", freqT, iSnp );
			exit(1);
		}

		freq[iSnp] = (sum_s[iSnp]) / (n_observed[iSnp] * (REAL)2.0);   //compute snp-freq[iSnp] as in the Visscher Height paper (Nat Gen, Yang et al 2010).

		if ((freq[iSnp] != freq[iSnp]) || betaNotUnitVariance && ((freq[iSnp] >= (REAL)1.0) || (freq[iSnp] <= (REAL)0.0)))
		{
			if (!seenSNC)
			{
				seenSNC = true;
				fprintf(stderr, "Illegal SNP frequency: %.2f for SNPs[:][%i]\n", freq[iSnp], iSnp);
			}
		}


		REAL variance = mean2_s[iSnp]-mean_s[iSnp] * mean_s[iSnp];        //By the Cauchy Shwartz inequality this should always be positive
		std[iSnp] = sqrt( variance );

		if ( (std[iSnp] != std[iSnp]) || (std[iSnp] <= (REAL)0.0) )
		{
			// a std == 0.0 means all SNPs have the same value (no variation or Single Nucleotide Constant (SNC))
			//   however ALL SNCs should have been removed in previous filtering steps
			//   This test now prevents a divide by zero error below
			std[iSnp] = 1.0;
			isSNC[iSnp] = true;
			if (!seenSNC)
			{
				seenSNC = true;
				fprintf(stderr, "std=.%2f has illegal value for SNPs[:][%i]\n", std[iSnp], iSnp );
			}
		}

		if (betaNotUnitVariance && freq[iSnp] > .5)
		{
			freq[iSnp] = 1.0 - freq[iSnp];
		}
	}

	for( size_t ind = 0; ind < nIndividuals; ++ind)
	{
		size_t rowStart = ind * nSNPs;
		for ( size_t iSnp = 0; iSnp < nSNPs; ++iSnp )
		{
			REAL value = SNPs[rowStart+iSnp];
			//check for NaN
			if ( (value != value) || isSNC[iSnp])
			{
				value = 0.0;
			}
			else
			{
				value -= mean_s[iSnp];     //subtract the mean from the data
				if (betaNotUnitVariance )
				{
					REAL rT = SUFFIX(BetaPdf)( freq[iSnp], betaA, betaB );
					//fprintf(stderr, "BetaPdf(%f,%f,%f)=%f\n",  freq, betaA, betaB, rT);
					value *= rT;
				}
				else
				{
					value /= std[iSnp];        //unit variance as well
				}
			}
			SNPs[rowStart+iSnp] = value;
		}
	}
#endif
}
示例#19
0
 double std(Mask* m){ return std(0,m_width,0,m_height,m); }
示例#20
0
 double std(){ return std(0,m_width,0,m_height); }
示例#21
0
    void desugar(AST *&ast_, unsigned obj_level)
    {
        if (auto *ast = dynamic_cast<Apply*>(ast_)) {
            desugar(ast->target, obj_level);
            for (Apply::Arg &arg : ast->args)
                desugar(arg.expr, obj_level);

        } else if (auto *ast = dynamic_cast<ApplyBrace*>(ast_)) {
            desugar(ast->left, obj_level);
            desugar(ast->right, obj_level);
            ast_ = alloc->make<Binary>(ast->location, ast->openFodder,
                                       ast->left, EF, BOP_PLUS, ast->right);

        } else if (auto *ast = dynamic_cast<Array*>(ast_)) {
            for (auto &el : ast->elements)
                desugar(el.expr, obj_level);

        } else if (auto *ast = dynamic_cast<ArrayComprehension*>(ast_)) {
            for (ComprehensionSpec &spec : ast->specs)
                desugar(spec.expr, obj_level);
            desugar(ast->body, obj_level + 1);

            int n = ast->specs.size();
            AST *zero = make<LiteralNumber>(E, EF, "0.0");
            AST *one = make<LiteralNumber>(E, EF, "1.0");
            auto *_r = id(U"$r");
            auto *_l = id(U"$l");
            std::vector<const Identifier*> _i(n);
            for (int i = 0; i < n ; ++i) {
                StringStream ss;
                ss << U"$i_" << i;
                _i[i] = id(ss.str());
            }
            std::vector<const Identifier*> _aux(n);
            for (int i = 0; i < n ; ++i) {
                StringStream ss;
                ss << U"$aux_" << i;
                _aux[i] = id(ss.str());
            }

            // Build it from the inside out.  We keep wrapping 'in' with more ASTs.
            assert(ast->specs[0].kind == ComprehensionSpec::FOR);

            int last_for = n - 1;
            while (ast->specs[last_for].kind != ComprehensionSpec::FOR)
                last_for--;
            // $aux_{last_for}($i_{last_for} + 1, $r + [body])
            AST *in = make<Apply>(
                ast->body->location,
                EF,
                var(_aux[last_for]),
                EF,
                Apply::Args {
                    { make<Binary>(E, EF, var(_i[last_for]), EF, BOP_PLUS, one), EF},
                    { make<Binary>(E, EF, var(_r), EF, BOP_PLUS, singleton(ast->body)), EF}
                },
                false,  // trailingComma
                EF,
                EF,
                true  // tailstrict
            );
            for (int i = n - 1; i >= 0 ; --i) {
                const ComprehensionSpec &spec = ast->specs[i];
                AST *out;
                if (i > 0) {
                    int prev_for = i - 1;
                    while (ast->specs[prev_for].kind != ComprehensionSpec::FOR)
                        prev_for--;

                    // aux_{prev_for}($i_{prev_for} + 1, $r)
                    out = make<Apply>(  // False branch.
                        E,
                        EF,
                        var(_aux[prev_for]),
                        EF,
                        Apply::Args {
                            { make<Binary>(E, EF, var(_i[prev_for]), EF, BOP_PLUS, one), EF, },
                            { var(_r), EF, }
                        },
                        false, // trailingComma
                        EF,
                        EF,
                        true  // tailstrict
                    );
                } else {
                    out = var(_r);
                }
                switch (spec.kind) {
                    case ComprehensionSpec::IF: {
                        /*
                            if [[[...cond...]]] then
                                [[[...in...]]]
                            else
                                [[[...out...]]]
                        */
                        in = make<Conditional>(
                            ast->location,
                            EF,
                            spec.expr,
                            EF,
                            in,  // True branch.
                            EF,
                            out);  // False branch.
                    } break;
                    case ComprehensionSpec::FOR: {
                        /*
                            local $l = [[[...array...]]]
                                  aux_{i}(i_{i}, r) =
                                if i_{i} >= std.length($l) then
                                    [[[...out...]]]
                                else
                                    local [[[...var...]]] = $l[i_{i}];
                                    [[[...in...]]];`
                            if std.type($l) != "array" then
                                error "In comprehension, can only iterate over array.."
                            else
                                aux_{i}(0, r) tailstrict;
                        */
                        in = make<Local>(
                            ast->location,
                            EF,
                            Local::Binds {
                                bind(_l, spec.expr),  // Need to check expr is an array
                                bind(_aux[i], make<Function>(
                                    ast->location,
                                    EF,
                                    EF,
                                    std::vector<Param>{Param(EF, _i[i], EF), Param(EF, _r, EF)},
                                    false,  // trailingComma
                                    EF,
                                    make<Conditional>(
                                        ast->location,
                                        EF,
                                        make<Binary>(
                                            E, EF, var(_i[i]), EF, BOP_GREATER_EQ, length(var(_l))),
                                        EF,
                                        out,
                                        EF,
                                        make<Local>(
                                            ast->location,
                                            EF,
                                            singleBind(
                                                spec.var,
                                                make<Index>(E, EF, var(_l), EF, false, var(_i[i]),
                                                            EF, nullptr, EF, nullptr, EF)
                                            ),
                                            in)
                                    )
                                ))},
                            make<Conditional>(
                                ast->location,
                                EF,
                                equals(ast->location, type(var(_l)), str(U"array")),
                                EF,
                                make<Apply>(
                                    E,
                                    EF,
                                    var(_aux[i]),
                                    EF,
                                    Apply::Args {
                                        {zero, EF},
                                        {
                                            i == 0
                                            ? make<Array>(E, EF, Array::Elements{}, false, EF)
                                            : static_cast<AST*>(var(_r)),
                                            EF,
                                        }
                                    },
                                    false,  // trailingComma
                                    EF,
                                    EF,
                                    true),  // tailstrict
                                EF,
                                error(ast->location,
                                      U"In comprehension, can only iterate over array.")));
                    } break;
                }
            }

            ast_ = in;

        } else if (auto *ast = dynamic_cast<Assert*>(ast_)) {
            desugar(ast->cond, obj_level);
            if (ast->message == nullptr) {
                ast->message = str(U"Assertion failed.");
            }
            desugar(ast->message, obj_level);
            desugar(ast->rest, obj_level);

            // if cond then rest else error msg
            AST *branch_false = alloc->make<Error>(ast->location, EF, ast->message);
            ast_ = alloc->make<Conditional>(ast->location, ast->openFodder,
                                            ast->cond, EF, ast->rest, EF, branch_false);

        } else if (auto *ast = dynamic_cast<Binary*>(ast_)) {
            desugar(ast->left, obj_level);
            desugar(ast->right, obj_level);

            bool invert = false;

            switch (ast->op) {
                case BOP_PERCENT: {
                    AST *f_mod = alloc->make<Index>(E, EF, std(), EF, false, str(U"mod"), EF,
                                                    nullptr, EF, nullptr, EF);
                    Apply::Args args = {{ast->left, EF}, {ast->right, EF}};
                    ast_ = alloc->make<Apply>(ast->location, ast->openFodder, f_mod, EF, args,
                                              false, EF, EF, false);
                } break;

                case BOP_MANIFEST_UNEQUAL:
                invert = true;
                case BOP_MANIFEST_EQUAL: {
                    ast_ = equals(ast->location, ast->left, ast->right);
                    if (invert)
                        ast_ = alloc->make<Unary>(ast->location, ast->openFodder, UOP_NOT, ast_);
                }
                break;

                default:;
                // Otherwise don't change it.
            }

        } else if (dynamic_cast<const BuiltinFunction*>(ast_)) {
            // Nothing to do.

        } else if (auto *ast = dynamic_cast<Conditional*>(ast_)) {
            desugar(ast->cond, obj_level);
            desugar(ast->branchTrue, obj_level);
            if (ast->branchFalse == nullptr)
                ast->branchFalse = alloc->make<LiteralNull>(LocationRange(), EF);
            desugar(ast->branchFalse, obj_level);

        } else if (auto *ast = dynamic_cast<Dollar*>(ast_)) {
            if (obj_level == 0) {
                throw StaticError(ast->location, "No top-level object found.");
            }
            ast_ = alloc->make<Var>(ast->location, EF, alloc->makeIdentifier(U"$"));

        } else if (auto *ast = dynamic_cast<Error*>(ast_)) {
            desugar(ast->expr, obj_level);

        } else if (auto *ast = dynamic_cast<Function*>(ast_)) {
            desugar(ast->body, obj_level);

        } else if (dynamic_cast<const Import*>(ast_)) {
            // Nothing to do.

        } else if (dynamic_cast<const Importstr*>(ast_)) {
            // Nothing to do.

        } else if (auto *ast = dynamic_cast<Index*>(ast_)) {
            desugar(ast->target, obj_level);
            if (ast->isSlice) {
                if (ast->index == nullptr)
                    ast->index = make<LiteralNull>(ast->location, EF);
                desugar(ast->index, obj_level);

                if (ast->end == nullptr)
                    ast->end = make<LiteralNull>(ast->location, EF);
                desugar(ast->end, obj_level);

                if (ast->step == nullptr)
                    ast->step = make<LiteralNull>(ast->location, EF);
                desugar(ast->step, obj_level);

                ast_ = make<Apply>(
                    ast->location,
                    EF,
                    make<Index>(
                        E, EF, std(), EF, false, str(U"slice"), EF, nullptr, EF, nullptr, EF),
                    EF,
                    std::vector<Apply::Arg>{
                        {ast->target, EF},
                        {ast->index, EF},
                        {ast->end, EF},
                        {ast->step, EF},
                    },
                    false,  // trailing comma
                    EF,
                    EF,
                    false  // tailstrict
                );
            } else {
                if (ast->id != nullptr) {
                    assert(ast->index == nullptr);
                    ast->index = str(ast->id->name);
                    ast->id = nullptr;
                }
                desugar(ast->index, obj_level);
            }

        } else if (auto *ast = dynamic_cast<Local*>(ast_)) {
            for (auto &bind: ast->binds)
                desugar(bind.body, obj_level);
            desugar(ast->body, obj_level);

            for (auto &bind: ast->binds) {
                if (bind.functionSugar) {
                    bind.body = alloc->make<Function>(
                        ast->location, ast->openFodder, bind.parenLeftFodder, bind.params, false,
                        bind.parenRightFodder, bind.body);
                    bind.functionSugar = false;
                    bind.params.clear();
                }
            }

        } else if (dynamic_cast<const LiteralBoolean*>(ast_)) {
            // Nothing to do.

        } else if (dynamic_cast<const LiteralNumber*>(ast_)) {
            // Nothing to do.

        } else if (auto *ast = dynamic_cast<LiteralString*>(ast_)) {
            if (ast->tokenKind != LiteralString::BLOCK) {
                ast->value = jsonnet_string_unescape(ast->location, ast->value);
            }
            ast->tokenKind = LiteralString::DOUBLE;
            ast->blockIndent.clear();

        } else if (dynamic_cast<const LiteralNull*>(ast_)) {
            // Nothing to do.

        } else if (auto *ast = dynamic_cast<DesugaredObject*>(ast_)) {
            for (auto &field : ast->fields) {
                desugar(field.name, obj_level);
                desugar(field.body, obj_level + 1);
            }
            for (AST *assert : ast->asserts) {
                desugar(assert, obj_level + 1);
            }

        } else if (auto *ast = dynamic_cast<Object*>(ast_)) {
            // Hidden variable to allow outer/top binding.
            if (obj_level == 0) {
                const Identifier *hidden_var = alloc->makeIdentifier(U"$");
                auto *body = alloc->make<Self>(E, EF);
                ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
            }

            desugarFields(ast, ast->fields, obj_level);

            DesugaredObject::Fields new_fields;
            ASTs new_asserts;
            for (const ObjectField &field : ast->fields) {
                if (field.kind == ObjectField::ASSERT) {
                    new_asserts.push_back(field.expr2);
                } else if (field.kind == ObjectField::FIELD_EXPR) {
                    new_fields.emplace_back(field.hide, field.expr1, field.expr2);
                } else {
                    std::cerr << "INTERNAL ERROR: field should have been desugared: "
                              << field.kind << std::endl;
                }
            }
            ast_ = alloc->make<DesugaredObject>(ast->location, new_asserts, new_fields);

        } else if (auto *ast = dynamic_cast<ObjectComprehension*>(ast_)) {
            // Hidden variable to allow outer/top binding.
            if (obj_level == 0) {
                const Identifier *hidden_var = alloc->makeIdentifier(U"$");
                auto *body = alloc->make<Self>(E, EF);
                ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
            }

            desugarFields(ast, ast->fields, obj_level);

            for (ComprehensionSpec &spec : ast->specs)
                desugar(spec.expr, obj_level);

            AST *field = ast->fields.front().expr1;
            AST *value = ast->fields.front().expr2;

            /*  {
                    [arr[0]]: local x = arr[1], y = arr[2], z = arr[3]; val_expr
                    for arr in [ [key_expr, x, y, z] for ...  ]
                }
            */
            auto *_arr = id(U"$arr");
            AST *zero = make<LiteralNumber>(E, EF, "0.0");
            int counter = 1;
            Local::Binds binds;
            Array::Elements arr_e {Array::Element(field, EF)};
            for (ComprehensionSpec &spec : ast->specs) {
                if (spec.kind == ComprehensionSpec::FOR) {
                    std::stringstream num;
                    num << counter++;
                    binds.push_back(bind(
                        spec.var,
                        make<Index>(E, EF, var(_arr), EF, false,
                                    make<LiteralNumber>(E, EF, num.str()), EF, nullptr, EF, nullptr,
                                    EF)));
                    arr_e.emplace_back(var(spec.var), EF);
                }
            }
            AST *arr = make<ArrayComprehension>(
                ast->location,
                EF,
                make<Array>(ast->location, EF, arr_e, false, EF),
                EF,
                false,
                ast->specs,
                EF);
            desugar(arr, obj_level);
            ast_ = make<ObjectComprehensionSimple>(
                ast->location,
                make<Index>(E, EF, var(_arr), EF, false, zero, EF, nullptr, EF, nullptr, EF),
                make<Local>(
                    ast->location,
                    EF,
                    binds,
                    value),
                _arr,
                arr);

        } else if (auto *ast = dynamic_cast<ObjectComprehensionSimple*>(ast_)) {
            desugar(ast->field, obj_level);
            desugar(ast->value, obj_level + 1);
            desugar(ast->array, obj_level);

        } else if (auto *ast = dynamic_cast<Parens*>(ast_)) {
            // Strip parens.
            desugar(ast->expr, obj_level);
            ast_ = ast->expr;

        } else if (dynamic_cast<const Self*>(ast_)) {
            // Nothing to do.

        } else if (auto * ast = dynamic_cast<SuperIndex*>(ast_)) {
            if (ast->id != nullptr) {
                assert(ast->index == nullptr);
                ast->index = str(ast->id->name);
                ast->id = nullptr;
            }
            desugar(ast->index, obj_level);

        } else if (auto *ast = dynamic_cast<Unary*>(ast_)) {
            desugar(ast->expr, obj_level);

        } else if (dynamic_cast<const Var*>(ast_)) {
            // Nothing to do.

        } else {
            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
            std::abort();

        }
    }
int main(void){

    /*********** INITIALIZE STUFF *************/
    /* Initialize random seed */
    time_t randseed = time(NULL);
    srand(randseed);
    printf("Seeded with %lld\n", (long long) randseed);

    int n=10000; //timesteps per plastic trial
    int no=5; //number of oscillators
    int plasticTrials = 10;
    int g=2*no; //number of groups
    double dt = 0.0001;
    int t,i,j,k,l;  //counters
    double Re[n][no], R_i[no][2]; //Excitatory rate vector and initial rate vec
    double R[n][g]; //All groups rate vec

    //Init weights
    int rw = 100;  //how often to record syn weights
    double W_t[n/rw][g][g]; //Weight matrix over time
    double wW[2][2];    //Within-oscillator synaptic weights
        wW[0][0]=2;         wW[0][1]=2.873; //EE    EI
        wW[1][0]=-2.873;    wW[1][1]=-2;    //IE    II
    double scl = 2/((double)no);
    double xW[2][2];    //Initial x-group synaptic strengths
        xW[0][0]=0.2*scl;   xW[0][1]=0.3*scl;   //xEE   xEI
        xW[1][0]=-0.5*scl;  xW[1][1]=0*scl;     //xIE   xII
    double W[g][g];    //All weights
    for (i=0;i<g;i++){ for (j=0;j<g;j++){
        if (i/2==j/2){ //within-group block
            W[i][j]=wW[i%2][j%2];
        } else { //cross-group
            W[i][j]=xW[i%2][j%2];
        }
    }}
    double W_1D[g*g];
    for (i=0;i<g;i++){
        for (j=0;j<g;j++){
            W_1D[g*i+j] = W[i][j];
        }
    }
    //TODO: debugger
    for (i=0;i<g;i++){
        for (j=0;j<g;j++){
            printf("%f\t", W[i][j]);
        }
        printf("\n");
    }
    

    //Weights alowed to change?
    int W_c[g][g];
    for (i=0;i<g;i++){ for (j=0;j<g;j++){
        if (i%2==0 && j%2==0 && i!=j){ //if we're @ an xEE weight,
            W_c[i][j]=1;
        } else {
            W_c[i][j]=0;
        }
    }}

    //Weight bounds?
    int W_b[g][g];
    for (i=0;i<g;i++){ for (j=0;j<g;j++){
        if (i%2==0 && j%2==0 && i!=j){ //if we're @ an xEE weight,
            W_b[i][j]=0.3;
        } else {
            W_b[i][j]=0;
        }
    }}

    //Plasticity time constants
    double t_w = 5000;
    double t_th = 500;

    double th[g][g];
    for (i=0;i<g;i++){ for (j=0;j<g;j++){
        if (i%2==0 && j%2==0 && i!=j){ //if we're @ an xEE weight,
            th[i][j]=15;
        } else {
            th[i][j]=0;
        }
    }}

    //Gamma and tau
    double gamma[g];
    for (i=0;i<g;i+=2){
        gamma[i] = 10;      //Excitatory
        gamma[i+1] = -10;   //Inhibitory
    }
    double tau[g];
    for (i=0;i<g;i+=2){
        tau[i] = 0.002; //AMPA (Excitatory - 2ms)
        tau[i+1] = 0.01; //GABA_A (Inhibitory - 10ms)
    }

    //Find initial rate vector
    int p=1000;
    double lp_rates[p][2];
    get_last_period(&p, lp_rates, wW);

    double R_i_A1[no][2];
            R_i_A1[0][0] = lp_rates[0][0]+gen_rand(); //O1, 2, and 3 are IN-phase,
            R_i_A1[0][1] = lp_rates[0][1]+gen_rand();
            R_i_A1[1][0] = lp_rates[0][0]+gen_rand();
            R_i_A1[1][1] = lp_rates[0][1]+gen_rand();
            R_i_A1[2][0] = lp_rates[0][0]+gen_rand();
            R_i_A1[2][1] = lp_rates[0][1]+gen_rand();
            R_i_A1[3][0] = lp_rates[p/2][0]+gen_rand(); //O4, 5 are OUT-phase
            R_i_A1[3][1] = lp_rates[p/2][1]+gen_rand();
            R_i_A1[4][0] = lp_rates[p/2][0]+gen_rand();
            R_i_A1[4][1] = lp_rates[p/2][1]+gen_rand();

    //Plastic runs
    int pd_res = 1000; //How many phase diff trials to do per plastic run
    int pl_res = 2; //How many plastic runs to do
    double o2_vec[pd_res], o3_vec[pd_res], o4_vec[pd_res], o5_vec[pd_res]; 
    double avgphdiffs[pl_res][4];
    double stdphdiffs[pl_res][4];

    //Multithreading stuff
    double phdiffs[4*pd_res];
    pthread_t threads[NUM_THREADS];
    THREAD_DAT_1D t_args[NUM_THREADS];
    int t_divs[NUM_THREADS+1];
    segment_threads(NUM_THREADS, 0, pd_res, t_divs);


    
    //put data in thread args
    for (i=0;i<NUM_THREADS;i++){
        t_args[i].id = i;
        t_args[i].a = t_divs[i];
        t_args[i].b = t_divs[i+1];
        t_args[i].res = pd_res;
        t_args[i].DATA = (double *)&phdiffs;
        t_args[i].DATA_IN = (double *)&W_1D;
    }


    /*********** TESTER RUN OF 5 GROUPS w/ RANDOM START ***********/
/*
    double Rees[n][no];
    int nn = 20000, phaseInd;
    double R_i_rand[no][2];
            R_i_rand[0][0] = lp_rates[0][0];
            R_i_rand[0][1] = lp_rates[0][1];
            R_i_rand[1][0] = lp_rates[0][0];
            R_i_rand[1][1] = lp_rates[0][1];
        for (i=2;i<no;i++){
            phaseInd = rand() % p;
            R_i_rand[i][0] = lp_rates[phaseInd][0];
            R_i_rand[i][1] = lp_rates[phaseInd][1];
        }
    pingRateN(nn,no,Rees,R_i_rand,W[0]*2/5,W[1]*2/5,W[2]*2/5,W[3]*2/5,wW,dt);
    char * fn_prnt = "Learned_group_synchrony_5grouptester.dat";
    asave(n, no, Rees, fn_prnt);
    printf("Done with pingRateN 5-group tester - data saved as %s\n", fn_prnt);
 */   



/******************************* LOOP THROUGH PLASTIC RUNS *****************/

    //Create new file to store weights
    char * fn_plas_w = "Learned_group_synchrony_plas_w.dat";
    FILE * pFile_w = fopen(fn_plas_w,"w"); 
    //fprintf(pFile_wn, "\n"); fclose(pFile_wn);
    //FILE * pFile_w = fopen(fn_plas_w,"a"); //now open it for appending

    //Create new file to store weights
    char * fn_plas_r = "Learned_group_synchrony_plas_r.dat";
    FILE * pFile_r = fopen(fn_plas_r,"w"); 
    //fprintf(pFile_rn, "\n"); fclose(pFile_rn);
    //FILE * pFile_r = fopen(fn_plas_r,"a"); //now open it for appending


int pr; //plastic loops
for (pr=0; pr<pl_res;pr++){

    /*********** BEFORE PLASTICITY AVG PHDIFFS *************/
    //Run threads
    for (i=0;i<NUM_THREADS;i++){
        pthread_create(&threads[i],NULL,Learned_group_synchrony_worker,(void*)&t_args[i]);
    }

    //Wait for threads to finish
    waitfor_threads(NUM_THREADS, threads);

    //Find avg phdiffs
    for (i=0;i<pd_res;i++){
        o2_vec[i] = phdiffs[i*4];
        o3_vec[i] = phdiffs[i*4+1];
        o4_vec[i] = phdiffs[i*4+2];
        o5_vec[i] = phdiffs[i*4+3];
    }
    avgphdiffs[pr][0] = mean(pd_res, o2_vec);    
    avgphdiffs[pr][1] = mean(pd_res, o3_vec);    
    avgphdiffs[pr][2] = mean(pd_res, o4_vec);    
    avgphdiffs[pr][3] = mean(pd_res, o5_vec);    

    stdphdiffs[pr][0] = std(pd_res, o2_vec);    
    stdphdiffs[pr][1] = std(pd_res, o3_vec);    
    stdphdiffs[pr][2] = std(pd_res, o4_vec);    
    stdphdiffs[pr][3] = std(pd_res, o5_vec);    

    printf("%d: Avg ph diff between O1 and O2: %f +/- %f\n", pr, avgphdiffs[pr][0], stdphdiffs[pr][0]);
    printf("%d: Avg ph diff between O1 and O3: %f +/- %f\n", pr, avgphdiffs[pr][1], stdphdiffs[pr][1]);
    printf("%d: Avg ph diff between O1 and O4: %f +/- %f\n", pr, avgphdiffs[pr][2], stdphdiffs[pr][2]);
    printf("%d: Avg ph diff between O1 and O5: %f +/- %f\n", pr, avgphdiffs[pr][3], stdphdiffs[pr][3]);




    /*********** DO PLASTIC RUNS WHERE A1 IS IN-PHASE ******************/
    printf("STARTING PLASTIC RUN %d\n", pr);

    //Simulate
    //for (l=0; l<plasticTrials; l++){ //alternate A1, A2
    //ASSEMBLY 1

    //plasticRateN_recW call
    plasticRateN_recW(g,n,R,R_i_A1,W_t,W_c,W,W_b,t_w,th,t_th,gamma,tau,dt);
    //Set 2D matrix returned as W -> W_1D for doing above step
    for (i=0;i<g;i++){ for (j=0;j<g;j++){
        W_1D[g*i+j] = W[i][j];
    }}
    //Append to file for weights
    for (t=0;t<n/rw;t++){
        for (i=0;i<g;i++){ for (j=0;j<g;j++){
            if (i%2==0 && j%2==0 && i!=j){ //if we're @ an xEE weight,
                fprintf(pFile_w, "%f\t", W_t[t][i][j]);
                //printf("%f\t", W_t[t][i][j]);
            }
        }}
        fprintf(pFile_w, "\n"); //new timestep
        //printf("\n"); //new timestep
    }
    //Append to file for rates
    for (t=0; t<n; t++){ 
        for (i=0;i<no;i++){
            fprintf(pFile_r, "%f\t", Re[t][i]);
        }
        fprintf(pFile_r, "\n");
    }

    printf("DONE WITH PLASTIC RUN %d\n", pr);

/*
        //ASSEMBLY 2
        plasticPingRateN_recW(n,no,Re,R_i_A2,W[0],W[1],W[2],W[3],
                            xEE_c,xEI_c,xIE_c,xII_c,wW,dt,W_t);    
        W[0] = (W_t[n/rw-1][0][2]+W_t[n/rw-1][0][2])/2; //set new xEE weight for next run
        printf("xEE weight after plastic run %d (A1): %f\n",i,W_t[n/rw-1][0][2]);
        //Append to file for weights
        for (t=0;t<n/rw;t++){
            for (i=0;i<g;i++){ for (j=0;j<g;j++){
                if (i%2==0 && j%2==0 && i!=j){ //if we're @ an xEE weight,
                    fprintf(pFile_w, "%f\t", W_t[t][i][j]);
                }
            }}
            fprintf(pFile_w, "\n"); //new timestep
        }
        //Append to file for rates
        for (t=0; t<n; t++){ 
            for (i=0;i<no;i++){
                fprintf(pFile_r, "%f\t", Re[t][i]);
            }
            fprintf(pFile_r, "\n");
        }
    }
*/

    }

    fclose(pFile_w);
    fclose(pFile_r);

    printf("Done!\n");

    return 0;

}
示例#23
0
#include "glue.h"

int	__sdidinit;

#define	NDYNAMIC 10		/* add ten more whenever necessary */

#define	std(flags, file) \
	{0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite}
/*	 p r w flags file _bf z  cookie      close    read    seek    write */

				/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
static struct glue uglue = { 0, FOPEN_MAX - 3, usual };

FILE __sF[3] = {
	std(__SRD, STDIN_FILENO),		/* stdin */
	std(__SWR, STDOUT_FILENO),		/* stdout */
	std(__SWR|__SNBF, STDERR_FILENO)	/* stderr */
};
struct glue __sglue = { &uglue, 3, __sF };

static struct glue *
moreglue(n)
	register int n;
{
	register struct glue *g;
	register FILE *p;
	static FILE empty;

	g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE));
	if (g == NULL)
inline void MacroAssembler::std(Register d, const Address& a, int offset) {
  if (a.has_index()) { assert(offset == 0, ""); std(d, a.base(), a.index()        ); }
  else               {                          std(d, a.base(), a.disp() + offset); }
}
示例#25
0
void C1_MacroAssembler::initialize_body(Register obj, Register tmp1, Register tmp2,
                                        int obj_size_in_bytes, int hdr_size_in_bytes) {
  const int index = (obj_size_in_bytes - hdr_size_in_bytes) / HeapWordSize;

  const int cl_size         = VM_Version::L1_data_cache_line_size(),
            cl_dwords       = cl_size>>3,
            cl_dw_addr_bits = exact_log2(cl_dwords);

  const Register tmp = R0,
                 base_ptr = tmp1,
                 cnt_dwords = tmp2;

  if (index <= 6) {
    // Use explicit NULL stores.
    if (index > 0) { li(tmp, 0); }
    for (int i = 0; i < index; ++i) { std(tmp, hdr_size_in_bytes + i * HeapWordSize, obj); }

  } else if (index < (2<<cl_dw_addr_bits)-1) {
    // simple loop
    Label loop;

    li(cnt_dwords, index);
    addi(base_ptr, obj, hdr_size_in_bytes); // Compute address of first element.
    li(tmp, 0);
    mtctr(cnt_dwords);                      // Load counter.
  bind(loop);
    std(tmp, 0, base_ptr);                  // Clear 8byte aligned block.
    addi(base_ptr, base_ptr, 8);
    bdnz(loop);

  } else {
    // like clear_memory_doubleword
    Label startloop, fast, fastloop, restloop, done;

    addi(base_ptr, obj, hdr_size_in_bytes);           // Compute address of first element.
    load_const_optimized(cnt_dwords, index);
    rldicl_(tmp, base_ptr, 64-3, 64-cl_dw_addr_bits); // Extract dword offset within first cache line.
    beq(CCR0, fast);                                  // Already 128byte aligned.

    subfic(tmp, tmp, cl_dwords);
    mtctr(tmp);                        // Set ctr to hit 128byte boundary (0<ctr<cl_dwords).
    subf(cnt_dwords, tmp, cnt_dwords); // rest.
    li(tmp, 0);

  bind(startloop);                     // Clear at the beginning to reach 128byte boundary.
    std(tmp, 0, base_ptr);             // Clear 8byte aligned block.
    addi(base_ptr, base_ptr, 8);
    bdnz(startloop);

  bind(fast);                                  // Clear 128byte blocks.
    srdi(tmp, cnt_dwords, cl_dw_addr_bits);    // Loop count for 128byte loop (>0).
    andi(cnt_dwords, cnt_dwords, cl_dwords-1); // Rest in dwords.
    mtctr(tmp);                                // Load counter.

  bind(fastloop);
    dcbz(base_ptr);                    // Clear 128byte aligned block.
    addi(base_ptr, base_ptr, cl_size);
    bdnz(fastloop);

    cmpdi(CCR0, cnt_dwords, 0);        // size 0?
    beq(CCR0, done);                   // rest == 0
    li(tmp, 0);
    mtctr(cnt_dwords);                 // Load counter.

  bind(restloop);                      // Clear rest.
    std(tmp, 0, base_ptr);             // Clear 8byte aligned block.
    addi(base_ptr, base_ptr, 8);
    bdnz(restloop);

  bind(done);
  }
}
示例#26
0
文件: sa.c 项目: drigz/5R1
real sa(unsigned seed)
{
    srandom(seed);

    real T;
    if (initial_temp_method != constant)
        T = INFINITY;
    else
        T = initial_temp;

    real step_size_x = init_step_size, step_size_y = init_step_size;
    real pos_x = 5, pos_y = 5;
    real obj = bump(pos_x, pos_y);
    real obj_pen = obj;

    int samples_remaining = 5000-1;

    real obj_d[5000];
    int n_obj_d = 0;
    real accepts[5000];
    int n_accepts = 0;

    int num_trials = 0, num_acceptances = 0;
    int initial_trials = 500;
    int max_trials = temp_length;
    int max_acceptances = 0.6*temp_length;

    real alpha = 0.1, omega = 2.1;

    real best_obj = obj;
    real best_x = pos_x, best_y = pos_y;
    int best_time = samples_remaining;

    while (samples_remaining > 0)
    {
        if (best_time - samples_remaining > 500)
        {
            best_time = samples_remaining;
            pos_x = best_x;
            pos_y = best_y;
            obj = best_obj;
            obj_pen = best_obj + penalty_weight * penalty(pos_x, pos_y) / T;

            step_size_x = step_size_y = init_step_size;
        }

        real step_x, step_y;
        if (step_method == gaussian)
        {
            step_x = step_size_x * randn();
            step_y = step_size_y * randn();
        }
        else
        {
            step_x = step_size_x * (2*randf()-1);
            step_y = step_size_y * (2*randf()-1);
        }

        real new_x = pos_x+step_x, new_y = pos_y+step_y;

        real new_pen = penalty_weight * penalty(new_x, new_y);

        if (T == INFINITY && new_pen != 0)
            continue;

        real new_obj = bump(new_x, new_y);
        real new_obj_pen = new_obj + new_pen / T;
        samples_remaining--;

        num_trials++;

        if (new_pen == 0)
        {
            if (new_obj > best_obj)
            {
                best_obj = new_obj;
                best_x = new_x;
                best_y = new_y;
                best_time = samples_remaining;
            }
        }

        real p;
        if (step_method == parks)
        {
            real step_norm = sqrtr(step_x*step_x + step_y*step_y);
            p = exp(- (obj_pen - new_obj_pen) / (T * step_norm));
        }
        else
        {
            p = exp(- (obj_pen - new_obj_pen) / T);
        }

        if (randf() < p)
        {
            num_acceptances++;
            obj_d[n_obj_d++] = new_obj_pen - obj_pen;
            pos_x = new_x;
            pos_y = new_y;
            obj = new_obj;
            obj_pen = new_obj_pen;

            accepts[n_accepts++] = new_obj_pen;

            if (T != INFINITY && step_method == parks)
            {
                step_size_x = (1-alpha)*step_size_x + alpha*omega*fabsr(step_x);
                step_size_y = (1-alpha)*step_size_y + alpha*omega*fabsr(step_y);
            }
        }

        bool reduced_T = false;

        if (T == INFINITY)
        {
            if (num_trials >= initial_trials)
            {
                if (initial_temp_method == kirkpatrick)
                    T = T_kirkpatrick(obj_d, n_obj_d);
                else if (initial_temp_method == white)
                    T = std(obj_d, n_obj_d);
                else
                {
                    fprintf(stderr, "unknown temp method");
                    exit(1);
                }
                reduced_T = true;
            }
        }
        else if (num_trials >= max_trials || num_acceptances >= max_acceptances)
        {
            if (temp_decay_method == huang)
            {
                real factor;
                if (n_accepts < 2)
                    factor = 0.5;
                else
                {
                    factor = exp(-0.7*T/std(accepts, n_accepts));
                    if (factor < 0.5)
                        factor = 0.5;
                }
                T *= factor;
            }
            else
                T *= temp_decay;
            reduced_T = true;
        }

        if (reduced_T)
        {
            //printf("%g\n", T);
            n_obj_d = 0;
            num_trials = 0;
            num_acceptances = 0;
            n_accepts = 1;
            accepts[0] = obj_pen;
        }
    }

    return best_obj;
}
inline void MacroAssembler::std(Register d, Register s1, RegisterOrConstant s2) { std(d, Address(s1, s2)); }
示例#28
0
//--------------------------------------------------------------------------
void
CoinIndexedVectorUnitTest()
{
  
  int i;
  // Test default constructor
  {
    CoinIndexedVector r;
    assert( r.indices_==NULL );
    assert( r.elements_==NULL );
    assert( r.getNumElements()==0 );
    assert( r.capacity_==0);
  }
  
  // Test set and get methods
  const int ne = 4;
  int inx[ne] = { 1, 3, 4, 7 };
  double el[ne] = { 1.2, 3.4, 5.6, 7.8 };
  {
    CoinIndexedVector r;    
    assert( r.getNumElements()==0 );
    
    // Test setting/getting elements with int* & float* vectors
    r.setVector( ne, inx, el );
    assert( r.getNumElements()==ne );
    for ( i=0; i<ne; i++ ) {
      assert( r.getIndices()[i]  == inx[i] );
      assert( r[inx[i]]  == el[i] );
    }
    
    // Test setting/getting elements with indices out of order  
    const int ne2 = 5;
    int inx2[ne2] = { 2, 4, 8, 14, 3 };
    double el2[ne2] = { 2.2, 4.4, 6.6, 8.8, 3.3 };
    
    r.setVector(ne2,inx2,el2);
    
    assert( r.getNumElements()==ne2 );    
    
    assert( r.getIndices()[0]==inx2[0] );
    
    assert( r.getIndices()[1]==inx2[1] );
    
    assert( r.getIndices()[2]==inx2[2] );
    
    assert( r.getIndices()[3]==inx2[3] );
    
    assert( r.getIndices()[4]==inx2[4] );
    

    CoinIndexedVector r1(ne2,inx2,el2);
    assert( r == r1 );   
  }    
  CoinIndexedVector r;
  
  
  {
    CoinIndexedVector r;
    const int ne = 3;
    int inx[ne] = { 1, 2, 3 };
    double el[ne] = { 2.2, 4.4, 8.8};
    r.setVector(ne,inx,el);
    int c = r.capacity();
    // Test swap function
    r.swap(0,2);
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.capacity() == c );
    
    // Test the append function
    CoinIndexedVector s;
    const int nes = 4;
    int inxs[nes] = { 11, 12, 13, 14 };
    double els[nes] = { .122, 14.4, 18.8, 19.9};
    s.setVector(nes,inxs,els);
    r.append(s);
    assert( r.getNumElements()==7 );
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.getIndices()[3]==11 );
    assert( r.getIndices()[4]==12 );
    assert( r.getIndices()[5]==13 );
    assert( r.getIndices()[6]==14 );
    
    // Test the resize function
    c = r.capacity();
    r.truncate(4);
    // we will lose 11
    assert( r.getNumElements()==3 );
    assert( r.getIndices()[0]==3 );
    assert( r.getIndices()[1]==2 );
    assert( r.getIndices()[2]==1 );
    assert( r.getMaxIndex() == 3 );
    assert( r.getMinIndex() == 1 );
    assert( r.capacity() == c );
  }
  
  // Test borrow and return vector
  {
    CoinIndexedVector r,r2;
    const int ne = 3;
    int inx[ne] = { 1, 2, 3 };
    double el[ne] = { 2.2, 4.4, 8.8};
    double els[4] = { 0.0,2.2, 4.4, 8.8};
    r.setVector(ne,inx,el);
    r2.borrowVector(4,ne,inx,els);
    assert (r==r2);
    r2.returnVector();
    assert (!r2.capacity());
    assert (!r2.getNumElements());
    assert (!r2.denseVector());
    assert (!r2.getIndices());
  }
  
  // Test copy constructor and assignment operator
  {
    CoinIndexedVector rhs;
    {
      CoinIndexedVector r;
      {
	CoinIndexedVector rC1(r);      
	assert( 0==r.getNumElements() );
	assert( 0==rC1.getNumElements() );
	
	
	r.setVector( ne, inx, el ); 
	
	assert( ne==r.getNumElements() );
	assert( 0==rC1.getNumElements() ); 
      }
      
      CoinIndexedVector rC2(r);   
      
      assert( ne==r.getNumElements() );
      assert( ne==rC2.getNumElements() );
      
      for ( i=0; i<ne; i++ ) {
	assert( r.getIndices()[i] == rC2.getIndices()[i] );
      }
      
      rhs=rC2;
    }
    // Test that rhs has correct values even though lhs has gone out of scope
    assert( rhs.getNumElements()==ne );
    
    for ( i=0; i<ne; i++ ) {
      assert( inx[i] == rhs.getIndices()[i] );
    } 
  }
  
  // Test operator==
  {
    CoinIndexedVector v1,v2;
    assert( v1==v2 );
    assert( v2==v1 );
    assert( v1==v1 );
    assert( !(v1!=v2) );
    
    v1.setVector( ne, inx, el );
    assert ( !(v1==v2) );
    assert ( v1!=v2 );
    
    CoinIndexedVector v3(v1);
    assert( v3==v1 );
    assert( v3!=v2 );
    
    CoinIndexedVector v4(v2);
    assert( v4!=v1 );
    assert( v4==v2 );
  }
  
  {
    // Test sorting of indexed vectors    
    const int ne = 4;
    int inx[ne] = { 1, 4, 0, 2 };
    double el[ne] = { 10., 40., 1., 20. };
    CoinIndexedVector r;
    r.setVector(ne,inx,el);
    
    // Test that indices are in increasing order
    r.sort();
    for ( i=1; i<ne; i++ ) assert( r.getIndices()[i-1] < r.getIndices()[i] );

  }    
  {
    // Test operator[] and indexExists()
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector r;
    bool errorThrown = false;
    try {
      assert( r[1]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    r.setVector(ne,inx,el);
    
    errorThrown = false;
    try {
      assert( r[-1]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    errorThrown = false;
    try {
      assert( r[5]==0. );
    }
    catch (CoinError& e) {
      errorThrown = true;
    }
    assert( errorThrown );
    
    assert ( r.getMaxIndex()==4 );
    assert ( r.getMinIndex()==0 );
  }
  
  // Test that attemping to get min/max index of a 0,
  // length vector 
  {
    CoinIndexedVector nullVec;
    assert( nullVec.getMaxIndex() == -COIN_INT_MAX/*0*/ );
    assert( nullVec.getMinIndex() == COIN_INT_MAX/*0*/ );
  } 
  
  // Test CoinFltEq with equivalent method
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    int inx2[ne] = { 7, 4, 3, 1 };
    double el2[ne] = { 7.8+.5, 5.6+.5, 3.4+.5, 1.2+.5 };
    CoinIndexedVector v1,v2;
    v1.setVector(ne,inx1,el1);
    v2.setVector(ne,inx2,el2);
  }
  
  {
    // Test reserve
    CoinIndexedVector v1,v2;
    assert( v1.capacity()==0 );
    v1.reserve(6);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==0 );
    v2=v1;
    assert( v2.capacity() == 6 );
    assert( v2.getNumElements()==0 );
    assert( v2==v1 );
    v1.setVector(0,NULL,NULL);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==0 );
    assert( v2==v1 );
    v2=v1;
    assert( v2.capacity() == 6 );
    assert( v2.getNumElements()==0 );
    assert( v2==v1 );
    
    const int ne = 2;
    int inx[ne] = { 1, 3 };
    double el[ne] = { 1.2, 3.4 };
    v1.setVector(ne,inx,el);
    assert( v1.capacity()==6 );
    assert( v1.getNumElements()==2 );
    v2=v1;
    assert( v2.capacity()==6 );
    assert( v2.getNumElements()==2 );
    assert( v2==v1 );
    
    const int ne1 = 5;
    int inx1[ne1] = { 1, 3, 4, 5, 6 };
    double el1[ne1] = { 1.2, 3.4, 5., 6., 7. };
    v1.setVector(ne1,inx1,el1);
    assert( v1.capacity()==7 );
    assert( v1.getNumElements()==5 );
    v2=v1;
    assert( v2.capacity()==7 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
    const int ne2 = 8;
    int inx2[ne2] = { 1, 3, 4, 5, 6, 7, 8, 9 };
    double el2[ne2] = { 1.2, 3.4, 5., 6., 7., 8., 9., 10. };
    v1.setVector(ne2,inx2,el2);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==8 );
    v2=v1;
    assert( v2.getNumElements()==8 );    
    assert( v2==v1 );
    
    v1.setVector(ne1,inx1,el1);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==5 );
    v2=v1;    
    assert( v2.capacity()==10 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
    v1.reserve(7);
    assert( v1.capacity()==10 );
    assert( v1.getNumElements()==5 );
    v2=v1;
    assert( v2.capacity()==10 );
    assert( v2.getNumElements()==5 );
    assert( v2==v1 );
    
  }
  
  // Test the insert method
  {
    CoinIndexedVector v1;
    assert( v1.getNumElements()==0 );
    assert( v1.capacity()==0 );
    
    v1.insert(1,1.);
    assert( v1.getNumElements()==1 );
    assert( v1.capacity()==2 );
    assert( v1.getIndices()[0] == 1 );
    
    v1.insert(10,10.);
    assert( v1.getNumElements()==2 );
    assert( v1.capacity()==11 );
    assert( v1.getIndices()[1] == 10 );
    
    v1.insert(20,20.);
    assert( v1.getNumElements()==3 );
    assert( v1.capacity()==21 );
    assert( v1.getIndices()[2] == 20 );
    
    v1.insert(30,30.);
    assert( v1.getNumElements()==4 );
    assert( v1.capacity()==31 );
    assert( v1.getIndices()[3] == 30 );

    v1.insert(40,40.);
    assert( v1.getNumElements()==5 );
    assert( v1.capacity()==41 );
    assert( v1.getIndices()[4] == 40 );
    
    v1.insert(50,50.);
    assert( v1.getNumElements()==6 );
    assert( v1.capacity()==51 );
    assert( v1.getIndices()[5] == 50 );
    
    CoinIndexedVector v2;
    const int ne1 = 3;
    int inx1[ne1] = { 1, 3, 4 };
    double el1[ne1] = { 1.2, 3.4, 5. };
    v2.setVector(ne1,inx1,el1);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==5 );

    // Test clean method - get rid of 1.2
    assert(v2.clean(3.0)==2);
    assert(v2.denseVector()[1]==0.0);

    // Below are purely for debug - so use assert
    // so we won't try with false
    // Test checkClean 
#ifndef NO_CHECK_CL
    v2.checkClean();
    assert( v2.getNumElements()==2 );

    // Get rid of all
    int numberRemaining = v2.clean(10.0);
    assert(numberRemaining==0);
    v2.checkClear();
#endif    
  }
  
  {
    //Test setConstant and setElement     
    CoinIndexedVector v2;
    const int ne1 = 3;
    int inx1[ne1] = { 1, 3, 4 };
    v2.setConstant(ne1,inx1,3.14);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==5 );
    assert( v2.getIndices()[0]==1 );
    assert( v2.getIndices()[1]==3 );
    assert( v2.getIndices()[2]==4 );
    
    assert( v2[3] == 3.14 );
    
    CoinIndexedVector v2X(ne1,inx1,3.14);
    assert( v2 == v2X );
    
  }
  
  {
    //Test setFull 
    CoinIndexedVector v2;
    const int ne2 = 3;
    double el2[ne2] = { 1., 3., 4. };
    v2.setFull(ne2,el2);    
    assert( v2.getNumElements()==3 );
    assert( v2.capacity()==3 );
    assert( v2.getIndices()[0]==0 );
    assert( v2.getIndices()[1]==1 );
    assert( v2.getIndices()[2]==2 );
    
    assert( v2[1] == 3. );
    
    CoinIndexedVector v2X(ne2,el2);
    assert( v2 == v2X ); 
    
    v2.setFull(0,el2); 
    assert( v2[2] == 0. );  
  }
  
  
#if 0
  // what happens when someone sets 
  // the number of elements to be a negative number
  {    
    const int ne = 4;
    int inx1[ne] = { 1, 3, 4, 7 };
    double el1[ne] = { 1.2, 3.4, 5.6, 7.8 };
    CoinIndexedVector v1;
    v1.set(-ne,inx1,el1);
  }
#endif
  
  
  // Test copy constructor from ShallowPackedVector
  {
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector std(ne,inx,el);
    CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
    CoinIndexedVector pv(*spvP);
    assert( pv == std );
    delete spvP;
    assert( pv == std );
  }
  
  // Test assignment from ShallowPackedVector
  {
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector std(ne,inx,el);
    CoinShallowPackedVector * spvP = new CoinShallowPackedVector(ne,inx,el);
    CoinIndexedVector pv;
    pv = *spvP;
    assert( pv == std );
    delete spvP;
    assert( pv == std );
  }
  
  {
    // Test that sample usage works
    
    const int ne = 4;
    int inx[ne] =   {  1,   4,  0,   2 };
    double el[ne] = { 10., 40., 1., 50. };
    CoinIndexedVector r(ne,inx,el);
    
    assert( r.getIndices()[0]== 1  );
    assert( r.getIndices()[1]== 4  );
    assert( r.getIndices()[2]== 0  );
    assert( r.getIndices()[3]== 2  );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    
    r.sortIncrElement();
    
    assert( r.getIndices()[0]== 0  );
    assert( r.getIndices()[1]== 1  );
    assert( r.getIndices()[2]== 4  );
    assert( r.getIndices()[3]== 2  );
    
    assert( r[ 0]==1. );
    assert( r[ 1]==10.);
    assert( r[ 2]==50.);
    assert( r[ 3]==0. );
    assert( r[ 4]==40.);
    
    CoinIndexedVector r1;
    r1=r;
    assert( r==r1 );
    
    CoinIndexedVector add = r + r1;
    assert( add[0] ==  1.+ 1. );
    assert( add[1] == 10.+10. );
    assert( add[2] == 50.+50. );
    assert( add[3] ==  0.+ 0. );
    assert( add[4] == 40.+40. );
    
  }
  
}
示例#29
0
int main(int argc, char *args[]) {
    if(argc != 5) {
        printf("Insufficient arguments. Need 4 arguments. %d\n", argc);
        exit(1);
    }


    time_t t;
    srand((unsigned) time(&t));
    int m = 10000;
    int n = 1000;
    int n_threads = atoi(args[1]);
    Ops ops;
    ops_init(&ops, m, atof(args[2]), atof(args[3]), atof(args[4])); // Workout the number of operations of each type
    Byte *opsList = malloc(sizeof(Byte) * m);

    runDummyThreads(n_threads);
    buildOpsList(opsList, &ops, m); // Build a randomly ordered list of operations to be carried out

    int sample_size = 0;
    int test_samples = 20;
    float mutex_std = 0;
    float rwlock_std = 0;
    float serial_std = 0;

    // arrays for test sample memory size
    float *mutext_time = malloc(sizeof(float) * test_samples);
    float *rwlock_time = malloc(sizeof(float) * test_samples);  //=malloc(sizeof(float)*test_samples)
    float *serial_time = malloc(sizeof(float) * test_samples);

    //all three linked list impletation run
    for (int i = 0; i < test_samples; i++) {
        mutext_time[i] = linkedListMutex(opsList, n_threads, m, n);
        rwlock_time[i] = linkedListRWLock(opsList, n_threads, m, n);
        serial_time[i] = serialLinkedList(opsList, m, n);
    }

    //finding standard deviation of each linked list implementation
    mutex_std = std(mutext_time, test_samples);
    rwlock_std = std(rwlock_time, test_samples);
    serial_std = std(serial_time, test_samples);

    //find average of each linked list implementation
    float mutex_avg = findAverage(mutext_time, test_samples);
    float rwlock_avg = findAverage(rwlock_time, test_samples);
    float serial_avg = findAverage(serial_time, test_samples);

    //find sample size with 5% accurary and 95% confident interval
    int mutext_ss = findSampleSize(mutex_std, mutex_avg);
    printf("mutex sample_size %d\n", mutext_ss);
    int rwlock_ss = findSampleSize(rwlock_std, rwlock_avg);
    printf("rwlock sample_size %d\n", rwlock_ss);
    int serial_ss = findSampleSize(serial_std, serial_avg);
    printf("serial sample_size %d\n", serial_ss);

    // array with sample size
    float *mutext_time_case = malloc(sizeof(float) * mutext_ss);
    float *rwlock_time_case = malloc(sizeof(float) * rwlock_ss);  //=malloc(sizeof(float)*test_samples)
    float *serial_time_case = malloc(sizeof(float) * serial_ss);

    //mutex linked list implementation
    for (int i = 0; i < mutext_ss; i++) {
        mutext_time_case[i] = linkedListMutex(opsList, n_threads, m, n);
    }

    //rwlock linked list implementation
    for (int i = 0; i < rwlock_ss; i++) {
        rwlock_time_case[i] = linkedListRWLock(opsList, n_threads, m, n);
    }

    //serial linked list implementation
    for (int i = 0; i < serial_ss; i++) {
        serial_time_case[i] = serialLinkedList(opsList, m, n);
    }

    // final average time of each linked list implementation
    float final_mutex_avg = findAverage(mutext_time_case, mutext_ss);
    float final_rwlock_avg = findAverage(rwlock_time_case, rwlock_ss);
    float final_serial_avg = findAverage(serial_time_case, serial_ss);

    // final standard deviation values of each linked list implementation
    float final_mutex_std = std(mutext_time_case, mutext_ss);
    float final_rwlock_std = std(rwlock_time_case, rwlock_ss);
    float final_serial_std = std(serial_time_case, serial_ss);

    printf("mutex linked list average %f :  std %f\n", final_mutex_avg, final_mutex_std);
    printf("rwlock linked list average %f :  std %f\n", final_rwlock_avg, final_rwlock_std);
    printf("serial linked list average %f :  std %f\n", final_serial_avg, final_serial_std);

    return 0;
}
示例#30
0
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
  // Slow_signature handler that respects the PPC C calling conventions.
  //
  // We get called by the native entry code with our output register
  // area == 8. First we call InterpreterRuntime::get_result_handler
  // to copy the pointer to the signature string temporarily to the
  // first C-argument and to return the result_handler in
  // R3_RET. Since native_entry will copy the jni-pointer to the
  // first C-argument slot later on, it is OK to occupy this slot
  // temporarilly. Then we copy the argument list on the java
  // expression stack into native varargs format on the native stack
  // and load arguments into argument registers. Integer arguments in
  // the varargs vector will be sign-extended to 8 bytes.
  //
  // On entry:
  //   R3_ARG1        - intptr_t*     Address of java argument list in memory.
  //   R15_prev_state - BytecodeInterpreter* Address of interpreter state for
  //     this method
  //   R19_method
  //
  // On exit (just before return instruction):
  //   R3_RET            - contains the address of the result_handler.
  //   R4_ARG2           - is not updated for static methods and contains "this" otherwise.
  //   R5_ARG3-R10_ARG8: - When the (i-2)th Java argument is not of type float or double,
  //                       ARGi contains this argument. Otherwise, ARGi is not updated.
  //   F1_ARG1-F13_ARG13 - contain the first 13 arguments of type float or double.

  const int LogSizeOfTwoInstructions = 3;

  // FIXME: use Argument:: GL: Argument names different numbers!
  const int max_fp_register_arguments  = 13;
  const int max_int_register_arguments = 6;  // first 2 are reserved

  const Register arg_java       = R21_tmp1;
  const Register arg_c          = R22_tmp2;
  const Register signature      = R23_tmp3;  // is string
  const Register sig_byte       = R24_tmp4;
  const Register fpcnt          = R25_tmp5;
  const Register argcnt         = R26_tmp6;
  const Register intSlot        = R27_tmp7;
  const Register target_sp      = R28_tmp8;
  const FloatRegister floatSlot = F0;

  address entry = __ function_entry();

  __ save_LR_CR(R0);
  __ save_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
  // We use target_sp for storing arguments in the C frame.
  __ mr(target_sp, R1_SP);
  __ push_frame_reg_args_nonvolatiles(0, R11_scratch1);

  __ mr(arg_java, R3_ARG1);

  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_signature), R16_thread, R19_method);

  // Signature is in R3_RET. Signature is callee saved.
  __ mr(signature, R3_RET);

  // Get the result handler.
  __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);

  {
    Label L;
    // test if static
    // _access_flags._flags must be at offset 0.
    // TODO PPC port: requires change in shared code.
    //assert(in_bytes(AccessFlags::flags_offset()) == 0,
    //       "MethodDesc._access_flags == MethodDesc._access_flags._flags");
    // _access_flags must be a 32 bit value.
    assert(sizeof(AccessFlags) == 4, "wrong size");
    __ lwa(R11_scratch1/*access_flags*/, method_(access_flags));
    // testbit with condition register.
    __ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT);
    __ btrue(CCR0, L);
    // For non-static functions, pass "this" in R4_ARG2 and copy it
    // to 2nd C-arg slot.
    // We need to box the Java object here, so we use arg_java
    // (address of current Java stack slot) as argument and don't
    // dereference it as in case of ints, floats, etc.
    __ mr(R4_ARG2, arg_java);
    __ addi(arg_java, arg_java, -BytesPerWord);
    __ std(R4_ARG2, _abi(carg_2), target_sp);
    __ bind(L);
  }

  // Will be incremented directly after loop_start. argcnt=0
  // corresponds to 3rd C argument.
  __ li(argcnt, -1);
  // arg_c points to 3rd C argument
  __ addi(arg_c, target_sp, _abi(carg_3));
  // no floating-point args parsed so far
  __ li(fpcnt, 0);

  Label move_intSlot_to_ARG, move_floatSlot_to_FARG;
  Label loop_start, loop_end;
  Label do_int, do_long, do_float, do_double, do_dontreachhere, do_object, do_array, do_boxed;

  // signature points to '(' at entry
#ifdef ASSERT
  __ lbz(sig_byte, 0, signature);
  __ cmplwi(CCR0, sig_byte, '(');
  __ bne(CCR0, do_dontreachhere);
#endif

  __ bind(loop_start);

  __ addi(argcnt, argcnt, 1);
  __ lbzu(sig_byte, 1, signature);

  __ cmplwi(CCR0, sig_byte, ')'); // end of signature
  __ beq(CCR0, loop_end);

  __ cmplwi(CCR0, sig_byte, 'B'); // byte
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'C'); // char
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'D'); // double
  __ beq(CCR0, do_double);

  __ cmplwi(CCR0, sig_byte, 'F'); // float
  __ beq(CCR0, do_float);

  __ cmplwi(CCR0, sig_byte, 'I'); // int
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'J'); // long
  __ beq(CCR0, do_long);

  __ cmplwi(CCR0, sig_byte, 'S'); // short
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'Z'); // boolean
  __ beq(CCR0, do_int);

  __ cmplwi(CCR0, sig_byte, 'L'); // object
  __ beq(CCR0, do_object);

  __ cmplwi(CCR0, sig_byte, '['); // array
  __ beq(CCR0, do_array);

  //  __ cmplwi(CCR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type
  //  __ beq(CCR0, do_void);

  __ bind(do_dontreachhere);

  __ unimplemented("ShouldNotReachHere in slow_signature_handler", 120);

  __ bind(do_array);

  {
    Label start_skip, end_skip;

    __ bind(start_skip);
    __ lbzu(sig_byte, 1, signature);
    __ cmplwi(CCR0, sig_byte, '[');
    __ beq(CCR0, start_skip); // skip further brackets
    __ cmplwi(CCR0, sig_byte, '9');
    __ bgt(CCR0, end_skip);   // no optional size
    __ cmplwi(CCR0, sig_byte, '0');
    __ bge(CCR0, start_skip); // skip optional size
    __ bind(end_skip);

    __ cmplwi(CCR0, sig_byte, 'L');
    __ beq(CCR0, do_object);  // for arrays of objects, the name of the object must be skipped
    __ b(do_boxed);          // otherwise, go directly to do_boxed
  }

  __ bind(do_object);
  {
    Label L;
    __ bind(L);
    __ lbzu(sig_byte, 1, signature);
    __ cmplwi(CCR0, sig_byte, ';');
    __ bne(CCR0, L);
   }
  // Need to box the Java object here, so we use arg_java (address of
  // current Java stack slot) as argument and don't dereference it as
  // in case of ints, floats, etc.
  Label do_null;
  __ bind(do_boxed);
  __ ld(R0,0, arg_java);
  __ cmpdi(CCR0, R0, 0);
  __ li(intSlot,0);
  __ beq(CCR0, do_null);
  __ mr(intSlot, arg_java);
  __ bind(do_null);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_int);
  __ lwa(intSlot, 0, arg_java);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_long);
  __ ld(intSlot, -BytesPerWord, arg_java);
  __ std(intSlot, 0, arg_c);
  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, argcnt, max_int_register_arguments);
  __ blt(CCR0, move_intSlot_to_ARG);
  __ b(loop_start);

  __ bind(do_float);
  __ lfs(floatSlot, 0, arg_java);
#if defined(LINUX)
  // Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float
  // in the least significant word of an argument slot.
#if defined(VM_LITTLE_ENDIAN)
  __ stfs(floatSlot, 0, arg_c);
#else
  __ stfs(floatSlot, 4, arg_c);
#endif
#elif defined(AIX)
  // Although AIX runs on big endian CPU, float is in most significant
  // word of an argument slot.
  __ stfs(floatSlot, 0, arg_c);
#else
#error "unknown OS"
#endif
  __ addi(arg_java, arg_java, -BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
  __ blt(CCR0, move_floatSlot_to_FARG);
  __ b(loop_start);

  __ bind(do_double);
  __ lfd(floatSlot, - BytesPerWord, arg_java);
  __ stfd(floatSlot, 0, arg_c);
  __ addi(arg_java, arg_java, - 2 * BytesPerWord);
  __ addi(arg_c, arg_c, BytesPerWord);
  __ cmplwi(CCR0, fpcnt, max_fp_register_arguments);
  __ blt(CCR0, move_floatSlot_to_FARG);
  __ b(loop_start);

  __ bind(loop_end);

  __ pop_frame();
  __ restore_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
  __ restore_LR_CR(R0);

  __ blr();

  Label move_int_arg, move_float_arg;
  __ bind(move_int_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
  __ mr(R5_ARG3, intSlot);  __ b(loop_start);
  __ mr(R6_ARG4, intSlot);  __ b(loop_start);
  __ mr(R7_ARG5, intSlot);  __ b(loop_start);
  __ mr(R8_ARG6, intSlot);  __ b(loop_start);
  __ mr(R9_ARG7, intSlot);  __ b(loop_start);
  __ mr(R10_ARG8, intSlot); __ b(loop_start);

  __ bind(move_float_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)
  __ fmr(F1_ARG1, floatSlot);   __ b(loop_start);
  __ fmr(F2_ARG2, floatSlot);   __ b(loop_start);
  __ fmr(F3_ARG3, floatSlot);   __ b(loop_start);
  __ fmr(F4_ARG4, floatSlot);   __ b(loop_start);
  __ fmr(F5_ARG5, floatSlot);   __ b(loop_start);
  __ fmr(F6_ARG6, floatSlot);   __ b(loop_start);
  __ fmr(F7_ARG7, floatSlot);   __ b(loop_start);
  __ fmr(F8_ARG8, floatSlot);   __ b(loop_start);
  __ fmr(F9_ARG9, floatSlot);   __ b(loop_start);
  __ fmr(F10_ARG10, floatSlot); __ b(loop_start);
  __ fmr(F11_ARG11, floatSlot); __ b(loop_start);
  __ fmr(F12_ARG12, floatSlot); __ b(loop_start);
  __ fmr(F13_ARG13, floatSlot); __ b(loop_start);

  __ bind(move_intSlot_to_ARG);
  __ sldi(R0, argcnt, LogSizeOfTwoInstructions);
  __ load_const(R11_scratch1, move_int_arg); // Label must be bound here.
  __ add(R11_scratch1, R0, R11_scratch1);
  __ mtctr(R11_scratch1/*branch_target*/);
  __ bctr();
  __ bind(move_floatSlot_to_FARG);
  __ sldi(R0, fpcnt, LogSizeOfTwoInstructions);
  __ addi(fpcnt, fpcnt, 1);
  __ load_const(R11_scratch1, move_float_arg); // Label must be bound here.
  __ add(R11_scratch1, R0, R11_scratch1);
  __ mtctr(R11_scratch1/*branch_target*/);
  __ bctr();

  return entry;
}