Пример #1
0
unsigned int *
mpow(unsigned int *a, unsigned int n)
{
	unsigned int *aa, *t;

	a = mcopy(a);

	aa = mint(1);

	for (;;) {

		if (n & 1) {
			t = mmul(aa, a);
			mfree(aa);
			aa = t;
		}

		n >>= 1;

		if (n == 0)
			break;

		t = mmul(a, a);
		mfree(a);
		a = t;
	}

	mfree(a);

	return aa;
}
Пример #2
0
int
compare_rationals(U *a, U *b)
{
	int t;
	unsigned int *ab, *ba;
	ab = mmul(a->u.q.a, b->u.q.b);
	ba = mmul(a->u.q.b, b->u.q.a);
	t = mcmp(ab, ba);
	mfree(ab);
	mfree(ba);
	return t;
}
Пример #3
0
int fib_mt(int n)
{
	int a[2][2]={1,1,1,0};
	int c[2][2]={1,0,1,0};
	int f[2][2]={1,1,1,1};
	int i;
	for(i=n-2;i>0;i=i>>1) {
		if(i&1) mmul(c,c,a);
		mmul(a,a,a);
	}
	mmul(c,c,f);
	return c[0][0];
}
Пример #4
0
void
qsub(void)
{
	unsigned int *a, *ab, *b, *ba, *c;

	save();

	p2 = pop();
	p1 = pop();

	ab = mmul(p1->u.q.a, p2->u.q.b);
	ba = mmul(p1->u.q.b, p2->u.q.a);

	a = msub(ab, ba);

	mfree(ab);
	mfree(ba);

	// zero?

	if (MZERO(a)) {
		mfree(a);
		push(zero);
		restore();
		return;
	}

	b = mmul(p1->u.q.b, p2->u.q.b);

	c = mgcd(a, b);

	MSIGN(c) = MSIGN(b);

	p1 = alloc();

	p1->k = NUM;

	p1->u.q.a = mdiv(a, c);
	p1->u.q.b = mdiv(b, c);

	mfree(a);
	mfree(b);
	mfree(c);

	push(p1);

	restore();
}
Пример #5
0
static unsigned int *
__factorial(int n)
{
	int i;
	unsigned int *a, *b, *t;

	if (n == 0 || n == 1) {
		a = mint(1);
		return a;
	}

	a = mint(2);

	b = mint(0);

	for (i = 3; i <= n; i++) {
		b[0] = (unsigned int) i;
		t = mmul(a, b);
		mfree(a);
		a = t;
	}

	mfree(b);

	return a;
}
Пример #6
0
void mpow(Matrix &r, int n)
{
    static Matrix m;
    int i, j;
    
    memcpy(&m, &r, sizeof(Matrix));
    memset(&r, 0, sizeof(r));
    r.d = m.d;
    for (int i = 0; i < r.d; i++)
        r.a[i][i] = 1;
    
    for (; n > 0; n >>= 1) {
        if (n & 1) mmul(r, m);
        mmul(m, m);
    }
}
Пример #7
0
matrix acquire(int vget, int curl, int curr, int l, int r) {
    if (l > r) {
        return id;
    } else if (l == curl && r == curr) {
        return d[vget];
    } else {
        int mid = (curl + curr) / 2;
        return mmul(acquire(vget * 2, curl, mid, l, min(mid, r)), acquire(vget * 2 + 1, mid + 1, curr, max(mid + 1, l), r));
    }
}
Пример #8
0
void build(int vget, int curl, int curr) {
    if (curl != curr) {
        int mid = (curl + curr) / 2;
        build(vget * 2, curl, mid);
        build(vget * 2 + 1, mid + 1, curr);
        d[vget] = mmul(d[vget * 2], d[vget * 2 + 1]);
    } else {
        d[vget] = ms[curl - 1];
    }
}
Пример #9
0
void Householder<T>::mulLeft(NDArray<T>& matrix, const NDArray<T>& tail, const T coeff) {
	
	// if(matrix.rankOf() != 2)
	// 	throw "ops::helpers::Householder::mulLeft method: input array must be 2D matrix !";	

	if(matrix.sizeAt(0) == 1)   
    	matrix *= (T)1. - coeff;
  	
  	else if(coeff != (T)0.) {

  		NDArray<T>* bottomPart =  matrix.subarray({{1, matrix.sizeAt(0)}, {}});
		NDArray<T> bottomPartCopy = *bottomPart; 

		if(tail.isColumnVector()) {

			NDArray<T> column = tail;
			NDArray<T>* row = tail.transpose();						
    		NDArray<T> resultingRow = mmul(*row, bottomPartCopy);
    		NDArray<T>* fistRow = matrix.subarray({{0,1}, {}});
    		resultingRow += *fistRow;        	
    		*fistRow -= resultingRow * coeff;	
    		*bottomPart -= mmul(column, resultingRow) * coeff;    		

			delete row;
			delete fistRow;
		}
		else {
			
			NDArray<T> row = tail;
			NDArray<T>* column = tail.transpose();
    		NDArray<T> resultingRow = mmul(row, bottomPartCopy);
    		NDArray<T>* fistRow = matrix.subarray({{0,1}, {}});
    		resultingRow += *fistRow;        	
    		*fistRow -= resultingRow * coeff;
    		*bottomPart -= mmul(*column, resultingRow) * coeff;    	

			delete column;
			delete fistRow;
		}	    	    	
		delete bottomPart;
	}
}
Пример #10
0
void Householder<T>::mulRight(NDArray<T>& matrix, const NDArray<T>& tail, const T coeff) {

	// if(matrix.rankOf() != 2)
	// 	throw "ops::helpers::Householder::mulRight method: input array must be 2D matrix !";
	
	if(matrix.sizeAt(1) == 1)   
    	matrix *= (T)1. - coeff;
  	
  	else if(coeff != (T)0.) {

  		NDArray<T>* rightPart =  matrix.subarray({{}, {1, matrix.sizeAt(1)}});
		NDArray<T> rightPartCopy = *rightPart; 
		NDArray<T>* fistCol = matrix.subarray({{},{0,1}});

  		if(tail.isColumnVector()) {

			NDArray<T> column = tail;
			NDArray<T>* row = tail.transpose();						
    		NDArray<T> resultingCol = mmul(rightPartCopy, column);    		
    		resultingCol += *fistCol;        	
    		*fistCol -= resultingCol * coeff;	
    		*rightPart -= mmul(resultingCol, *row) * coeff;    		

			delete row;			
		}
		else {
			
			NDArray<T> row = tail;
			NDArray<T>* column = tail.transpose();
    		NDArray<T> resultingCol = mmul(rightPartCopy, *column);    		
    		resultingCol += *fistCol;        	
    		*fistCol -= resultingCol * coeff;
    		*rightPart -= mmul(resultingCol, row) * coeff;

			delete column;
			
		}	    	    	
  		delete rightPart;
  		delete fistCol;
	}
}
Пример #11
0
/* Stub Main program */
int main(int argc, char ** argv){
	int error;
	int result;
	int methodID;
	int immediateExit;

	immediateExit = ngexStubAnalyzeArgumentWithExit(
		argc, argv, &remoteClassInfo, &error);
	if (immediateExit != 0) {
		exit(0);
	}


	result = ngexStubInitialize(argc, argv, &remoteClassInfo, &error);
	if (result != 1) {
		goto ng_stub_end;
	}

	while(1) {
		result = ngexStubGetRequest(&methodID, &error);
		if (result != NGEXI_INVOKE_METHOD) break;
		ngexStubCalculationStart(&error);
		switch (methodID) {
		case 0:
		{         /* __default__ */
			long n;
			double *A;
			double *B;
			double *C;
		ngexStubGetArgument(0,&n,&error);
		ngexStubGetArgument(1,&A,&error);
		ngexStubGetArgument(2,&B,&error);
		ngexStubGetArgument(3,&C,&error);
		mmul(n,A,B,C);
		}
		break;
		default:
			fprintf(stderr, "unknown method number");
		}
		result = ngexStubCalculationEnd(&error);
		if (result == 1){
		    continue;
		} else {
		    break;
		}
	}
ng_stub_end:
	ngexStubFinalize(&error);

	exit(0);
}
Пример #12
0
void main()
{
	int i, j;
	double eps;

	eps = 1.0e-6;

	for(i = 0; i < 3; i++)
	  for(j = 0; j < 3; j++)
	    aa[i][j] = a[i][j];

	minver(3, 3, eps);
	for(i = 0; i < 3; i++)
	  for(j = 0; j < 3; j++)
	    a_i[i][j] = a[i][j];

	mmul(3, 3, 3, 3);
}
Пример #13
0
unsigned int *
msqrt(unsigned int *n)
{
	int i, k, kk;
	unsigned int m, *x, *y;

	if (MLENGTH(n) == 1 && n[0] == 0) {
		x = mint(0);
		return x;
	}

	// count number of bits

	k = 32 * (MLENGTH(n) - 1);

	m = n[MLENGTH(n) - 1];

	while (m) {
		m >>= 1;
		k++;
	}

	k = (k - 1) / 2;

	// initial guess

	kk = k / 32 + 1;
	x = mnew(kk);
	MSIGN(x) = 1;
	MLENGTH(x) = kk;
	for (i = 0; i < kk; i++)
		x[i] = 0;
	mp_set_bit(x, k);

	while (--k >= 0) {
		mp_set_bit(x, k);
		y = mmul(x, x);
		if (mcmp(y, n) == 1)
			mp_clr_bit(x, k);
		mfree(y);
	}

	return x;
}
Пример #14
0
void print_orires_log(FILE *log,t_fcdata *fcd)
{
  int           ex,i,j,nrot;
  bool          bZero;
  matrix        S,TMP;
  t_oriresdata  *od;
  static double **M=NULL,*eig,**v;
  
  od = &(fcd->orires);

  if (M == NULL) {
    snew(M,DIM);
    for(i=0; i<DIM; i++)
      snew(M[i],DIM);
    snew(eig,DIM);
    snew(v,DIM);
    for(i=0; i<DIM; i++)
      snew(v[i],DIM);
  }
  
  for(ex=0; ex<od->nex; ex++) {
    /* Rotate the S tensor back to the reference frame */
    mmul(od->R,od->S[ex],TMP);
    mtmul(TMP,od->R,S);
    for(i=0; i<DIM; i++)
      for(j=0; j<DIM; j++)
	M[i][j] = S[i][j];
    
    jacobi(M,DIM,eig,v,&nrot);

    j=0;
    for(i=1; i<DIM; i++)
      if (sqr(eig[i]) > sqr(eig[j]))
	j=i;
    
    fprintf(log,"  Orientation experiment %d:\n",ex+1);
    fprintf(log,"    order parameter: %g\n",eig[j]);
    for(i=0; i<DIM; i++)
      fprintf(log,"    eig: %6.3f   %6.3f %6.3f %6.3f\n",
	      (fabs(eig[j])>GMX_REAL_MIN) ? eig[i]/eig[j] : 0,v[XX][i],v[YY][i],v[ZZ][i]);
    fprintf(log,"\n");
  }
}
Пример #15
0
void
benchmark (void)
{
  int i, j;
  float eps;

  eps = 1.0e-6;

  for(i = 0; i < 3; i++)
    for(j = 0; j < 3; j++)
      aa[i][j] = a[i][j];

  minver(3, 3, eps);
  for(i = 0; i < 3; i++)
    for(j = 0; j < 3; j++)
      a_i[i][j] = a[i][j];

  mmul(3, 3, 3, 3);
}
Пример #16
0
NDArray<T> Householder<T>::evalHHmatrix(const NDArray<T>& x) {

	// input validation
	if(!x.isVector() && !x.isScalar())
		throw "ops::helpers::Householder::evalHHmatrix method: input array must be vector or scalar!";

	NDArray<T> w((int)x.lengthOf(), 1,  x.ordering(), x.getWorkspace());							// column-vector
	NDArray<T> wT(1, (int)x.lengthOf(), x.ordering(), x.getWorkspace());							// row-vector (transposed w)	

	T coeff;
	T normX = x.template reduceNumber<simdOps::Norm2<T>>();	
	const T min = DataTypeUtils::min<T>();
	
	if(normX*normX - x(0)*x(0) <= min) {

		normX = x(0); 
		coeff = (T)0.;		
		w = (T)0.;
		
	} 	
	else {
		
		if(x(0) >= (T)0.)
			normX = -normX;									// choose opposite sign to lessen roundoff error
		
		T u0 = x(0) - normX;
		coeff = -u0 / normX;				
		w.assign(x / u0);		
	}
	
	w(0) = (T)1.;
	wT.assign(&w);
	
	NDArray<T> identity((int)x.lengthOf(), (int)x.lengthOf(), x.ordering(), x.getWorkspace());					 
	identity.setIdentity();																			// identity matrix	

	return identity - mmul(w, wT) * coeff;	

}
Пример #17
0
unsigned int *
mgcd(unsigned int *u, unsigned int *v)
{
	int i, k, n;
	unsigned int *t;

	if (MZERO(u)) {
		t = mcopy(v);
		MSIGN(t) = 1;
		return t;
	}

	if (MZERO(v)) {
		t = mcopy(u);
		MSIGN(t) = 1;
		return t;
	}

	u = mcopy(u);
	v = mcopy(v);

	MSIGN(u) = 1;
	MSIGN(v) = 1;

	k = 0;

	while ((u[0] & 1) == 0 && (v[0] & 1) == 0) {
		mshiftright(u);
		mshiftright(v);
		k++;
	}

	if (u[0] & 1) {
		t = mcopy(v);
		MSIGN(t) *= -1;
	} else
		t = mcopy(u);

	while (1) {

		while ((t[0] & 1) == 0)
			mshiftright(t);

		if (MSIGN(t) == 1) {
			mfree(u);
			u = mcopy(t);
		} else {
			mfree(v);
			v = mcopy(t);
			MSIGN(v) *= -1;
		}

		mfree(t);

		t = msub(u, v);

		if (MZERO(t)) {
			mfree(t);
			mfree(v);
			n = (k / 32) + 1;
			v = mnew(n);
			MSIGN(v) = 1;
			MLENGTH(v) = n;
			for (i = 0; i < n; i++)
				v[i] = 0;
			mp_set_bit(v, k);
			t = mmul(u, v);
			mfree(u);
			mfree(v);
			return t;
		}
	}
}
Пример #18
0
real calc_orires_dev(const gmx_multisim_t *ms,
                     int nfa,const t_iatom forceatoms[],const t_iparams ip[],
                     const t_mdatoms *md,const rvec x[],const t_pbc *pbc,
                     t_fcdata *fcd,history_t *hist)
{
    int          fa,d,i,j,type,ex,nref;
    real         edt,edt1,invn,pfac,r2,invr,corrfac,weight,wsv2,sw,dev;
    tensor       *S,R,TMP;
    rvec5        *Dinsl,*Dins,*Dtav,*rhs;
    real         *mref,***T;
    double       mtot;
    rvec         *xref,*xtmp,com,r_unrot,r;
    t_oriresdata *od;
    bool         bTAV;
    const real   two_thr=2.0/3.0;
    
    od = &(fcd->orires);

    if (od->nr == 0)
    {
        /* This means that this is not the master node */
        gmx_fatal(FARGS,"Orientation restraints are only supported on the master node, use less processors");
    }
    
    bTAV = (od->edt != 0);
    edt  = od->edt;
    edt1 = od->edt1;
    S    = od->S;
    Dinsl= od->Dinsl;
    Dins = od->Dins;
    Dtav = od->Dtav;
    T    = od->TMP;
    rhs  = od->tmp;
    nref = od->nref;
    mref = od->mref;
    xref = od->xref;
    xtmp = od->xtmp;
    
    if (bTAV)
    {
        od->exp_min_t_tau = hist->orire_initf*edt;
        
        /* Correction factor to correct for the lack of history
         * at short times.
         */
        corrfac = 1.0/(1.0 - od->exp_min_t_tau);
    }
    else
    {
        corrfac = 1.0;
    }

    if (ms)
    {
        invn = 1.0/ms->nsim;
    }
    else
    {
        invn = 1.0;
    }
    
    clear_rvec(com);
    mtot = 0;
    j=0;
    for(i=0; i<md->nr; i++)
    {
        if (md->cORF[i] == 0)
        {
            copy_rvec(x[i],xtmp[j]);
            mref[j] = md->massT[i];
            for(d=0; d<DIM; d++)
            {
                com[d] += mref[j]*xref[j][d];
            }
            mtot += mref[j];
            j++;
        }
    }
    svmul(1.0/mtot,com,com);
    for(j=0; j<nref; j++)
    {
        rvec_dec(xtmp[j],com);
    }
    /* Calculate the rotation matrix to rotate x to the reference orientation */
    calc_fit_R(DIM,nref,mref,xref,xtmp,R);
    copy_mat(R,od->R);
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        type = forceatoms[fa];
        if (pbc)
        {
            pbc_dx_aiuc(pbc,x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
        }
        else
        {
            rvec_sub(x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
        }
        mvmul(R,r_unrot,r);
        r2   = norm2(r);
        invr = invsqrt(r2);
        /* Calculate the prefactor for the D tensor, this includes the factor 3! */
        pfac = ip[type].orires.c*invr*invr*3;
        for(i=0; i<ip[type].orires.power; i++)
        {
            pfac *= invr;
        }
        Dinsl[d][0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2);
        Dinsl[d][1] = pfac*(2*r[0]*r[1]);
        Dinsl[d][2] = pfac*(2*r[0]*r[2]);
        Dinsl[d][3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2);
        Dinsl[d][4] = pfac*(2*r[1]*r[2]);
        
        if (ms)
        {
            for(i=0; i<5; i++)
            {
                Dins[d][i] = Dinsl[d][i]*invn;
            }
        }

        d++;
    }
  
    if (ms)
    {
        gmx_sum_sim(5*od->nr,Dins[0],ms);
    }
   
    /* Calculate the order tensor S for each experiment via optimization */
    for(ex=0; ex<od->nex; ex++)
    {
        for(i=0; i<5; i++)
        {
            rhs[ex][i] = 0;
            for(j=0; j<=i; j++)
            {
                T[ex][i][j] = 0;
            }
        }
    }
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        if (bTAV)
        {
            /* Here we update Dtav in t_fcdata using the data in history_t.
             * Thus the results stay correct when this routine
             * is called multiple times.
             */
            for(i=0; i<5; i++)
            {
                Dtav[d][i] = edt*hist->orire_Dtav[d*5+i] + edt1*Dins[d][i];
            }
        }
        
        type   = forceatoms[fa];
        ex     = ip[type].orires.ex;
        weight = ip[type].orires.kfac;
        /* Calculate the vector rhs and half the matrix T for the 5 equations */
        for(i=0; i<5; i++) {
            rhs[ex][i] += Dtav[d][i]*ip[type].orires.obs*weight;
            for(j=0; j<=i; j++)
            {
                T[ex][i][j] += Dtav[d][i]*Dtav[d][j]*weight;
            }
        }
        d++;
    }
    /* Now we have all the data we can calculate S */
    for(ex=0; ex<od->nex; ex++)
    {
        /* Correct corrfac and copy one half of T to the other half */
        for(i=0; i<5; i++)
        {
            rhs[ex][i]  *= corrfac;
            T[ex][i][i] *= sqr(corrfac);
            for(j=0; j<i; j++)
            {
                T[ex][i][j] *= sqr(corrfac);
                T[ex][j][i]  = T[ex][i][j];
            }
        }
        m_inv_gen(T[ex],5,T[ex]);
        /* Calculate the orientation tensor S for this experiment */
        S[ex][0][0] = 0;
        S[ex][0][1] = 0;
        S[ex][0][2] = 0;
        S[ex][1][1] = 0;
        S[ex][1][2] = 0;
        for(i=0; i<5; i++)
        {
            S[ex][0][0] += 1.5*T[ex][0][i]*rhs[ex][i];
            S[ex][0][1] += 1.5*T[ex][1][i]*rhs[ex][i];
            S[ex][0][2] += 1.5*T[ex][2][i]*rhs[ex][i];
            S[ex][1][1] += 1.5*T[ex][3][i]*rhs[ex][i];
            S[ex][1][2] += 1.5*T[ex][4][i]*rhs[ex][i];
        }
        S[ex][1][0] = S[ex][0][1];
        S[ex][2][0] = S[ex][0][2];
        S[ex][2][1] = S[ex][1][2];
        S[ex][2][2] = -S[ex][0][0] - S[ex][1][1];
    }
    
    wsv2 = 0;
    sw   = 0;
    
    d = 0;
    for(fa=0; fa<nfa; fa+=3)
    {
        type = forceatoms[fa];
        ex = ip[type].orires.ex;
        
        od->otav[d] = two_thr*
            corrfac*(S[ex][0][0]*Dtav[d][0] + S[ex][0][1]*Dtav[d][1] +
                     S[ex][0][2]*Dtav[d][2] + S[ex][1][1]*Dtav[d][3] +
                     S[ex][1][2]*Dtav[d][4]);
        if (bTAV)
        {
            od->oins[d] = two_thr*(S[ex][0][0]*Dins[d][0] + S[ex][0][1]*Dins[d][1] +
                                   S[ex][0][2]*Dins[d][2] + S[ex][1][1]*Dins[d][3] +
                                   S[ex][1][2]*Dins[d][4]);
        }
        if (ms)
        {
            /* When ensemble averaging is used recalculate the local orientation
             * for output to the energy file.
             */
            od->oinsl[d] = two_thr*
                (S[ex][0][0]*Dinsl[d][0] + S[ex][0][1]*Dinsl[d][1] +
                 S[ex][0][2]*Dinsl[d][2] + S[ex][1][1]*Dinsl[d][3] +
                 S[ex][1][2]*Dinsl[d][4]);
        }
        
        dev = od->otav[d] - ip[type].orires.obs;
        
        wsv2 += ip[type].orires.kfac*sqr(dev);
        sw   += ip[type].orires.kfac;
        
        d++;
    }
    od->rmsdev = sqrt(wsv2/sw);
    
    /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
    for(ex=0; ex<od->nex; ex++)
    {
        tmmul(R,S[ex],TMP);
        mmul(TMP,R,S[ex]);
    }
    
    return od->rmsdev;
    
    /* Approx. 120*nfa/3 flops */
}
Пример #19
0
void diagonalize_orires_tensors(t_oriresdata *od)
{
    int           ex,i,j,nrot,ord[DIM],t;
    matrix        S,TMP;
    static double **M=NULL,*eig,**v;
    
    if (M == NULL)
    {
        snew(M,DIM);
        for(i=0; i<DIM; i++)
        {
            snew(M[i],DIM);
        }
        snew(eig,DIM);
        snew(v,DIM);
        for(i=0; i<DIM; i++)
        {
            snew(v[i],DIM);
        }
    }

    for(ex=0; ex<od->nex; ex++)
    {
        /* Rotate the S tensor back to the reference frame */
        mmul(od->R,od->S[ex],TMP);
        mtmul(TMP,od->R,S);
        for(i=0; i<DIM; i++)
        {
            for(j=0; j<DIM; j++)
            {
                M[i][j] = S[i][j];
            }
        }
        
        jacobi(M,DIM,eig,v,&nrot);
        
        for(i=0; i<DIM; i++)
        {
            ord[i] = i;
        }
        for(i=0; i<DIM; i++)
        {
            for(j=i+1; j<DIM; j++)
            {
                if (sqr(eig[ord[j]]) > sqr(eig[ord[i]]))
                {
                    t = ord[i];
                    ord[i] = ord[j];
                    ord[j] = t;
                }
            }
        }
            
        for(i=0; i<DIM; i++)
        {
            od->eig[ex*12 + i] = eig[ord[i]];
        }
        for(i=0; i<DIM; i++)
        {
            for(j=0; j<DIM; j++)
            {
                od->eig[ex*12 + 3 + 3*i + j] = v[j][ord[i]];
            }
        }
    }
}
Пример #20
0
static int
mprimef(unsigned int *n, unsigned int *q, int k)
{
	int i, j;
	unsigned int *t, *x, *y;

	// generate x

	t = mcopy(n);

	while (1) {
		for (i = 0; i < MLENGTH(t); i++)
			t[i] = rand();
		x = mmod(t, n);
		if (!MZERO(x) && !MEQUAL(x, 1))
			break;
		mfree(x);
	}

	mfree(t);

	// exponentiate

	y = mmodpow(x, q, n);

	// done?

	if (MEQUAL(y, 1)) {
		mfree(x);
		mfree(y);
		return 1;
	}

	j = 0;

	while (1) {

		// y = n - 1?

		t = msub(n, y);

		if (MEQUAL(t, 1)) {
			mfree(t);
			mfree(x);
			mfree(y);
			return 1;
		}

		mfree(t);

		if (++j == k) {
			mfree(x);
			mfree(y);
			return 0;
		}

		// y = (y ^ 2) mod n

		t = mmul(y, y);
		mfree(y);
		y = mmod(t, n);
		mfree(t);

		// y = 1?

		if (MEQUAL(y, 1)) {
			mfree(x);
			mfree(y);
			return 0;
		}
	}
}
Пример #21
0
int main( int argc, char** argv ) {

	int pnum, pid;
	double elapsed_time;
	float *A, *B, *C, *Cans;
	float diff;
	int n = 2048;
	int i, j, k;
	unsigned short seed[3];

	if( argc != 1 ){
		if( argc == 2 ){
			n = atoi(argv[1]);
		}
		else{
			printf("mmul [n]\n");
			exit(0);
		}
	}

	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &pnum);
	MPI_Comm_rank(MPI_COMM_WORLD, &pid);
	//printf("Processor %d out of %d says hi!\n", pid, pnum);

	if( pid == 0 ){
		//printf("Intializing matrix size : %d x %d x %d\n", n, n, n);

		A = (float*)malloc( sizeof(float) * n * n );
		B = (float*)malloc( sizeof(float) * n * n );
		C = (float*)malloc( sizeof(float) * n * n );

		seed[0] = 0; seed[1] = 1; seed[2] = 2;

		for (i=0; i<n; i++) {
			for (k=0; k<n; k++) {
				A(i,k) = (float)erand48(seed);
			}
		}
		for (k=0; k<n; k++) {
			for (j=0; j<n; j++) {
				B(k,j) = (float)erand48(seed);
			}
		}
	}

	MPI_Barrier(MPI_COMM_WORLD);
	elapsed_time = -1*MPI_Wtime();
	
	//Please modify the content of this function
	mmul(A, B, C, n);

	MPI_Barrier(MPI_COMM_WORLD);
	elapsed_time += MPI_Wtime();

	if( pid == 0 ){
		printf("Elapsed Time : %f secs\n", elapsed_time);

		Cans = (float*)malloc( sizeof(float) * n * n );
		mmul1(A, B, Cans, n);
		diff = compute_diff(C, Cans, n);

	    printf("Performance  : %.2f GFlops\n", 2.0*n*n*n/elapsed_time/1000000000 );
		printf("Result Diff  : %.3f\%\n", diff*100 );

		free(A);
		free(B);
		free(C);
		free(Cans);
	}
