Exemple #1
0
int witness(type a,type n)
{
    type i;
    type t;
    type u;
    type x;
    type y;

    t = power2(n-1, &u);
    y = mod_exp(a, u, n);

    for (i = 0; i < t; i++) {
        x = y*y%n ;
        if (x == 1 && y != 1 && y != n-1) {
            return 1;
        }
        y = x;
    }
    if ( y != 1 ) {
        return 1;
    }

    return 0;
}
Exemple #2
0
GF2m pow(const GF2m& b,int m)
{
    GF2m z;
    power2(b.fn,m,z.fn);
    return z;
}
Exemple #3
0
void FHT::power(float *p)
{
    power2(p);
    for (int i = 0; i < (m_num / 2); i++)
        *p++ *= .5;
}
Exemple #4
0
void FHT::spectrum(float *p)
{
    power2(p);
    for (int i = 0; i < (m_num / 2); i++, p++)
        *p = (float)sqrt(*p * .5);
}
Exemple #5
0
// 求 2^n,分别测试power2BF_I、power2BF_R、power2、power2_I的性能
void test_power2()
{
	// 测试一千万次取均值
	constexpr int TEST_TIME = 10000000;
	// TEST_TIME个n
	auto n = new int[TEST_TIME];

	// 初始化TEST_TIME个n为随机数,范围[32, 63]
	std::mt19937 engine;
	std::uniform_int_distribution<int> di(32, 63);
	for (int i = 0; i < TEST_TIME; i++) {
		n[i] = di(engine);
	}

	// 正确性测试
	printf("assertion test begin...\n");
	clock_t begin = clock();
	for (int i = 0; i < 100; i++) {
		__int64 pow = static_cast<__int64>(std::pow(2, n[i]));
		assert(power2BF_I(n[i]) == pow);
		assert(power2BF_R(n[i]) == pow);
		assert(power2(n[i]) == pow);
		assert(power2_I(n[i]) == pow);
	}
	auto elapse = clock() - begin;
	printf("assertion test elapsed %lf ms, avg %lf ms\n\n", elapse * 1000.0 / CLOCKS_PER_SEC, elapse * 1000.0 / TEST_TIME/ CLOCKS_PER_SEC);

	// 性能测试1:power2BF_I
	printf("performance test for power2BF_I begin...\n");
	begin = clock();
	for (int i = 0; i < TEST_TIME; i++) {
		power2BF_I(n[i]);
	}
	elapse = clock() - begin;
	printf("performance test for power2BF_I elapsed %lf ms, avg %lf ms\n\n", elapse * 1000.0 / CLOCKS_PER_SEC, elapse * 1000.0 / TEST_TIME / CLOCKS_PER_SEC);

	// 性能测试2:power2BF_R
	printf("performance test for power2BF_R begin...\n");
	begin = clock();
	for (int i = 0; i < TEST_TIME; i++) {
		power2BF_R(n[i]);
	}
	elapse = clock() - begin;
	printf("performance test for power2BF_R elapsed %lf ms, avg %lf ms\n\n", elapse * 1000.0 / CLOCKS_PER_SEC, elapse * 1000.0 / TEST_TIME / CLOCKS_PER_SEC);

	// 性能测试3:power2
	printf("performance test for power2 begin...\n");
	begin = clock();
	for (int i = 0; i < TEST_TIME; i++) {
		power2(n[i]);
	}
	elapse = clock() - begin;
	printf("performance test for power2 elapsed %lf ms, avg %lf ms\n\n", elapse * 1000.0 / CLOCKS_PER_SEC, elapse * 1000.0 / TEST_TIME / CLOCKS_PER_SEC);

	// 性能测试4:power2_I
	printf("performance test for power2_I begin...\n");
	begin = clock();
	for (int i = 0; i < TEST_TIME; i++) {
		power2_I(n[i]);
	}
	elapse = clock() - begin;
	printf("performance test for power2_I elapsed %lf ms, avg %lf ms\n\n", elapse * 1000.0 / CLOCKS_PER_SEC, elapse * 1000.0 / TEST_TIME / CLOCKS_PER_SEC);


	delete[] n;
}
Exemple #6
0
void FHT::spectrum(float* p) {
  power2(p);
  for (int i = 0; i < (num_ / 2); i++, p++)
    *p = static_cast<float>(sqrt(*p * .5));
}
Exemple #7
0
llvm::Value* CVariableDeclaration::codeGen(CodeGenContext& context)
{
	BitVariable temp(size.getAPInt(), 0);

	temp.arraySize = arraySize.getAPInt();
	temp.pinType = pinType;
	temp.refLoc = declarationLoc;

	if (context.currentBlock())
	{
		if (pinType != 0)
		{
			return context.gContext.ReportError(nullptr, EC_ErrorAtLocation, declarationLoc, "Cannot declare pins anywhere but global scope");
		}
		// Within a basic block - so must be a stack variable
		llvm::AllocaInst *alloc = new llvm::AllocaInst(context.getIntType(size), 0, id.name.c_str(), context.currentBlock());
		temp.value = alloc;
	}
	else
	{
		// GLobal variable
		// Rules for globals have changed. If we are defining a PIN then the variable should be private to this module, and accessors should be created instead. 
		if (pinType == 0)
		{
			llvm::Type* type = context.getIntType(size);
			if (arraySize.getAPInt().getLimitedValue())
			{
				llvm::APInt power2(arraySize.getAPInt().getLimitedValue() + 1, 1);
				power2 <<= arraySize.getAPInt().getLimitedValue();
				type = llvm::ArrayType::get(context.getIntType(size), power2.getLimitedValue());
			}

			if (internal)
			{
				temp.value = context.makeGlobal(type, false, llvm::GlobalValue::PrivateLinkage, nullptr, context.getSymbolPrefix() + id.name);
			}
			else
			{
				temp.value = context.makeGlobal(type, false, llvm::GlobalValue::ExternalLinkage, nullptr, context.getSymbolPrefix() + id.name);
			}
		}
		else
		{
			temp.value = context.makeGlobal(context.getIntType(size), false, llvm::GlobalValue::PrivateLinkage, nullptr, context.getSymbolPrefix() + id.name);
			switch (pinType)
			{
			case TOK_IN:
				CreateWriteAccessor(context, temp, id.module, id.name, false);
				break;
			case TOK_OUT:
				CreateReadAccessor(context, temp, false);
				break;
			case TOK_BIDIRECTIONAL:
			{
				// we need a new variable to hold the impedance mask
				bool needsImpedance = false;
				if (context.gContext.impedanceRequired.find(context.moduleName + context.getSymbolPrefix() + id.name) != context.gContext.impedanceRequired.end())
				{
					temp.impedance = context.makeGlobal(context.getIntType(size), false, llvm::GlobalValue::PrivateLinkage, nullptr, context.getSymbolPrefix() + id.name + ".HZ");
					needsImpedance = true;
				}
				CreateWriteAccessor(context, temp, id.module, id.name, needsImpedance);
				CreateReadAccessor(context, temp, needsImpedance);
			}
			break;
			default:
				return context.gContext.ReportError(nullptr, EC_InternalError, declarationLoc, "Unhandled pin type");
			}
		}

	}

	// Safety check, validate that all of the aliases and original variable match in size
	for (auto aliasset : aliases)
	{
		uint64_t bitCount = 0;
		for (auto alias : aliasset)
		{
			if (alias->size_not_value)
				bitCount += alias->sizeOrValue.getAPInt().getLimitedValue();
			else
				bitCount += alias->sizeOrValue.getAPInt().getBitWidth();
		}
		if (bitCount)
		{
			if (bitCount != size.getAPInt().getLimitedValue())
			{
				return context.gContext.ReportError(nullptr, EC_ErrorWholeLine, declarationLoc, "Alias bit count doesn't match parent bit count");
			}
		}
	}

	// Create our various aliases
	for (auto aliasset : aliases)
	{
		llvm::APInt bitPos = size.getAPInt() - 1;
		for (int a = 0; a < aliasset.size(); a++)
		{
			if (!aliasset[a]->size_not_value)
			{
				// For constants we need to update the mask and cnst values (we also need to set the initialiser properly - that will come later)

				llvm::APInt newMask = ~llvm::APInt(aliasset[a]->sizeOrValue.getAPInt().getBitWidth(), 0);
				llvm::APInt newCnst = aliasset[a]->sizeOrValue.getAPInt();

				bitPos -= llvm::APInt(bitPos.getBitWidth(), aliasset[a]->sizeOrValue.getAPInt().getBitWidth() - 1);

				if (newMask.getBitWidth() != size.getAPInt().getLimitedValue())
				{
					newMask = newMask.zext(size.getAPInt().getLimitedValue());
				}
				if (newCnst.getBitWidth() != size.getAPInt().getLimitedValue())
				{
					newCnst = newCnst.zext(size.getAPInt().getLimitedValue());
				}
				newCnst <<= bitPos.getLimitedValue();
				newMask <<= bitPos.getLimitedValue();
				temp.mask &= ~newMask;
				temp.cnst |= newCnst;

				bitPos -= llvm::APInt(bitPos.getBitWidth(), 1);
			}
			else
			{
				if (aliasset[a]->idOrEmpty.name.size() > 0)
				{
					// For identifiers, we need to create another entry in the correct symbol table and set up the masks appropriately
					// e.g. BOB[4] ALIAS CAT[2]:%01
					// would create CAT with a shift of 2 a mask of %1100 (cnst will always be 0 for these)

					bitPos -= llvm::APInt(bitPos.getBitWidth(), aliasset[a]->sizeOrValue.getAPInt().getLimitedValue() - 1);

					BitVariable alias;
					alias.arraySize = temp.arraySize;
					alias.size = temp.size;
					alias.trueSize = aliasset[a]->sizeOrValue.getAPInt();
					alias.value = temp.value;	// the value will always point at the stored local/global
					alias.cnst = temp.cnst;		// ignored
					alias.mappingRef = false;
					alias.pinType = temp.pinType;
					alias.writeAccessor = temp.writeAccessor;
					alias.writeInput = temp.writeInput;
					alias.priorValue = temp.priorValue;
					alias.fromExternal = false;
					alias.impedance = nullptr;
					alias.refLoc = declarationLoc;

					llvm::APInt newMask = ~llvm::APInt(aliasset[a]->sizeOrValue.getAPInt().getLimitedValue(), 0);
					if (newMask.getBitWidth() != size.getAPInt().getLimitedValue())
					{
						newMask = newMask.zext(size.getAPInt().getLimitedValue());
					}
					newMask <<= bitPos.getLimitedValue();
					alias.mask = newMask;		// need to generate correct mask

					alias.shft = llvm::APInt(size.getAPInt().getLimitedValue(), bitPos.getLimitedValue());
					alias.aliased = true;

					if (context.currentBlock())
					{
						if (context.locals().find(aliasset[a]->idOrEmpty.name) != context.locals().end())
						{
							return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.locals()[aliasset[a]->idOrEmpty.name].refLoc, "Duplicate '%s' (already locally defined)",aliasset[a]->idOrEmpty.name.c_str());
						}
						if (context.globals().find(aliasset[a]->idOrEmpty.name) != context.globals().end())
						{
							return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.globals()[aliasset[a]->idOrEmpty.name].refLoc, "Duplicate '%s' (shadows global variable declaration)",aliasset[a]->idOrEmpty.name.c_str());
						}
						context.locals()[aliasset[a]->idOrEmpty.name] = alias;
					}
					else
					{
						if (context.globals().find(aliasset[a]->idOrEmpty.name) != context.globals().end())
						{
							return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.globals()[aliasset[a]->idOrEmpty.name].refLoc, "Duplicate '%s' (shadows global variable declaration)",aliasset[a]->idOrEmpty.name.c_str());
						}
						context.globals()[aliasset[a]->idOrEmpty.name] = alias;
					}

					bitPos -= llvm::APInt(bitPos.getBitWidth(), 1);
				}
				else
				{
					// For an anonymous alias, just skip the bits
					bitPos -= llvm::APInt(bitPos.getBitWidth(), aliasset[a]->sizeOrValue.getAPInt().getLimitedValue() - 1);
					bitPos -= llvm::APInt(bitPos.getBitWidth(), 1);
				}
			}
		}
	}

	llvm::ConstantInt* const_intn_0 = context.getConstantInt(temp.cnst);
	if (context.currentBlock())
	{
		// Initialiser Definitions for local scope (arrays are not supported at present)
		if (context.locals().find(id.name) != context.locals().end())
		{
			return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.locals()[id.name].refLoc, "Duplicate'%s' (already locally defined)",id.name.c_str());
		}
		if (context.globals().find(id.name) != context.globals().end())
		{
			return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.globals()[id.name].refLoc, "Duplicate '%s' (shadows global variable declaration)",id.name.c_str());
		}

		if (initialiserList.empty())
		{
			llvm::StoreInst* stor = new llvm::StoreInst(const_intn_0, temp.value, false, context.currentBlock());		// NOT SURE HOW WELL THIS WILL WORK IN FUTURE
		}
		else
		{
			if (initialiserList.size() != 1)
			{
				return context.gContext.ReportError(nullptr, EC_ErrorWholeLine, declarationLoc, "Too many initialisers (note array initialisers not currently supported in local scope)");
			}

			llvm::APInt t = initialiserList[0]->getAPInt();

			if (t.getBitWidth() != size.getAPInt().getLimitedValue())
			{
				t = t.zext(size.getAPInt().getLimitedValue());
			}

			llvm::ConstantInt* constInit = context.getConstantInt(t);

			llvm::StoreInst* stor = new llvm::StoreInst(constInit, temp.value, false, context.currentBlock());
		}
		context.locals()[id.name] = temp;
	}
	else
	{
		if (context.globals().find(id.name) != context.globals().end())
		{
			return context.gContext.ReportDuplicationError(nullptr, declarationLoc, context.globals()[id.name].refLoc, "Duplicate '%s' (already globally defined)",id.name.c_str());
		}
		// Initialiser Definitions for global scope
		if (temp.arraySize.getLimitedValue())
		{
			llvm::APInt power2(arraySize.getAPInt().getLimitedValue() + 1, 1);
			power2 <<= arraySize.getAPInt().getLimitedValue();

			if (initialiserList.empty())
			{
				llvm::ConstantAggregateZero* const_array_7 = llvm::ConstantAggregateZero::get(llvm::ArrayType::get(context.getIntType(size), power2.getLimitedValue()));
				llvm::cast<llvm::GlobalVariable>(temp.value)->setInitializer(const_array_7);
			}
			else
			{
				if (initialiserList.size() > power2.getLimitedValue())
				{
					return context.gContext.ReportError(nullptr, EC_ErrorWholeLine, declarationLoc, "Too many initialisers, initialiser list bigger than array storage");
				}

				int a;
				std::vector<llvm::Constant*> const_array_9_elems;
				llvm::ArrayType* arrayTy = llvm::ArrayType::get(context.getIntType(size), power2.getLimitedValue());
				llvm::ConstantInt* const0 = context.getConstantZero(size.getAPInt().getLimitedValue());

				for (a = 0; a < power2.getLimitedValue(); a++)
				{
					if (a < initialiserList.size())
					{
						llvm::APInt t = initialiserList[a]->getAPInt();

						if (t.getBitWidth() != size.getAPInt().getLimitedValue())
						{
							t = t.zext(size.getAPInt().getLimitedValue());
						}

						const_array_9_elems.push_back(context.getConstantInt(t));
					}
					else
					{
						const_array_9_elems.push_back(const0);
					}
				}

				llvm::Constant* const_array_9 = llvm::ConstantArray::get(arrayTy, const_array_9_elems);
				llvm::cast<llvm::GlobalVariable>(temp.value)->setInitializer(const_array_9);
			}
		}
		else
		{
			if (initialiserList.empty())
			{
				llvm::cast<llvm::GlobalVariable>(temp.value)->setInitializer(const_intn_0);
				if (temp.impedance)
				{
					llvm::cast<llvm::GlobalVariable>(temp.impedance)->setInitializer(const_intn_0);
				}
			}
			else
			{
				if (initialiserList.size() != 1)
				{
					return context.gContext.ReportError(nullptr, EC_ErrorWholeLine, declarationLoc, "Too many initialisers");
				}

				llvm::APInt t = initialiserList[0]->getAPInt();

				if (t.getBitWidth() != size.getAPInt().getLimitedValue())
				{
					t = t.zext(size.getAPInt().getLimitedValue());
				}

				llvm::ConstantInt* constInit = context.getConstantInt(t);
				llvm::cast<llvm::GlobalVariable>(temp.value)->setInitializer(constInit);
			}
		}

		context.globals()[id.name] = temp;
	}

	return temp.value;
}
Exemple #8
0
void iil4mitkImage::drawTextures (iil4mitkWidget* widget)
{
  const unsigned int s = _size; // size of the tiles
  unsigned int n, m;  // number of the tiles

  n = (unsigned int) ceilf ((float) _rw / (float) (s - 2));
  m = (unsigned int) ceilf ((float) _rh / (float) (s - 2));

  /* Allocate memory for the textures */
  
  Textures* textures;
  {
    iil4mitkWidget* w;
    unsigned int available, total;
  
    //w = (widget->IsSharing () ? widget->SharedWidget () : widget);
    w = (false ? NULL : widget);
    std::map<void*,Textures*>::iterator tex_it = _textures.find (w);
    if(tex_it!=_textures.end())
      textures = tex_it->second;
    else
      textures = NULL;

    if (!textures) {
      textures = new Textures ();
      typedef std::pair <void*, std::vector<_iil4mitkTexture*>* > TexturePair;
      _textures.insert (TexturePair(w, textures));
    }
    available = textures->size (); 
    total = n * m;
    //textures->resize (total);
    int iii;
    for (unsigned int i = available; i < total; i++)
    {
      textures->push_back(new _iil4mitkTexture (w));
      iii=textures->size ();
    }
    widget->MakeCurrent ();
  }  

  /* Render the textures */

  glScalef ((float) (s-2), (float) (s-2), 1.0);
  for (unsigned int i = 0; i < n; i++)
  {
    unsigned int pos [2]; // left-top corner of the region
    unsigned int len [2]; // extent of the region
    unsigned int tex [2]; // size of the texture
    float res [2];        // resolution of the texture
    
    pos [0] = _rx+i*(s-2);
          len [0] = (pos[0]+(s-2)>_rw ? _rw-pos[0] : s-2);  
    tex [0] = power2(s);
    res [0] = 1.0f/tex[0];
    for (unsigned int j = 0; j < m; j++) 
    {
      _iil4mitkTexture* texture;
      
      texture = (*textures)[i*m+j];
      pos [1] = _ry+j*(s-2);
      len [1] = (pos[1]+(s-2)>_rh ? _rh-pos[1] : s-2);
      tex [1] = power2(s);
      res [1] = 1.0f/tex[1];
  
      //if (widget->isVisible (pos [0], pos [1], len [0], len [1])) {
      if (true) {
      // widget->makeCurrent ();  
      texture->bind ();
      // widget->makeCurrent ();  
      texture->setSize (tex[0], tex[1]);
      texture->setModel (_model);
      texture->setInterpolation (_interpolation);
      if (!texture->isValid ()) 
      {
        updateTexture (texture, pos[0], pos[1], len[0], len[1]);
      }  

      glBegin (GL_QUADS);
      glTexCoord2f (res[0], res[1]); glVertex3f (0.0, 0.0, 0.0);
      glTexCoord2f (1.0-res[0], res[1]); glVertex3f (1.0, 0.0, 0.0);
      glTexCoord2f (1.0-res[0], 1.0-res[1]); glVertex3f (1.0, 1.0, 0.0);
      glTexCoord2f (res[0], 1.0-res[1]); glVertex3f (0.0, 1.0, 0.0);
      glEnd ();
      }
      glTranslatef (0.0, 1.0, 0.0);
    }
    glTranslatef (1.0, -((float) m), 0.0);
  }
}
Exemple #9
0
void FHT::power(float* p) {
  power2(p);
  for (int i = 0; i < (num_ / 2); i++) *p++ /= 2;
}
Exemple #10
0
////////////////////////////////////////////
//
// Perform one iteration of EM algorithm 
//
// Input: 
// whmt - WHMT_struct with all parameters 
// w1 - 1-dimensional vector with data 
// ws1 - 1-dimensional vector with st.d. data (for Poisson model. This is ignored for the Gaussian case) 
// P - length of 1-dimensional vector 
// MU - PxM two-dimensional array of Gaussians means
// PS - PxM two-dimensional array of Gaussian probabilities
// SI - PxM two-dimensional array of Gaussian standard deviations
// ES - PxPxM three-dimensional array of Gaussian Markov transition probabilities 
//
// Output: 
// loglikelihood - NEW! the function returns the loglikelihood !!! 
// MU, PS, SI, ES - we change their values 
// P1 - marginal posterior probabilities: P1[i][j] = Pr(S_i = j)
// P2 - transition posterior probabilities: P1[i][j][k] = Pr(S_i=j | S_{pa(i)} = k) 
//
////////////////////////////////////////////
double emhmt_1D(WHMT_struct whmt, double *w1, double *ws1, long P, // P can be part of structure whmt ??  
	double **MU, double **PS, double **SI, double ***ES, 
	double **P1, double ***P2) // NEW: output also P1, P2 !!!! // Perform EM algorithm for 1D Poisson model 
{

	// How do we know iteration number inside the function?
	int i, j, jj, k, J, ip, level;
	double temp, t1;
	int si, ei, sni, eni;
	double loglikelihood = 0.0;

	double T, lambda; // for Poisson multi-scale model 
	//double norm_ctr = 0.0;//Unused Variable
	//double tol = 0.000001;//Unused Variable
	double min_prob = 0.000001; // don't allow probabilities smaller than this (avoid log underflows)
	double min_std = 0.000000001; //  don't allow too small standard deviations (avoid underflows) 

	//	long P=1024; // should read vector length from input 
	double **BE, **BEP, **BER, **AL; ///  **P1, ***P2; // set pointers 

	BE = new double*[P];  // beta
	BEP = new double*[P]; // beta-parent
	BER = new double*[P]; // beta-rest of tree
	AL = new double*[P];  // alpha 
//	P1 = new double*[P];  // marginal posterior
//	P2 = new double**[P]; // transition posterior 
    //printf("The value of whmt.num_states%d\n",whmt.num_states);
	for (i = 0; i < P; i++)
	{
		BE[i] = new double[whmt.num_states];
		BEP[i] = new double[whmt.num_states];
		BER[i] = new double[whmt.num_states];
		AL[i] = new double[whmt.num_states];
//		P1[i] = new double[whmt.num_states];
//		P2[i] = new double*[whmt.num_states];
//		for (j = 0; j < whmt.num_states; j++)
//			P2[i][j] = new double[whmt.num_states];
	}


	//	printf("Allocate: P=%ld, num-gaussians=%ld\n", P, whmt.num_states); 
	//	fflush(stdout); 

	double gtmp[P][MAX_STATES]; // double 2-D array //    mumatrix(P,P);
	double scale[P]; // scale parameter for each value. This is for normalization 
	double maximal_exponent[P];
	level = l2(P);

#ifdef DEBUG_PRINTS
	printf("Doing up step:\n");
	fflush(stdout);
    printf("________%d\n\n",whmt.num_states);
	for (k = 0; k < level; k++) // change all indexing to zero-based
		for (j = 0; j < whmt.num_states; j++)
			for (jj = 0; jj < whmt.num_states; jj++)
				//printf("Start EM: ES[%ld][%ld][%ld]=%lf\n", k, j, jj, ES[k][j][jj]);
#endif

//	printf("WHMT NOISE MODEL IS: %ld. Gaussian=%ld, Poisson=%ld\n", whmt.noise_model, GAUSSIAN, POISSON); fflush(stdout);
	scale[0] = 0.0;
	switch (whmt.noise_model) { // avoid underflows from too little st.d. 
	case 'N':
		// Set first scale (match Matlab) 
		for (j = 0; j < whmt.num_states; j++)
		{
			gtmp[0][j] = gauss(w1[0], 0/*MU[k][j]*/, 1/*SI[k][j]*/); // why i vs k? should be i !!!   % why use 0 and 1 and not the true MU, SI?? WTF? ONLY FOR FIRST LEVEL!!!  
			scale[0] += gtmp[0][j];
		}
		//	printf("SET SCALE[0]=%lf\n", scale[0]); 
		break; 
	case 'P': // 'gaussian':
		T = w1[0] / ws1[0]; // From Heejung's notes (approximation of likelihood) 
		maximal_exponent[0] = 0.0; //  T*T;
		for (j = 0; j < whmt.num_states; j++)
		{
			lambda = ws1[0] * ws1[0] / (ws1[0] * ws1[0] + SI[0][j] * SI[0][j]);
			maximal_exponent[0] = MAX(maximal_exponent[0], T*T*(1 - lambda) / 2);
		}
		for (j = 0; j < whmt.num_states; j++)
		{
			lambda = ws1[0] * ws1[0] / (ws1[0] * ws1[0] + SI[0][j] * SI[0][j]);
			gtmp[0][j] = sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[0]);
			scale[0] += gtmp[0][j]; //  sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[0]);
		}

		//	printf("SET SCALE[0]=%lf\n", scale[0]); 
		for (i = 0; i < P; i++)  // update ws1 (don't allow too little st.d.) 
			ws1[i] = MAX(ws1[i], min_std);
		break;
	} // end switch 
	scale[0] /= whmt.num_states; // normalize scale coefficient

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/* UP Step */
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	for (k = 0; k < level; k++) // change all indexing to zero-based
	{
		J = power2(k); // don't remove one
		si = J+1;	ei = 2*J;
		LOOPsi // start at high i 
		{
			scale[i] = 0; // initialize
			maximal_exponent[i] = 0.0; 
			for (j = 0; j < whmt.num_states; j++)
			{
				switch (whmt.noise_model) {
				case 'N': // 'gaussian':
					gtmp[i][j] = gauss(w1[i], MU[k][j], SI[k][j]); // why i vs k? should be i !!! Here do use MU, SI !!!  Always compute gtmp !!! 
					scale[i] += gtmp[i][j];
#ifdef DEBUG_PRINTS
					printf("Set i=%ld, j=%ld, k=%ld; ", i, j, k); fflush(stdout);
					printf("W[%ld]=%lf; ", i, w1[i]); fflush(stdout);
					printf("MU[%ld][%ld]=%lf; ", k, j, MU[k][j]); fflush(stdout);
					printf("SI[%ld][%ld]=%lf; ", k, j, SI[k][j]); fflush(stdout);
					printf("phi(x; mu, st.d.)[%ld][%ld]=%lf; ", i, j, gtmp[i][j]);  fflush(stdout);
					printf("scale[%ld]=%lf\n", i, scale[i]);  fflush(stdout);
#endif
					break;
				case 'P': // 'poisson'
					T = w1[i] / ws1[i]; // From Heejung's notes (approximation of likelihood) 
					lambda = ws1[i] * ws1[i] / (ws1[i] * ws1[i] + SI[k][j] * SI[k][j]);
					maximal_exponent[i] = MAX(maximal_exponent[i], T*T*(1 - lambda) / 2);
#ifdef DEBUG_PRINTS
					printf("SET lambda-scale, lambda=%lf, T=%lf ; ", lambda, T);
					fflush(stdout);
					printf("lambda-part=%lf, T-part=%lf, ", sqrt(lambda), exp(T*T*(1 - lambda) / 2 - maximal_exponent[i])); fflush(stdout);

					printf(" exponent[%ld]=%lf; exponent-normalized=%lf; maximal-exponent=%lf; ", i, T*T*(1 - lambda) / 2, T*T*(1 - lambda) / 2 - maximal_exponent[i], maximal_exponent[i]);
					fflush(stdout);
#endif
					break;
				} // end switch 
			} // end loop on state j 

#ifdef DEBUG_PRINTS
			printf("### SET-MAXEXP[%ld]=%lf ###\n", i, maximal_exponent[i]);
#endif
			switch (whmt.noise_model) {
			case 'P':
				for (j = 0; j < whmt.num_states; j++)
				{
					lambda = ws1[i] * ws1[i] / (ws1[i] * ws1[i] + SI[k][j] * SI[k][j]); // T[i] already set 
					gtmp[i][j] = sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[i]);
					scale[i] += gtmp[i][j]; //  sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[i]);
				}
				break;
			}
			scale[i] /= whmt.num_states; // normalize scale coefficient
#ifdef DEBUG_PRINTS
			printf("SET SCALE[%ld]=%lf\n\n", i, scale[i]); fflush(stdout);
#endif
		}
	} // loop on k 


	si = power2(level - 1) + 1;
	ei = P;
	k = level - 1; // set k to the last level (fine resolution, P/2 variables) 
	LOOPsi // here loop only for the last level !!! 
	{
#ifdef DEBUG_PRINTS
		printf("SET AGAIN SCALE[%ld]=%lf\n", i, scale[i]);
#endif
		for (j = 0; j < whmt.num_states; j++)
		{
			switch (whmt.noise_model) {
			case 'N': // 'gaussian':
				BE[i][j] = gtmp[i][j] / scale[i]; // set BE to begin. Problem: we may divide by zero!!!  (also: Matlab doesn't fill first one) 
				break;
			case 'P': // 'poisson':
#ifdef DEBUG_PRINTS
				printf("SET T, j=%ld w1[%ld]=%lf, ", j, i, w1[i]); // seperate into two printings 
				fflush(stdout);
				printf("ws1[%ld]=%lf\n", i, ws1[i]); // seperate into two printings 
				fflush(stdout);
#endif
				T = w1[i] / ws1[i]; // From Heejung's notes (approximation of likelihood) 
				lambda = ws1[i] * ws1[i] / (ws1[i] * ws1[i] + SI[k][j] * SI[k][j]);
//				BE[i][j] = sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[i]) / scale[i] + 1e-15;
				BE[i][j] = gtmp[i][j] / scale[i] + 1e-15; 
#ifdef DEBUG_PRINTS
				printf("SET lambda, ws1[%ld]=%lf, ", i, ws1[i]);
				fflush(stdout);
				printf(" k=%ld, j=%ld, ", k, j);
				fflush(stdout);
				printf(" SI[%ld][%ld]=%lf\n", k, j, SI[k][j]);
				fflush(stdout);
				printf("SET lambda, lambda=%lf, T=%lf ; ", lambda, T);
				fflush(stdout);
				printf(" exponent=%lf; normalize-exponent=%lf", T*T*(1 - lambda) / 2, T*T*(1 - lambda) / 2 - maximal_exponent[i]);
				fflush(stdout);
				printf(" BE[%ld][%ld]=%lf\n", i, j, BE[i][j]);
				fflush(stdout);
				
#endif
				break;
			} 					// Here end 'switch' 

#ifdef DEBUG_PRINTS
			printf("Set gtmp[%ld][%ld]=%lf, ", i, j, gtmp[i][j]);
			printf("BE[%ld][%ld] = %lf, ", i, j, BE[i][j]);  // seperate printing 
			fflush(stdout);
			printf(" scale[%ld]=%lf:\n", i, scale[i]);  // seperate printing 
			fflush(stdout);
			printf("W[%ld]=%lf; ", i, w1[i]); fflush(stdout);
			printf("MU[%ld][%ld]=%lf; ", k, j, MU[k][j]); fflush(stdout);
			printf("SI[%ld][%ld]=%lf; ", k, j, SI[k][j]); fflush(stdout);
			printf("phi(x; mu, st.d.)[%ld][%ld]=%lf; ", i, j, gtmp[i][j]);  fflush(stdout);


#endif
		} // end for loop on j (on states) 
	} // end loop on i in the k-th level 

	// Initialize to zero the top 0 level root of the WHMT tree (this messes-up when parent! probably not needed! ) 
	for (j = 0; j < whmt.num_states; j++)
		BE[0][j] = 0.0; // 1.0 / whmt.num_states;



	//	printf("Go down on levels:\n"); 
	//	fflush(stdout); 


	for (k = level - 1; k >= 1; k--) // go down on levels (except bottom level). Why repeat level-1?  
	{
		J = power2(k); // don't remove one
		si = J + 1; ei = 2 * J;
		//	 printf("Run ei=%ld, si=%ld:\n", ei, si); 
		//	 fflush(stdout); 
		//		printf("Run level k=%ld, num-gaussians=%ld,P=%ld,  Indices: si=%ld -> ei=%ld\n", 
		//			k, whmt.num_states, P, si, ei); 
		//		fflush(stdout); 

		LOOPsi
		{
			for (j = 0; j < whmt.num_states; j++)
			{
				BEP[i][j] = 0.0;
				for (jj = 0; jj < whmt.num_states; jj++) // loop on child variable Gaussian 
				{
					BEP[i][j] += ES[k][jj][j] * BE[i][jj]; // what loops should we write here?     use j or jj for BE?? 
#ifdef DEBUG_PRINTS
					printf("Updated BEP: ES[%ld][%ld][%ld]=%lf, ",
						k, j, jj, ES[k][j][jj]);
					printf(" BE[%ld][%ld]=%lf -> ",
						i, jj, BE[i][jj]);
					printf(" BEP[%ld][%ld]=%lf\n",
						i, j, BEP[i][j]);
#endif
				}
			}
		}

		/* construct Betachild matrix */
		sni = J / 2 + 1; eni = si - 1;
		for (i = sni - 1; i < eni; i++) // remove one here!!! ???
		{
			t1 = 0.0; // temp variable
			for (j = 0; j < whmt.num_states; j++)
			{
#ifdef DEBUG_PRINTS
				printf("Update temp: BEP[%ld][%ld]=%lf, ", 2 * i, j, BEP[2 * i][j]);
				printf("BEP[%ld][%ld]=%lf, prod=%lf\n", 2 * i + 1, j, BEP[2 * i + 1][j], BEP[2 * i][j] * BEP[2 * i + 1][j]);
#endif
				t1 += BEP[2 * i][j] * BEP[2 * i + 1][j];  // here +1 not -1 !! (since we removed one  from i!!)
			}
			temp = t1 / whmt.num_states;   // normalize by number of states  
#ifdef DEBUG_PRINTS
			printf("Update Scale: temp=%lf, scale[%ld]=%lf -> %lf\n", temp, i, scale[i], scale[i] * temp); fflush(stdout);
#endif
			scale[i] *= temp;

			for (j = 0; j < whmt.num_states; j++)
			{
				switch (whmt.noise_model) {
				case 'N': // 'gaussian':
					BE[i][j] = BEP[2*i][j] * BEP[2*i+1][j] * gtmp[i][j] / scale[i]; // NO TEMP (average) but (i,j) element!!! update BE !!! (WHY? No updating in C!!!) 
#ifdef DEBUG_PRINTS				
					printf("Update BE: temp=%lf, gtmp[%ld][%ld]=%lf, ", temp, i, j, gtmp[i][j]); fflush(stdout);
					printf(" scale[%ld]=%lf. ", i, scale[i]); fflush(stdout);
					printf("  BE[%ld][%ld]=%lf\n", i, j, BE[i][j]);
					fflush(stdout);
#endif
					break;
				case 'P': // 'poisson':
					T = w1[i] / ws1[i]; // From Heejung's notes : approximation to the likelihood!!!!! 
					lambda = ws1[i] * ws1[i] / (ws1[i] * ws1[i] + SI[k-1][j] * SI[k-1][j]); // Take SI from previous level !!! 
//					BE[i][j] = BEP[2*i][j] * BEP[2*i+1][j] * sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[i]) / scale[i] + 1e-15;  // is maximal_exponent even already set here? 
					BE[i][j] = BEP[2*i][j] * BEP[2*i+1][j] * gtmp[i][j] / scale[i]; // NO TEMP (average) but (i,j) element!!! update BE !!! (WHY? No updating in C!!!) 
#ifdef DEBUG_PRINTS				
					printf("USE GET lambda-scale, lambda=%lf, T=%lf ; ", lambda, T);
					printf(" <- ws1=%lf, SI=%lf; ", ws1[i], SI[k-1][j]);


					printf("Update BE: temp=%lf, lambda-T[%ld][%ld]=%lf, ", temp, i, j, sqrt(lambda)*exp(T*T*(1 - lambda) / 2 - maximal_exponent[i])); fflush(stdout);
					printf("lambda-part=%lf, T-part=%lf, ", sqrt(lambda), exp(T*T*(1 - lambda) / 2 - maximal_exponent[i])); fflush(stdout);
					printf("T^2=%lf, max-exponent=%lf ;;; ",  T*T*(1 - lambda) / 2, maximal_exponent[i]); fflush(stdout);
					printf(" scale[%ld]=%lf. ", i, scale[i]); fflush(stdout);
					printf(" BEP_prod[%ld][%ld]=%lf. ", 2 * i, j, BEP[2 * i][j] * BEP[2 * i + 1][j]); fflush(stdout);

					printf("  BE[%ld][%ld]=%lf\n\n", i, j, BE[i][j]);
					fflush(stdout);
#endif
					break;
				} // end switch 
			} // end 2nd for loop on Gaussians , j
#ifdef DEBUG_PRINTS
			printf("### USE-MAXEXP[%ld]=%lf ###\n", i, maximal_exponent[i]);
#endif
		} // end loop on i of betachild matrix 

		/* construct BER matrix */
		LOOPsi
		for (j = 0; j < whmt.num_states; j++)
		{
			ip = i / 2; // (i+1)/2; // need to subtract 1 !!! 
			BER[i][j] = BE[ip][j] / BEP[i][j];
#ifdef DEBUG_PRINTS
			printf(" NEWSETSET: BER[%ld][%ld]=%lf <-- ", i, j, BER[i][j]); fflush(stdout);
			printf(" BE[%ld][%ld]=%lf / ", ip, j, BE[ip][j]); fflush(stdout);
			printf(" BEP[%ld][%ld]=%lf\n", i, j, BEP[i][j]); fflush(stdout);
#endif

		}
	} // end loop on levels 


	//	printf("Doing down step:\n"); 
	//	fflush(stdout); 
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/* DOWN step */
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	for (j = 0; j < whmt.num_states; j++)
		AL[1][j] = PS[0][j]; // take minus 1. Set 1 or zero? 


	// NEW! Print all scale and all BE: 
#ifdef DEBUG_PRINTS
	for (i = 0; i < P; i++)
	{
		printf("All BE, scale: scale[%ld]=%lf.", i, scale[i]); fflush(stdout); // wtf is wrong with scale? 
		printf("  phi(x; mu, st.d.)[%ld][0]=%lf, phi(x; mu, st.d.)[%ld][1]= %lf\n",
			i, gtmp[i][0], i, gtmp[i][1]);
		/**
		for (j = 0; j < whmt.num_states; j++)
		{
			printf(" BE[%ld][%ld]=%lf; ", i, j, BE[i][j]); fflush(stdout);
			printf(" BEP[%ld][%ld]=%lf; ", i, j, BEP[i][j]); fflush(stdout);
			printf(" BER[%ld][%ld]=%lf\n", i, j, BER[i][j]); fflush(stdout);
		}
		**/


		//				printf(" MU[%ld][0]=%lf, MU[%ld][1]=%lf, SI[%ld][0]=%lf, SI[%ld][1]=%lf, phi(x; mu, st.d.)=%lf, %lf\n", 
		//					i, MU[i][0], i, MU[i][1], i, SI[i][0], i, SI[i][1], gtmp[i][0], gtmp[i][0]);
	}
#endif


	for (j = 0; j < whmt.num_states; j++)
	{
#ifdef DEBUG_PRINTS
		printf("Add likelihood: BE[1][%ld]=%lf, scale[1]=%lf, ", j, BE[1][j], scale[1]);
		fflush(stdout);
		printf("AL[1][%ld]=%lf\n", j, AL[1][j]);
#endif
		loglikelihood += BE[1][j] * scale[1] * AL[1][j]; // update from each variable 
	}
	loglikelihood = log(loglikelihood); // take log 


	for (k = 1; k < level; k++)
	{
#ifdef DEBUG_PRINTS
		printf("E-STEP LEVEL K=%ld\n", k);
		fflush(stdout);
#endif
		J = power2(k); // don't remove one
		si = J + 1;
		ei = 2 * J;

		LOOPsi // loop on i ?? 
		{
#ifdef DEBUG_PRINTS
			printf("E-STEP SET i=%ld\n", i);
			fflush(stdout);
#endif
			for (j = 0; j < whmt.num_states; j++)
			{
				AL[i][j] = 0.0; // set to zero !!! 
				for (jj = 0; jj < whmt.num_states; jj++)  // loop over all jj ??? 
				{
					ip = (i + 0/*1*/) / 2;
					AL[i][j] += ES[k][j][jj] * AL[ip][jj] * BER[i][jj]; // assignment for same cell? 


#ifdef DEBUG_PRINTS
					printf("E-STEP SET AL: AL[%ld][%ld]=%lf <- ", i, j, AL[i][j]);
					printf("(ES[%ld][%ld][%ld]=%lf) * ", k, j, jj, ES[k][j][jj]);
					printf("(AL[%ld][%ld]=%lf) *", ip, j, AL[ip][j]);
					printf(" (BER[%ld][%ld]=%lf)\n", i, jj, BER[i][jj]);
#endif
				}
			}
		}
	}
	//	printf("Finished all levels1:\n"); 
	//	fflush(stdout); 


	//	free_double_matrix(BEP, P, whmt.num_states);  // NO freeing of arrays !!! free_mumatrix(BEP,P,P);

	/* Compute Probablities */
	for (k = 1; k < level; k++) // what about level 1? 
	{
#ifdef DEBUG_PRINTS
		printf("Run up k=%ld, num-gaussians=%ld,P=%ld:\n", k, whmt.num_states, P);
		fflush(stdout);
#endif

		J = power2(k); // don't remove one
		si = J + 1;
		ei = 2 * J;
		LOOPsi
		{
			ip = i / 2; // parent of i (for DEBUG!)

			temp = 0.0; // initialize temp 
			for (j = 0; j < whmt.num_states; j++)
			{
				temp += (AL[i][j] * BE[i][j] + 1e-15);
				//		if(i == (si-1)) // print only once 
#ifdef DEBUG_PRINTS
				printf("E-STEP Update temp: i=%ld, j=%ld, ", i, j);
				printf(" AL[%ld][%ld]=%lf, ", i, j, AL[i][j]);
				printf(" BE[%ld][%ld]=%lf, ", i, j, BE[i][j]);
				printf(" prod=%lf, temp=%lf:\n", AL[i][j] * BE[i][j], temp);
				fflush(stdout);
#endif
			}
			for (j = 0; j < whmt.num_states; j++)
			{
				P1[i][j] = (AL[i][j] * BE[i][j] + 1e-15) / temp;

#ifdef DEBUG_PRINTS
				printf("E-STEP Set P1[%ld][%ld]=%lf, ", i, j, P1[i][j]);
				printf(" (AL[%ld][%ld]=%lf)*", i, j, AL[i][j]);
				printf("(BE[%ld][%ld]=%lf)/(temp=%lf)\n", i, j, BE[i][j], temp);
#endif

				ip = (i + 0/*1*/) / 2; // set  ip, parent of i  !!! 
				for (jj = 0; jj < whmt.num_states; jj++)
				{
#ifdef DEBUG_PRINTS
					//					printf("E-STEP Set jj=%ld\n", jj); 
					//					fflush(stdout); 
					//					printf("E-STEP Set BE=%lf ES=%lf\n", BE[i][j], ES[k][j][jj]); 
					//					printf("E-STEP Set BER=%lf temp=%lf\n", BER[i][jj], temp); 
					//					fflush(stdout); 
#endif
					//			 printf("Run-up j=%ld, jj=%ld, ip=%ld, jp=%ld, temp=%lf:\n", j, jj, ip, jp, temp); // jp not assigned !!! 
					//			 fflush(stdout); 


					P2[i][j][jj] = (BE[i][j] * ES[k][j][jj] * AL[ip][jj] * BER[i][jj] + 1e-15 / whmt.num_states) / temp; // Is it the same 'temp' as in P1? // why 1 index? should be zero? what probabilities are we calculating here? 
#ifdef DEBUG_PRINTS
					printf("E-STEP Set P2[%ld][%ld][%ld]=%lf: ", i, j, jj, P2[i][j][jj]);
					printf(" (BE[%ld][%ld]=%lf)*", i, j, BE[i][j]);
					printf("(ES[%ld][%ld][%ld]=%lf)*", k, j, jj, ES[k][j][jj]);
					printf("(AL[%ld][%ld]=%lf)*", ip, jj, AL[ip][jj]);
					printf("(BER[%ld][%ld]=%lf)/(temp=%lf)\n", i, jj, BER[i][jj], temp);
					fflush(stdout);
#endif


					//			 printf("Run-up j=%ld, jj=%ld, assigned P2:\n", j, jj);
					//			 fflush(stdout); 

				} // loop on jj 
#ifdef DEBUG_PRINTS
				norm_ctr = 0.0;
				for (jj = 0; jj < whmt.num_states; jj++)
					norm_ctr += P2[i][j][jj]; 
				if (ABS(norm_ctr - P1[i][j])>tol)
					printf("MATCH ERROR! P1[%ld][%ld]=%lf, sum P2=%lf\n", i, j, P1[i][j], norm_ctr);
#endif 


			} // loop on j 
			/**/
#ifdef DEBUG_PRINTS
			norm_ctr = 0.0; 
			for (j = 0; j < whmt.num_states; j++)
				norm_ctr += P1[i][j];
			if (ABS(norm_ctr - 1.0)>tol)
			{
				printf("ERROR! P1[%ld] NOT_NORMAL SUM=%lf\n", i, norm_ctr); fflush(stdout); return -999999.9999;
			}


			norm_ctr = 0.0;
			for (jj = 0; jj < whmt.num_states; jj++)
			{
				for (j = 0; j < whmt.num_states; j++)
					norm_ctr += P2[i][j][jj];
			}
			if (ABS(norm_ctr - 1.0)>tol)
			{
				printf("ERROR! P2[%ld][XXX][%ld] NOT_NORMAL SUM=%lf\n", i, jj, norm_ctr); fflush(stdout); return -999999.9999;
			}

			if (ip>1)
			for (jj = 0; jj < whmt.num_states; jj++)
			{
				norm_ctr = 0.0; 
				for (j = 0; j < whmt.num_states; j++)
					norm_ctr += P2[i][j][jj];
				if (ABS(norm_ctr - P1[ip][jj])>tol)
				{
					printf("MATCH PRRENT ERROR! P1[%ld][%ld]=%lf, sum P2=%lf\n", ip, jj, P1[ip][jj], norm_ctr); fflush(stdout); return -999999.9999;
					//				printf("ERROR! P2[%ld][XXX][%ld] NOT_NORMAL SUM=%lf\n", i, jj, norm_ctr); 
				}
			}

#endif
			/**/
		} // loop on i within level k  
	} // loop on k 

	// Set 1 separately (why?)
	temp = 0.0;
	for (j = 0; j < whmt.num_states; j++)
		temp += AL[1][j] * BE[1][j];
	for (j = 0; j < whmt.num_states; j++)
	{
		P1[1][j] = AL[1][j] * BE[1][j] / temp;  // set last one - why separately? 
#ifdef DEBUG_PRINTS
		printf("SPECIAL SET: P1[1][%ld] = %lf, (AL[1][%ld]=%lf)*", j, PS[1][j], j, AL[1][j]);
		printf("(BE[1][%ld]=%lf)/(temp=%lf) \n", j, BE[1][j], temp);
#endif
	}


	//	printf("Finished all levels2:\n"); 
	//	fflush(stdout); 

	/**
	for(i=0; i<P; i++) // where is the loop on j?
	{
	for(j=0; j<whmt.num_states; j++)
	{
	#ifdef DEBUG_PRINTS
	printf("Set i=%ld, j=%ld, P[%ld][%ld]=%lf gtmp=%lf, scale[%ld]=%lf:\n",
	i, j, i, j, BE[i][j], gtmp[i][j], i, scale[i]);
	fflush(stdout);
	#endif
	}
	}
	**/


	//	printf("Doing M-Step:\n"); 
	//	fflush(stdout); 

	/********************************************************************************************/
	/************************************* M step ***********************************************/
	/********************************************************************************************/
	for (j = 0; j < whmt.num_states; j++)  // Set Zero-based indices 
	{
		PS[0][j] = P1[1][j]; // copy stuff?? why? because no need for averaging  (just one value) 
		//		printf("SPECIAL SET: PS[0][%ld] = %lf\n", j, PS[0][j]); 
	}

	double p_level_ave[MAX_STATES];
	double p_level_markov_ave[MAX_STATES][MAX_STATES];
	double mu_level_ave[MAX_STATES];
	double sigma_level_ave[MAX_STATES];

	for (k = 1; k < level; k++) // go over all levels EXCEPT first !! 
	{
		//		printf("Doing M-Step Level %ld:\n", k); 
		//		fflush(stdout); 

		J = power2(k); // don't remove one
		si = J+1; ei = 2*J;

		for (j = 0; j < whmt.num_states; j++)
		{
			p_level_ave[j] = 0.0; mu_level_ave[j] = 0.0; sigma_level_ave[j] = 0.0;
			for (jj = 0; jj < whmt.num_states; jj++)
				p_level_markov_ave[j][jj] = 0.0;
		}
		LOOPsi
		{
			for (j = 0; j < whmt.num_states; j++)
			{
				p_level_ave[j] += P1[i][j];
				mu_level_ave[j] += w1[i] * P1[i][j]; // we don't need mu - not updated !!! // tmus+=w1[i]*P1[i][j];
				for (jj = 0; jj < whmt.num_states; jj++) // what's this? 
					p_level_markov_ave[j][jj] += P2[i][j][jj];  // take average for each jj? //					tesss+=P2[i][j][jj];

#ifdef DEBUG_PRINTS
				printf("M-STEP Update  P1[%ld][%ld]=%lf, ", i, j, P1[i][j]);
				printf(" P2[%ld][%ld][0]=%lf, ", i, j, P2[i][j][0]);
				printf(" P2[%ld][%ld][1]=%lf\n", i, j, P2[i][j][1]);
				fflush(stdout);
#endif
			}
		}



		//		printf("Doing M-Step Level %ld:, Finished first loop on i \n", k); 
		//		fflush(stdout); 

		for (j = 0; j < whmt.num_states; j++)  // update PS. One-dimensional 
		{
			PS[k][j] = MAX(min_prob, p_level_ave[j] / J); // don't let PS be too low 
#ifdef DEBUG_PRINTS
			printf("Doing M-Step Level %ld: Update PS[%ld][%ld]=%lf\n", k, k, j, PS[k][j]);
			fflush(stdout);
			printf("CHECK M-STEP NORMALIZATION: P_LEVEL_AVE[%ld][%ld]=%lf ; ", k, j, p_level_ave[j]); fflush(stdout);
			for (jj = 0; jj < whmt.num_states; jj++) // what's this? 
				printf("P_LEVEL_MARKOV_AVE[%ld][%ld][%ld]=%lf, ", k, j, jj, p_level_markov_ave[j][jj]); 
			printf("\n"); fflush(stdout); 

#endif
		}

		for (j = 0; j < whmt.num_states; j++) // update ES. Based on what? should have both Gaussians !!! 
			for (jj = 0; jj < whmt.num_states; jj++)
			{
				ES[k][j][jj] = MAX(min_prob, p_level_markov_ave[j][jj]) / (J*PS[k - 1][jj]);  // NOTE! we use k-1 here // normalize by upper level for PS // tesss/(J*PS[k-1][j]);
#ifdef DEBUG_PRINTS
				printf("Doing M-Step: Update ES[%ld][%ld][%ld]=%lf, ", k, j, jj, ES[k][j][jj]); fflush(stdout); 
				printf("p_markov[%ld][%ld]=%lf, ", j, jj, p_level_markov_ave[j][jj] / J);  fflush(stdout);
				printf(" PS[%ld][%ld]=%lf\n", k - 1, j, PS[k - 1][j]);	fflush(stdout);
#endif
			}


			/**
#ifdef DEBUG_PRINTS
			for (jj = 0; jj < whmt.num_states; jj++)  // loop over all jj ??? 
			{
				norm_ctr = 0.0; 
				for (j = 0; j < whmt.num_states; j++)
					norm_ctr += ES[i][j][jj];
				if (ABS(norm_ctr - 1.0)>tol)
				{
					printf("ERROR! ES[%ld][XXX][%ld] NOT_NORMAL SUM=%lf\n", i, jj, norm_ctr); fflush(stdout); return -999999.9999;
				}
			}

#endif
			***/

		/* uncommnet these two lines to use nonzero means
		MU[k][1].S = tmus;
		MU[k][1].L = tmul;
		*/


		//			printf("Doing M-Step Level %ld: Start updating SI\n", k); 
		//			fflush(stdout); 


		for (j = 0; j < whmt.num_states; j++) // update standard deviations 
			SI[k][j] = 0.0;
		LOOPsi
		{
			for (j = 0; j < whmt.num_states; j++)
			{
				SI[k][j] += (w1[i] - MU[k][j])*(w1[i] - MU[k][j])*P1[i][j];
#ifdef DEBUG_PRINTS
				printf("M-STEP Update STD i=%ld, j=%ld,  ", i, j);
				printf("SI[%ld][%ld]=%lf, ", k, j, SI[k][j]);
				printf(" P1[%ld][%ld]=%lf\n", i, j, P1[i][j]);
				fflush(stdout);
#endif
			}
		}
		for (j = 0; j < whmt.num_states; j++)
		{
			SI[k][j] /= (J*PS[k][j]); // why normalize by PS? 
			SI[k][j] = MAX(SI[k][j], min_std); // avoid too little st.d. 
		}

	} // end loop on k levels 
	//	printf("Finished all levels2:\n"); 
	//	fflush(stdout); 