Пример #22
0
int mesh_out( const char*name)
{
	FILE*f=fopen( name , "wb");
	if(!f)
		return printf("File could not open: %s\n",name), -1;

	{
		//quick, non-optimal export
		int count = v_tri.size() / 3;
		std::vector<vertex_t>vertices;
		std::vector<u16>indices;
	
		for ( int i=0; i<count; ++i){
			int j=i*3;
			int vix = v_tri[j];
			int nix = v_tri[j+1];
			int tix = v_tri[j+2];
			
			vertex_t v={
				v_pos[vix*3],
				v_pos[vix*3+1],
				v_pos[vix*3+2],
				
				v_uv[tix*2],
				1.f-v_uv[tix*2+1],
				
				v_normal[nix*3],
				v_normal[nix*3+1],
				v_normal[nix*3+2],
				
				(float)v_jw[vix].joint_a,
				(float)v_jw[vix].joint_b,
				v_jw[vix].weight_a,
				v_jw[vix].weight_b
			};
			int index = vfind( &vertices[0], v, vertices.size() );
			if( index == (int)vertices.size() )
				vertices.push_back(v);
			indices.push_back( index );
		}

		//write
		int num_indices = indices.size();
		int num_vertices = vertices.size();
		int num_bone = v_keyframes.size();
		int num_frame = v_keyframes[0].size()/ 16;
		u8 num_child[16]={};
		u8 level[16]={};
		char stack_instr[16]={};
		std::vector<mat4_t>invm;
		int child_count = 0;

		assert( num_bone <= 16 && " TOO MANY BONES "[0] );
		assert( !v_keyframes.empty() && "KEYFRAMES EMPTY"[0]);
		//for( size_t i= 0 ;  i < joint_hier.size(); ++i)
		joint_ride(invm,num_child, joint_hier[0], level, child_count);
		
		for(int i = 0; i<num_bone-1; ++i)
			stack_instr[i]=(int)level[i+1]-(int)level[i];

		//WRITE header
		fwrite( &num_indices, sizeof( int ), 1, f );
		fwrite( &num_vertices, sizeof( int ), 1, f );
		fwrite( &num_bone, sizeof( int ) , 1, f);
		fwrite( &num_frame, sizeof( int ) , 1, f);
		//fwrite( num_child, sizeof(u8), 16, f);// hierarchy
		fwrite( stack_instr, sizeof(char), 16, f);// stack_instr
		
		//WRITE indices
		fwrite( &indices[0], sizeof( u16 ), num_indices, f );
		//WRITE vertices
		fwrite( &vertices[0], sizeof( vertex_t ), num_vertices, f );


		//transpose all matrices 
		mtranspose( &bind_shape_matrix[0] );

		for( int i=0; i<num_bone; ++i ){
			float res[16];
			mtranspose( res,invm[i].data );
			
			//PRE-MULTIPLY WITH BSM
			mmul(invm[i].data, res, &bind_shape_matrix[0]);
			
			for( int k=0;k<num_frame; ++k){
				mtranspose(&v_keyframes[i][k*16] );

			}
		}
		//fwrite( bind_shape_matrix.data(), sizeof(float),16,f);

		//WRITE inverse matrices
		fwrite( invm[0].data, sizeof(float),16*num_bone,f);

		//KEYFRAMES
		//create joints  ( pos , dir/quat ) from matrices 
		//WRITE keyframes (and reorder frame wise, not bone wise)
		//AND convert to joint quat
		jq_t jq={};
		std::vector<jq_t>jointquats;
		jointquats.reserve(num_frame*num_bone);
		for( int k=0;k<num_frame; ++k)
			for( int i=0;i<num_bone; ++i){
			quat_from_mat4(jq.quat,&v_keyframes[i][k*16]);

			jq.pos[0]=v_keyframes[i][k*16+12];
			jq.pos[1]=v_keyframes[i][k*16+13];
			jq.pos[2]=v_keyframes[i][k*16+14];

			jq.child[0]=jq.child[1]=jq.child[2]=jq.child[3]=0;
			jointquats.push_back(jq);
			//fwrite( &v_keyframes[i][k*16], sizeof(float),16,f);
			}
		fwrite(jointquats.data(), sizeof(jq_t),num_frame*num_bone,f);
		
		//done
		fclose(f);
		
		//print stuff...
		for( int i=0;i<16; ++i)
			printf( "m = %.4f\tinv = %.4f\n",v_keyframes[0][i],
					invm[0].data[i]);


		printf("\nOUTPUT\n");
		printf( "INDICES: %d\n", num_indices);
		printf( "VERTICES: %d\n", num_vertices);
		printf("BONES = %d\n", num_bone);
		printf("FRAMES = %d\n", num_frame);
		printf("STACK = \n\t");
		for( int i=0;i<num_bone; ++i)
			printf("%d, ",stack_instr[i]);
		printf("\nHIERARCHY = \n\t");
		for( int i=0;i<num_bone; ++i)
			printf("%d, ",num_child[i]);
		printf("\n");
	}

	return 0;
}
Пример #23
0
unsigned int *
mfactor(unsigned int *n)
{
	unsigned int *r, *root, *t, *two, *x, *y;

	two = mint(2);

	root = msqrt(n);

	// y = 1;

	y = mint(1);

	// x = 2 isqrt(n) + 1

	t = madd(root, root);
	x = madd(t, y);
	mfree(t);

	// r = isqrt(n) ^ 2 - n

	t = mmul(root, root);
	r = msub(t, n);
	mfree(t);

	mfree(root);

	while (1) {

		if (MZERO(r)) {

			// n = (x - y) / 2

			t = msub(x, y);
			n = mdiv(t, two);
			mfree(t);

			mfree(r);
			mfree(x);
			mfree(y);
			mfree(two);

			return n;
		}

		// r = r + x

		t = madd(r, x);
		mfree(r);
		r = t;

		// x = x + 2

		t = madd(x, two);
		mfree(x);
		x = t;

		while (1) {

			// r = r - y

			t = msub(r, y);
			mfree(r);
			r = t;

			// y = y + 2

			t = madd(y, two);
			mfree(y);
			y = t;

			if (MSIGN(r) == -1 || MZERO(r))
				break;
		}
	}
}
Пример #24
0
real calc_orires_dev(t_commrec *mcr,
		     int nfa,t_iatom forceatoms[],t_iparams ip[],
		     t_mdatoms *md,rvec x[],t_fcdata *fcd)
{
  int          fa,d,i,j,type,ex,nref;
  real         edt,edt1,invn,pfac,r2,invr,corrfac,weight,wsv2,sw,dev;
  tensor       *S,R,TMP;
  rvec5        *Dinsl,*Dins,*Dtav,*rhs;
  real         *mref,***T;
  rvec         *xref,*xtmp,com,r_unrot,r;
  t_oriresdata *od;
  bool         bTAV;
  static real  two_thr=2.0/3.0;

  od = &(fcd->orires);

  bTAV = (fabs(od->edt)>GMX_REAL_MIN);
  edt  = od->edt;
  edt1 = od->edt1;
  S    = od->S;
  Dinsl= od->Dinsl;
  Dins = od->Dins;
  Dtav = od->Dtav;
  T    = od->TMP;
  rhs  = od->tmp;
  nref = od->nref;
  mref = od->mref;
  xref = od->xref;
  xtmp = od->xtmp;
  
  od->exp_min_t_tau *= edt;

  if (mcr)
    invn = 1.0/mcr->nnodes;
  else
    invn = 1.0;

  j=0;
  for(i=0; i<md->nr; i++)
    if (md->cORF[i] == 0) {
      copy_rvec(x[i],xtmp[j]);
      for(d=0; d<DIM; d++)
	com[d] += mref[j]*xref[j][d];
      j++;
    }
  svmul(od->invmref,com,com);
  for(j=0; j<nref; j++)
    rvec_dec(xtmp[j],com);
  /* Calculate the rotation matrix to rotate x to the reference orientation */
  calc_fit_R(nref,mref,xref,xtmp,R);
  copy_mat(R,od->R);

  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    rvec_sub(x[forceatoms[fa+1]],x[forceatoms[fa+2]],r_unrot);
    mvmul(R,r_unrot,r);
    r2   = norm2(r);
    invr = invsqrt(r2);
    /* Calculate the prefactor for the D tensor, this includes the factor 3! */
    pfac = ip[type].orires.c*invr*invr*3;
    for(i=0; i<ip[type].orires.pow; i++)
      pfac *= invr;
    Dinsl[d][0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2);
    Dinsl[d][1] = pfac*(2*r[0]*r[1]);
    Dinsl[d][2] = pfac*(2*r[0]*r[2]);
    Dinsl[d][3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2);
    Dinsl[d][4] = pfac*(2*r[1]*r[2]);

    if (mcr)
      for(i=0; i<5; i++)
	Dins[d][i] = Dinsl[d][i]*invn;
    
    d++;
  }
  
  if (mcr)
    gmx_sum(5*od->nr,Dins[0],mcr);
  
  /* Correction factor to correct for the lack of history for short times */
  corrfac = 1.0/(1.0-od->exp_min_t_tau);
  
  /* Calculate the order tensor S for each experiment via optimization */
  for(ex=0; ex<od->nex; ex++)
    for(i=0; i<5; i++) {
      rhs[ex][i] = 0;
      for(j=0; j<=i; j++)
	T[ex][i][j] = 0;
    }
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    if (bTAV)
      for(i=0; i<5; i++)
	Dtav[d][i] = edt*Dtav[d][i] + edt1*Dins[d][i];

    type   = forceatoms[fa];
    ex     = ip[type].orires.ex;
    weight = ip[type].orires.kfac;
    /* Calculate the vector rhs and half the matrix T for the 5 equations */
    for(i=0; i<5; i++) {
      rhs[ex][i] += Dtav[d][i]*ip[type].orires.obs*weight;
      for(j=0; j<=i; j++)
	T[ex][i][j] += Dtav[d][i]*Dtav[d][j]*weight;
    }
    d++;
  }
  /* Now we have all the data we can calculate S */
  for(ex=0; ex<od->nex; ex++) {
    /* Correct corrfac and copy one half of T to the other half */
    for(i=0; i<5; i++) {
      rhs[ex][i]  *= corrfac;
      T[ex][i][i] *= sqr(corrfac);
      for(j=0; j<i; j++) {
	T[ex][i][j] *= sqr(corrfac);
	T[ex][j][i]  = T[ex][i][j];
      }
    }
    m_inv_gen(T[ex],5,T[ex]);
    /* Calculate the orientation tensor S for this experiment */
    S[ex][0][0] = 0;
    S[ex][0][1] = 0;
    S[ex][0][2] = 0;
    S[ex][1][1] = 0;
    S[ex][1][2] = 0;
    for(i=0; i<5; i++) {
      S[ex][0][0] += 1.5*T[ex][0][i]*rhs[ex][i];
      S[ex][0][1] += 1.5*T[ex][1][i]*rhs[ex][i];
      S[ex][0][2] += 1.5*T[ex][2][i]*rhs[ex][i];
      S[ex][1][1] += 1.5*T[ex][3][i]*rhs[ex][i];
      S[ex][1][2] += 1.5*T[ex][4][i]*rhs[ex][i];
    }
    S[ex][1][0] = S[ex][0][1];
    S[ex][2][0] = S[ex][0][2];
    S[ex][2][1] = S[ex][1][2];
    S[ex][2][2] = -S[ex][0][0] - S[ex][1][1];
  }
  
  wsv2 = 0;
  sw   = 0;
  
  d = 0;
  for(fa=0; fa<nfa; fa+=3) {
    type = forceatoms[fa];
    ex = ip[type].orires.ex;

    od->otav[d] = two_thr*
      corrfac*(S[ex][0][0]*Dtav[d][0] + S[ex][0][1]*Dtav[d][1] +
	       S[ex][0][2]*Dtav[d][2] + S[ex][1][1]*Dtav[d][3] +
	       S[ex][1][2]*Dtav[d][4]);
    if (bTAV)
      od->oins[d] = two_thr*(S[ex][0][0]*Dins[d][0] + S[ex][0][1]*Dins[d][1] +
			     S[ex][0][2]*Dins[d][2] + S[ex][1][1]*Dins[d][3] +
			     S[ex][1][2]*Dins[d][4]);
    if (mcr)
      /* When ensemble averaging is used recalculate the local orientation
       * for output to the energy file.
       */
      od->oinsl[d] = two_thr*
	(S[ex][0][0]*Dinsl[d][0] + S[ex][0][1]*Dinsl[d][1] +
	 S[ex][0][2]*Dinsl[d][2] + S[ex][1][1]*Dinsl[d][3] +
	 S[ex][1][2]*Dinsl[d][4]);
    
    dev = od->otav[d] - ip[type].orires.obs;
    
    wsv2 += ip[type].orires.kfac*sqr(dev);
    sw   += ip[type].orires.kfac;
    
    d++;
  }
  od->rmsdev = sqrt(wsv2/sw);
  
  /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */
  for(ex=0; ex<od->nex; ex++) {
    tmmul(R,S[ex],TMP);
    mmul(TMP,R,S[ex]);
  }

  return od->rmsdev;
  
  /* Approx. 120*nfa/3 flops */
}
Пример #25
0
void parrinellorahman_pcoupl(FILE *fplog,gmx_step_t step,
			     t_inputrec *ir,real dt,tensor pres,
			     tensor box,tensor box_rel,tensor boxv,
			     tensor M,matrix mu,bool bFirstStep)
{
  /* This doesn't do any coordinate updating. It just
   * integrates the box vector equations from the calculated
   * acceleration due to pressure difference. We also compute
   * the tensor M which is used in update to couple the particle
   * coordinates to the box vectors.
   *
   * In Nose and Klein (Mol.Phys 50 (1983) no 5., p 1055) this is
   * given as
   *            -1    .           .     -1
   * M_nk = (h')   * (h' * h + h' h) * h
   *
   * with the dots denoting time derivatives and h is the transformation from
   * the scaled frame to the real frame, i.e. the TRANSPOSE of the box. 
   * This also goes for the pressure and M tensors - they are transposed relative
   * to ours. Our equation thus becomes:
   *
   *                  -1       .    .           -1
   * M_gmx = M_nk' = b  * (b * b' + b * b') * b'
   * 
   * where b is the gromacs box matrix.                       
   * Our box accelerations are given by
   *   ..                                    ..
   *   b = vol/W inv(box') * (P-ref_P)     (=h')
   */
  
  int    d,n;
  tensor winv;
  real   vol=box[XX][XX]*box[YY][YY]*box[ZZ][ZZ];
  real   atot,arel,change,maxchange,xy_pressure;
  tensor invbox,pdiff,t1,t2;

  real maxl;

  m_inv_ur0(box,invbox);

  if (!bFirstStep) {
    /* Note that PRESFAC does not occur here.
     * The pressure and compressibility always occur as a product,
     * therefore the pressure unit drops out.
     */
    maxl=max(box[XX][XX],box[YY][YY]);
    maxl=max(maxl,box[ZZ][ZZ]);
    for(d=0;d<DIM;d++)
      for(n=0;n<DIM;n++)
	winv[d][n]=
	  (4*M_PI*M_PI*ir->compress[d][n])/(3*ir->tau_p*ir->tau_p*maxl);
    
    m_sub(pres,ir->ref_p,pdiff);
    
    if(ir->epct==epctSURFACETENSION) {
      /* Unlike Berendsen coupling it might not be trivial to include a z
       * pressure correction here? On the other hand we don't scale the
       * box momentarily, but change accelerations, so it might not be crucial.
       */
      xy_pressure=0.5*(pres[XX][XX]+pres[YY][YY]);
      for(d=0;d<ZZ;d++)
	pdiff[d][d]=(xy_pressure-(pres[ZZ][ZZ]-ir->ref_p[d][d]/box[d][d]));
    }
    
    tmmul(invbox,pdiff,t1);
    /* Move the off-diagonal elements of the 'force' to one side to ensure
     * that we obey the box constraints.
     */
    for(d=0;d<DIM;d++) {
      for(n=0;n<d;n++) {
	t1[d][n] += t1[n][d];
	t1[n][d] = 0;
      }
    }
    
    switch (ir->epct) {
    case epctANISOTROPIC:
      for(d=0;d<DIM;d++) 
	for(n=0;n<=d;n++)
	  t1[d][n] *= winv[d][n]*vol;
      break;
    case epctISOTROPIC:
      /* calculate total volume acceleration */
      atot=box[XX][XX]*box[YY][YY]*t1[ZZ][ZZ]+
	box[XX][XX]*t1[YY][YY]*box[ZZ][ZZ]+
	t1[XX][XX]*box[YY][YY]*box[ZZ][ZZ];
      arel=atot/(3*vol);
      /* set all RELATIVE box accelerations equal, and maintain total V
       * change speed */
      for(d=0;d<DIM;d++)
	for(n=0;n<=d;n++)
	  t1[d][n] = winv[0][0]*vol*arel*box[d][n];    
      break;
    case epctSEMIISOTROPIC:
    case epctSURFACETENSION:
      /* Note the correction to pdiff above for surftens. coupling  */
      
      /* calculate total XY volume acceleration */
      atot=box[XX][XX]*t1[YY][YY]+t1[XX][XX]*box[YY][YY];
      arel=atot/(2*box[XX][XX]*box[YY][YY]);
      /* set RELATIVE XY box accelerations equal, and maintain total V
       * change speed. Dont change the third box vector accelerations */
      for(d=0;d<ZZ;d++)
	for(n=0;n<=d;n++)
	  t1[d][n] = winv[d][n]*vol*arel*box[d][n];
      for(n=0;n<DIM;n++)
	t1[ZZ][n] *= winv[d][n]*vol;
      break;
    default:
      gmx_fatal(FARGS,"Parrinello-Rahman pressure coupling type %s "
		  "not supported yet\n",EPCOUPLTYPETYPE(ir->epct));
      break;
    }
    
    maxchange=0;
    for(d=0;d<DIM;d++)
      for(n=0;n<=d;n++) {
	boxv[d][n] += dt*t1[d][n];
	/* We do NOT update the box vectors themselves here, since
	 * we need them for shifting later. It is instead done last
	 * in the update() routine.
	 */
	
	/* Calculate the change relative to diagonal elements -
	 * since it's perfectly ok for the off-diagonal ones to
	 * be zero it doesn't make sense to check the change relative
	 * to its current size.
	 */
	change=fabs(dt*boxv[d][n]/box[d][d]);
	if(change>maxchange)
	  maxchange=change;
      }
    
    if (maxchange > 0.01 && fplog) {
      char buf[22];
      fprintf(fplog,"\nStep %s  Warning: Pressure scaling more than 1%%.\n",
	      gmx_step_str(step,buf));
    }
  }
  
  preserve_box_shape(ir,box_rel,boxv);

  mtmul(boxv,box,t1);       /* t1=boxv * b' */
  mmul(invbox,t1,t2);
  mtmul(t2,invbox,M);

  /* Determine the scaling matrix mu for the coordinates */
  for(d=0;d<DIM;d++)
    for(n=0;n<=d;n++)
      t1[d][n] = box[d][n] + dt*boxv[d][n];
  preserve_box_shape(ir,box_rel,t1);
  /* t1 is the box at t+dt, determine mu as the relative change */
  mmul_ur0(invbox,t1,mu);
}
Пример #26
0
void diagonalize_orires_tensors(t_oriresdata *od)
{
    int           ex, i, j, nrot, ord[DIM], t;
    matrix        S, TMP;

    if (od->M == NULL)
    {
        snew(od->M, DIM);
        for (i = 0; i < DIM; i++)
        {
            snew(od->M[i], DIM);
        }
        snew(od->eig_diag, DIM);
        snew(od->v, DIM);
        for (i = 0; i < DIM; i++)
        {
            snew(od->v[i], DIM);
        }
    }

    for (ex = 0; ex < od->nex; ex++)
    {
        /* Rotate the S tensor back to the reference frame */
        mmul(od->R, od->S[ex], TMP);
        mtmul(TMP, od->R, S);
        for (i = 0; i < DIM; i++)
        {
            for (j = 0; j < DIM; j++)
            {
                od->M[i][j] = S[i][j];
            }
        }

        jacobi(od->M, DIM, od->eig_diag, od->v, &nrot);

        for (i = 0; i < DIM; i++)
        {
            ord[i] = i;
        }
        for (i = 0; i < DIM; i++)
        {
            for (j = i+1; j < DIM; j++)
            {
                if (gmx::square(od->eig_diag[ord[j]]) > gmx::square(od->eig_diag[ord[i]]))
                {
                    t      = ord[i];
                    ord[i] = ord[j];
                    ord[j] = t;
                }
            }
        }

        for (i = 0; i < DIM; i++)
        {
            od->eig[ex*12 + i] = od->eig_diag[ord[i]];
        }
        for (i = 0; i < DIM; i++)
        {
            for (j = 0; j < DIM; j++)
            {
                od->eig[ex*12 + 3 + 3*i + j] = od->v[j][ord[i]];
            }
        }
    }
}