#ifdef DEBUG_PRINTS
	for (k = 0; k < level; k++) // go over all levels except first !! 
	{
		for (j = 0; j < whmt.num_states; j++)
		{
			printf("After M-STEP: New Parameters: [ES[%ld][%ld][0]=%lf, ", k, j, ES[k][j][0]);
			printf(" ES[%ld][%ld][1]=%lf] ; ", k, j, ES[k][j][1]);
			printf(" PS[%ld][%ld]=%lf, ", k, j, PS[k][j]);
			printf(" MU[%ld][%ld]=%lf, ", k, j, MU[k][j]);
			printf("SI[%ld][%ld]=%lf\n", k, j, SI[k][j]);
		}


	}	// Print all new parameters: 
#endif


	// Transfer all P2 to conditional 
	long P2_conditional = 1; 
	if (P2_conditional)
		for (k = 1; k < level; k++) // what about level 1? 
		{
			J = power2(k); // don't remove one
			si = J + 1;	ei = 2 * J;
			sni = J / 2 + 1; eni = si - 1;
			///for (i = sni - 1; i < eni; i++) // remove one here!!! ??? loop on parents. What about offspring??? 
			LOOPsi
			{
				ip = i / 2; 
				for (j = 0; j < whmt.num_states; j++)
					for (jj = 0; jj < whmt.num_states; jj++)
					if (P1[ip][jj]>0)
						P2[i][j][jj] /= P1[ip][jj]; // normalize posterior probabilities 
					else
						P2[i][j][jj] = 1.0 / whmt.num_states; // normalize posterior probabilities
			}
		}

	// Free memory
	for (i = 0; i < P; i++)
	{
        delete [] BE[i];
        delete [] BEP[i];
        delete [] BER[i];
        delete [] AL[i]; //  P1[i], P2[i];
    }
    delete [] BE;
    delete [] BEP;
    delete [] BER;
    delete [] AL; // DO NOT delete P1,P2 !!!  , P1, P2;



	return(loglikelihood); // new! return log-likelihood 


} // end function emhmt_1D
//usage:feature = feaGen( training,depth,ndim);
//state:finishing
//version:v1
//notation: maximum size of buffer is 1024
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray * prhs[])
{
	// check the input parameter
	if (nlhs != 1)
		mexErrMsgTxt(" error in using feaGen, one output is needed");
	if (nrhs != 3)
		mexErrMsgTxt(" error in using feaGen, three input are needed");
	if (!mxIsCell(prhs[0]))
	{
		mexErrMsgTxt(" input type error");
	}

	mxArray * pp, *ptemp;
	mwSize M;
	mwSize depth, ndim;
	int i, j, k, m, n, intTemp;
	double *pointer;

	//get parameter
	depth = mxGetScalar(prhs[1]);
	ndim = mxGetScalar(prhs[2]);
	M = mxGetM(prhs[0]);
	//alloc the space

	char *buf = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char));

	char ** fea;
	fea = (char**) mxMalloc((unsigned int) ndim * sizeof(char*));
	for (i = 0; i < ndim; i++)
	{
		fea[i] = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char));
	}

	feature fv(ndim, depth, M);

	for (i = 0; i < M; i++)
	{
		fv.addLine();
		ptemp = mxGetCell(prhs[0], i);
		if (mxGetString(ptemp, buf, (unsigned int) MAXSIZE))
			mexErrMsgTxt("error in the buffer of this function:line53");
#ifdef debug
		mexPrintf("%s",buf);
#endif
		for (j = 0; buf[j] != '\0'; j++)
		{
			intTemp = char2num(buf[j]);
			for (int l = 0; l < ndim; l++)
			{

				fea[l][j] = (int)(intTemp & 0x1) + '0';
				intTemp >>= 1;
			}
		}

		int len = j;
#ifdef debug
		mexPrintf("%s",len);
#endif
		char *temp;
		temp = (char*) mxMalloc((ndim * depth + 1) * sizeof(char));
		for (j = 0; j <= len - depth; j++)
		{
			intTemp = 0;
			int mm, nn;
			for (nn = 0; nn < ndim; nn++)
			{
				for (mm = 0; mm < depth; mm++)
				{
					temp[intTemp++] = fea[nn][mm + j];
				}
			}
			*(temp + ndim * depth) = '\0';
			intTemp = ndim * depth;
			int index = to2num(temp, intTemp);
			if( index < 0 || index > power2(ndim,depth))
			{
				mexErrMsgTxt("error in input format line:90");
			}
			fv.store(index);
		}
		mxFree(temp);

	}

	mxFree(buf);
	for (i = 0; i < ndim; i++)
	{
		mxFree(fea[i]);
	}
	mxFree(fea);

	int lineSize = fv.getLineSize();
	plhs[0] = mxCreateDoubleMatrix(fv.getLen(), lineSize, mxREAL);
	pointer = mxGetPr(plhs[0]);
	fv.transaction(pointer);

}
      int32_t random (int32_t left, int32_t right) {
        if (left >= right) {
          return left;
        }

        if (left == INT32_MIN && right == INT32_MAX) {
          return static_cast<int32_t>(device->random());
        }

        uint32_t range = static_cast<uint32_t>(right - left + 1);

        switch (range) {
          case 0x00000002: return power2(left, 0x00000002 - 1);
          case 0x00000004: return power2(left, 0x00000004 - 1);
          case 0x00000008: return power2(left, 0x00000008 - 1);
          case 0x00000010: return power2(left, 0x00000010 - 1);
          case 0x00000020: return power2(left, 0x00000020 - 1);
          case 0x00000040: return power2(left, 0x00000040 - 1);
          case 0x00000080: return power2(left, 0x00000080 - 1);
          case 0x00000100: return power2(left, 0x00000100 - 1);
          case 0x00000200: return power2(left, 0x00000200 - 1);
          case 0x00000400: return power2(left, 0x00000400 - 1);
          case 0x00000800: return power2(left, 0x00000800 - 1);
          case 0x00001000: return power2(left, 0x00001000 - 1);
          case 0x00002000: return power2(left, 0x00002000 - 1);
          case 0x00004000: return power2(left, 0x00004000 - 1);
          case 0x00008000: return power2(left, 0x00008000 - 1);
          case 0x00010000: return power2(left, 0x00010000 - 1);
          case 0x00020000: return power2(left, 0x00020000 - 1);
          case 0x00040000: return power2(left, 0x00040000 - 1);
          case 0x00080000: return power2(left, 0x00080000 - 1);
          case 0x00100000: return power2(left, 0x00100000 - 1);
          case 0x00200000: return power2(left, 0x00200000 - 1);
          case 0x00400000: return power2(left, 0x00400000 - 1);
          case 0x00800000: return power2(left, 0x00800000 - 1);
          case 0x01000000: return power2(left, 0x01000000 - 1);
          case 0x02000000: return power2(left, 0x02000000 - 1);
          case 0x04000000: return power2(left, 0x04000000 - 1);
          case 0x08000000: return power2(left, 0x08000000 - 1);
          case 0x10000000: return power2(left, 0x10000000 - 1);
          case 0x20000000: return power2(left, 0x20000000 - 1);
          case 0x40000000: return power2(left, 0x40000000 - 1);
          case 0x80000000: return power2(left, 0x80000000 - 1);
        }

        return other(left, range);
      }
//Creating another function this function returns x^4
int power4(int x){
	
	return power2(x) * power2(x);
}
Exemple #14
0
int main()
{
    for (int i = 0; i < 10; ++i) 
        std::cout << power2(i) << " ";
    std::cout << std::endl;
}
int power2 (int x, int n)
{
	if (n == 0) return 1;
	else if ((n % 2) == 0) return power2(x, n/2) * power2(x, n/2) ;
	else return x * power2(x, n-1);
}
Exemple #16
0
int main(int argc, char *argv[])
{
    int argn = argc;
    char *in = NULL;
    char *out = NULL;
    char *password = NULL;
    bool decrypt = false;
    bool verbose = false;
    bool overwrite = false;
    bool longrand = false;
    char inBuff = 0;
    char outBuff = 0;
    char place = 0;
    int passchar = 0;
    int loopn = 0;

    printf(MSG_SPASH);

    if(argc <= 1)
    {
        printf("%s%s", MSG_HELP, MSG_DONE);
        return err_noargs;
    }

    while((argn--) > 1)
    {
        if(!strcmp(argv[argn], ARG_HELP))
        {
            printf("%s%s", MSG_HELP, MSG_DONE);
            return err_helpGiven;
        }

        else if(!strcmp(argv[argn - 1], ARG_IN))
        {
            in = argv[argn];
        }

        else if(!strcmp(argv[argn - 1], ARG_PASS))
        {
            password = argv[argn];
        }

        else if(!strcmp(argv[argn - 1], ARG_OUT))
        {
            out = argv[argn];
        }

        else if(!strcmp(argv[argn], ARG_DECRYPT))
        {
            decrypt = true;
        }

        else if(!strcmp(argv[argn], ARG_VERBOSE))
        {
            verbose = true;
        }

        else if(!strcmp(argv[argn], ARG_OVERWRITE))
        {
            overwrite = true;
        }

        else if(!strcmp(argv[argn], ARG_LONGRAND))
        {
            longrand = true;
        }
    }

    if(in == NULL)
    {
        printf("%s%s%s", MSG_NOIN, MSG_HELP, MSG_DONE);
        return err_noin;
    }

    if(password == NULL)
    {
        printf(MSG_GIVEPASS);
        password = fmakes(stdin);
    }

    if(!(password = strToBase8(password)))
    {
        printf("%s%s", MSG_ALLOCERR, MSG_DONE);
        return err_alloc;
    }

    if(verbose == true) printf("%s%s\n", MSG_BASE8EQU, password);

    if(out == NULL)
    {
        out = calloc(
            strlen(in) + strlen(FILEEXT) + sizeof(char), sizeof(char));

        if(out == NULL)
        {
            printf("%s%s", MSG_ALLOCERR, MSG_DONE);
            return err_alloc;
        }

        strcat(out, in);
        strcat(out, FILEEXT);
    }

    if(!strcmp(out, in))
    {
        printf("%s%s", MSG_CANNOTWTI, MSG_DONE);
        return 0;
    }

    if(!(inFile = fopen(in, "rb")))
    {
        printf("%s%s", MSG_INNOTREAL, MSG_DONE);
        return err_innotreal;
    }

    if((outFile = fopen(out, "rb")) && overwrite == false)
    {
        printf(MSG_OUTEXISTS);
        scanf("%c", &overwrite);
        if(overwrite != 'y' && overwrite != 'Y')
        {
            printf("%s%s", MSG_WILLNOT, MSG_DONE);
            return err_willnot;
        }
    }

    if(!(outFile = fopen(out, "wb")))
    {
        printf("%s%s", MSG_OUTCANT, MSG_DONE);
        return err_outcant;
    }

    fseek(inFile, 0, SEEK_SET);
    fseek(outFile, 0, SEEK_SET);

    if(decrypt == true)
    {
        printf("%s%s%s\n", in, MSG_TOD, out);
        while(!feof(inFile))
        {
            if(fread(&inBuff, sizeof(inBuff), 1, inFile) != 1 && !feof(inFile))
            {
                printf("%s%s", MSG_FREAD, MSG_DONE);
                closeAll();
                return err_fread;
            }

            place = power2(loopn);

            if(getBit(inBuff, *(password + passchar) - '0')) outBuff += place;

            passchar ++;

            if(!(*(password + passchar)))
            {
                passchar = 0;
            }

            loopn ++;

            if(loopn > eight)
            {
                if(fwrite(&outBuff, sizeof(outBuff), 1, outFile) != 1)
                {
                    printf("%s%s", MSG_FWRITE, MSG_DONE);
                    closeAll();
                    return err_fwrite;
                }
                loopn = 0;
                outBuff = 0;
            }
        }
    }

    else
    {
        if(longrand == true && (randomFile = fopen("/dev/random", "rb")))
        {
            printf(MSG_LONGRAND);
        }
        else if((randomFile = fopen("/dev/urandom", "rb")))
        {
            if(verbose == true) printf(MSG_URAND);
        }
        else
        {
            printf("%s%s", MSG_NORAND, MSG_DONE);
        return err_norand;
        }

        printf("%s%s%s\n", in, MSG_TOE, out);
        loopn = eight + 1;
        while(!feof(inFile))
        {
            if(loopn > eight)
            {
                if(fread(&inBuff, sizeof(inBuff), 1, inFile) != 1 &&
                    !feof(inFile))
                {
                    printf("%s%s", MSG_FREAD, MSG_DONE);
                    closeAll();
                    return err_fwrite;
                }
                loopn = 0;
            }

            if(randomFile == NULL) outBuff = rand();
            else if(fread(&outBuff, sizeof(char), 1, randomFile) != 1)
            {
                printf("%s%s", MSG_RANDERR, MSG_DONE);
                closeAll();
                return err_randerr;
            }

            place = power2(*(password + passchar) - '0');

            if(getBit(inBuff, loopn)) outBuff |= place;
            else outBuff &= ~place;

            if(fwrite(&outBuff, sizeof(outBuff), 1, outFile) != 1)
            {
                printf("%s%s", MSG_FWRITE, MSG_DONE);
                closeAll();
                return err_fwrite;
            }

            loopn ++;
            passchar ++;

            if(!(*(password + passchar)))
            {
                passchar = 0;
            }
        }
    }

    closeAll();

    printf(MSG_DONE);
    return none;
}