Пример #1
0
/* use pointer device to rotate (via magic sphere) */
bool pointer_rotate (int iw, int to_x, int to_y)
{
    double a[3], b[3], c[3], R[3][3];
    mgs ( n[iw].lx - AX_size[iw].width/2.,
          n[iw].ly - AX_size[iw].height/2., n[iw].mgs_radius, a );
    mgs ( to_x - AX_size[iw].width/2.,
          to_y - AX_size[iw].height/2., n[iw].mgs_radius, b );
    V3CROSS (a, b, c);
    if (V3LENGTH2(c) < MIN_RADIAN*MIN_RADIAN) return (FALSE);
    M3geodesic (b, a, R);
    rotate (iw, R);
    n[iw].lx = to_x;
    n[iw].ly = to_y;
    return (TRUE);
} /* end pointer_rotate() */
Пример #2
0
void onDisplay( ) {
	glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_LINES);
	for (int i = -3; i < 3; i++) {
		for (int j = -3; j <= 3; j++) {
			glVertex3f(i*zoom, 0, j*zoom);
			glVertex3f((i+1)*zoom, 0, j*zoom);
		}
	}
	for (int i = -3; i < 3; i++) {
		for (int j = -3; j <= 3; j++) {
			glVertex3f(j*zoom, 0, i*zoom);
			glVertex3f(j*zoom, 0, (i+1)*zoom);
		}
	}
	glEnd();

	mygluSphere mgs(2., 100., 100.);
	//GLUquadric *quad = gluNewQuadric();
	//gluSphere(quad, 2., 100., 100.);

	// Buffercsere: rajzolas vege
	glFinish();
	glutSwapBuffers();
}
Пример #3
0
int DLL_EXPORT extrapolate(real_t *vectors, uint_t dim, uint_t order, enum EXTR_METHOD method)
{
    real_t *const v0 = vectors;

    /* Compute differences */
    for (uint_t i = order - 1; i > 0; --i) {
        real_t *v = vectors + i * dim;
        real_t *u = v - dim;
        for (uint_t k = 0; k < dim; ++k)
            v[k] = v[k] - u[k];
    }
    vectors = vectors + dim;
    order = order - 1;

    /* QR decomposition */
    real_t R[order * order];
    mgs(vectors, R, dim, order);

    /* Compute coefficients */
    real_t gamma[order];
    switch (method) {
        case MPE:	mpe(R, gamma, order); break;
        case RRE:  	rre(R, gamma, order); break;
        default:    return -1;
    }

    /* xi = 1 - cumsum(gamma) */
    for (uint_t i = 1; i < order; ++i)
        gamma[i] = gamma[i] + gamma[i-1];
    real_t xi[order];
    for (uint_t i = 0; i < order; ++i)
        xi[i] = 1 - gamma[i];

    /* eta = R * xi */
    real_t eta[order];
    for (uint_t i = 0; i < order; ++i) {
        eta[i] = 0;
        for (uint_t k = 0; k < order; ++k)
            eta[i] = eta[i] + R[IDX(i, k, order)] * xi[k];
    }

    /* Compute the solution: v0 + Q * eta */
    for (uint_t i = 0; i < order; ++i) {
        real_t *q = vectors + i * dim;
        for (uint_t k = 0; k < dim; ++k)
            v0[k] = v0[k] + q[k] * eta[i];
    }
    return 0;
}
Пример #4
0
int main ( void )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for MGS_PRB.

  Discussion:

    MGS_PRB tests the MGS library.

  Modified:

    07 November 2011

  Author:

    John Burkardt
*/
{
  float **a;
  float **a_qr;
  float **a_save;
  float a_hi = 10.0;
  float a_lo = -10.0;
  float diff;
  int i;
  int j;
  int k;
  int m;
  int n;
  float **q;
  float **r;
  int seed = 123456789;
  int test;

  timestamp ( );
  printf ( "\n" );
  printf ( "MGS_PRB:\n" );
  printf ( "  C version\n" );
  printf ( "  Test cases for MGS.\n" );
  printf ( "\n" );

  for ( test = 1; test <= 4; test++ )
  {
    m = i4_uniform ( 1, 20, &seed );
    n = i4_uniform ( 1, 20, &seed );

    a = r4mat_new ( m, n );
    a_qr = r4mat_new ( m, n );
    a_save = r4mat_new ( m, n );
    q = r4mat_new ( m, n );
    r = r4mat_new ( n, n );

    r4mat_uniform ( m, n, a_lo, a_hi, &seed, a );

    for ( j = 0; j < n; j++ )
    {
      for ( i = 0; i < m; i++ )
      {
        a_save[i][j] = a[i][j];
      }
    }

    for ( j = 0; j < n; j++ )
    {
      for ( i = 0; i < m; i++ )
      {
        q[i][j] = 0.0;
      }
    }

    for ( j = 0; j < n; j++ )
    {
      for ( i = 0; i < n; i++ )
      {
        r[i][j] = 0.0;
      }
    }

    mgs ( m, n, a, r, q );

    for ( j = 0; j < n; j++ )
    {
      for ( i = 0; i < m; i++ )
      {
        a_qr[i][j] = 0.0;
        for ( k = 0; k < n; k++ )
        {
          a_qr[i][j] = a_qr[i][j] + q[i][k] * r[k][j];
        }
      }
    }
    diff = 0.0;
    for ( j = 0; j < n; j++ )
    {
      for ( i = 0; i < m; i++ )
      {
        diff = diff + pow ( a_save[i][j] - a_qr[i][j], 2 );
      }
    }
    diff = diff / sqrt ( ( float ) ( m * n ) );

    printf ( "  %2d  %2d  %14.6g\n", m, n, diff );

    r4mat_delete ( a, m, n );
    r4mat_delete ( a_qr, m, n );
    r4mat_delete ( a_save, m, n );
    r4mat_delete ( q, m, n );
    r4mat_delete ( r, n, n );
  }
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "MGS_PRB:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}
Пример #5
0
void Peer::received(
	const RuntimeEnvironment *RR,
	const SharedPtr<Socket> &fromSock,
	const InetAddress &remoteAddr,
	unsigned int hops,
	uint64_t packetId,
	Packet::Verb verb,
	uint64_t inRePacketId,
	Packet::Verb inReVerb,
	uint64_t now)
{
	// Update system-wide last packet receive time
	*((const_cast<uint64_t *>(&(RR->timeOfLastPacketReceived)))) = now;

	// Global last receive time regardless of path
	_lastReceive = now;

	if (!hops) {
		// Learn paths from direct packets (hops == 0)
		{
			bool havePath = false;
			for(unsigned int p=0,np=_numPaths;p<np;++p) {
				if ((_paths[p].address() == remoteAddr)&&(_paths[p].tcp() == fromSock->tcp())) {
					_paths[p].received(now);
					havePath = true;
					break;
				}
			}

			if (!havePath) {
				unsigned int np = _numPaths;
				if (np >= ZT_PEER_MAX_PATHS)
					clean(now);
				np = _numPaths;
				if (np < ZT_PEER_MAX_PATHS) {
					Path::Type pt = Path::PATH_TYPE_UDP;
					switch(fromSock->type()) {
						case Socket::ZT_SOCKET_TYPE_TCP_IN:
							pt = Path::PATH_TYPE_TCP_IN;
							break;
						case Socket::ZT_SOCKET_TYPE_TCP_OUT:
							pt = Path::PATH_TYPE_TCP_OUT;
							break;
						default:
							break;
					}
					_paths[np].init(remoteAddr,pt,false);
					_paths[np].received(now);
					_numPaths = ++np;
				}
			}
		}

		/* Announce multicast groups of interest to direct peers if they are
		 * considered authorized members of a given network. Also announce to
		 * supernodes and network controllers. The other place this is done
		 * is in rescanMulticastGroups() in Network, but that only sends something
		 * if a network's multicast groups change. */
		if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) {
			_lastAnnouncedTo = now;

			bool isSupernode = RR->topology->isSupernode(_id.address());

			Packet outp(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
			std::vector< SharedPtr<Network> > networks(RR->nc->networks());
			for(std::vector< SharedPtr<Network> >::iterator n(networks.begin());n!=networks.end();++n) {
				if ( ((*n)->isAllowed(_id.address())) || (isSupernode) ) {
					std::set<MulticastGroup> mgs((*n)->multicastGroups());
					for(std::set<MulticastGroup>::iterator mg(mgs.begin());mg!=mgs.end();++mg) {
						if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
							outp.armor(_key,true);
							fromSock->send(remoteAddr,outp.data(),outp.size());
							outp.reset(_id.address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
						}

						// network ID, MAC, ADI
						outp.append((uint64_t)(*n)->id());
						mg->mac().appendTo(outp);
						outp.append((uint32_t)mg->adi());
					}
				}
			}
			if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) {
				outp.armor(_key,true);
				fromSock->send(remoteAddr,outp.data(),outp.size());
			}
		}
	}

	if ((verb == Packet::VERB_FRAME)||(verb == Packet::VERB_EXT_FRAME))
		_lastUnicastFrame = now;
	else if ((verb == Packet::VERB_P5_MULTICAST_FRAME)||(verb == Packet::VERB_MULTICAST_FRAME))
		_lastMulticastFrame = now;
}
Пример #6
0
SEXP TASCB_min(SEXP vect, SEXP tau, SEXP numberofSamples, SEXP sigma){
	int value_count, sigma_count;
	mgs_result mgs_res;
	quant_result q_res;
	dbl_array *vector, *vect_sorted, *s;
	dbl_matrix *H_Mat1, *H_Mat2;
	calc_V_result_tri v_res;
	final_result_tri f_res;
	SEXP result, binarized_vector, threshold1, threshold2, p_value, other_results, names;
	SEXP smoothed, zerocrossing, deriv, steps, H1, H2, index, v_vec, meanlist, smoothedX;

	value_count = length(vect);
	sigma_count = length(sigma);

	PROTECT(result = allocVector(VECSXP, 5));
	PROTECT(names = allocVector(VECSXP, 5));
	SET_VECTOR_ELT(names,0, mkChar("binarized_vector"));
	SET_VECTOR_ELT(names,1, mkChar("threshold1"));
	SET_VECTOR_ELT(names,2, mkChar("threshold2"));
	SET_VECTOR_ELT(names,3, mkChar("p_value"));
	SET_VECTOR_ELT(names,4, mkChar("other_results"));
	setAttrib(result, R_NamesSymbol, names);
	UNPROTECT(1);

	PROTECT(other_results = allocVector(VECSXP, 10));
	PROTECT(names = allocVector(VECSXP, 10));
	SET_VECTOR_ELT(names,0, mkChar("smoothed"));
	SET_VECTOR_ELT(names,1, mkChar("zerocrossing"));
	SET_VECTOR_ELT(names,2, mkChar("deriv"));
	SET_VECTOR_ELT(names,3, mkChar("steps"));
	SET_VECTOR_ELT(names,4, mkChar("H_Mat1"));
	SET_VECTOR_ELT(names,5, mkChar("H_Mat2"));
	SET_VECTOR_ELT(names,6, mkChar("index"));
	SET_VECTOR_ELT(names,7, mkChar("v_vec"));
	SET_VECTOR_ELT(names,8, mkChar("smoothedX"));
	SET_VECTOR_ELT(names,9, mkChar("meanlist"));
	setAttrib(other_results, R_NamesSymbol, names);
	UNPROTECT(1);

	PROTECT(smoothed = allocMatrix(REALSXP, value_count - 1, sigma_count));
	PROTECT(zerocrossing = allocMatrix(INTSXP, (int)ceil((double)value_count / 2.0), sigma_count));
	PROTECT(deriv = allocVector(REALSXP, value_count - 1));
	
	mgs_res.smoothed = init_dbl_matrix(REAL(smoothed), sigma_count, value_count - 1, 0);
	mgs_res.zerocrossing = init_int_matrix(INTEGER(zerocrossing), sigma_count, (int)ceil((double)value_count / 2.0), 0);
	mgs_res.deriv = init_dbl_array(REAL(deriv), value_count - 1, 0);
	vector = init_dbl_array(REAL(vect), value_count, 1);
	vect_sorted = init_dbl_array(0, value_count, 0);
	s = init_dbl_array(REAL(sigma), sigma_count, 1);
	b = init_dbl_matrix(0, sigma_count, mgs_res.deriv->length, 0);
	b_returned = init_int_matrix(0, sigma_count, mgs_res.deriv->length, 0);

	memcpy(vect_sorted->values, REAL(vect), vect_sorted->length * sizeof(double));
	qsort(vect_sorted->values, vect_sorted->length, sizeof(double), comp);

	mgs(&mgs_res, vect_sorted, s);

	q_res.steps = init_int_matrix(0, sigma_count, (int)ceil((double)value_count / 2.0), 0);
	q_res.index = init_int_array(0, sigma_count, 0);
	q_res.greatest_index_ind = 0;
	q_res.greatest_steps_col = 0;
	q_res.greatest_steps_row = 0;

	getQuantizations(&q_res, &mgs_res);
	
	PROTECT(steps = allocMatrix(INTSXP, q_res.greatest_steps_col, q_res.greatest_steps_row));
	PROTECT(H1 = allocMatrix(REALSXP, q_res.greatest_steps_col, q_res.greatest_steps_row));
	PROTECT(H2 = allocMatrix(REALSXP, q_res.greatest_steps_col, q_res.greatest_steps_row));
	PROTECT(index = allocVector(INTSXP, q_res.greatest_index_ind));

	cut_int_matrix(q_res.steps, INTEGER(steps), 0, q_res.greatest_steps_row - 1, 0, q_res.greatest_steps_col - 1);
	cut_int_array(q_res.index, INTEGER(index), 0, q_res.greatest_index_ind - 1);
	H_Mat1 = init_dbl_matrix(REAL(H1), q_res.greatest_steps_row, q_res.greatest_steps_col, 0);
	H_Mat2 = init_dbl_matrix(REAL(H2), q_res.greatest_steps_row, q_res.greatest_steps_col, 0);

	PROTECT(v_vec = allocMatrix(INTSXP, q_res.index->length, 2));
	PROTECT(smoothedX = allocMatrix(REALSXP, mgs_res.smoothed->cols + 1, q_res.index->length));
	PROTECT(meanlist = allocMatrix(REALSXP, vect_sorted->length, q_res.index->length + 1));
	v_res.v = init_int_matrix(INTEGER(v_vec), q_res.index->length, 2, 0);
	
	v_res.meanlist = init_dbl_matrix(REAL(meanlist), q_res.index->length + 1, vect_sorted->length, 0);
	v_res.smoothedX = init_dbl_matrix(REAL(smoothedX), q_res.index->length, mgs_res.smoothed->cols + 1, 0);

	calc_V_Scalespace_tri_min(&v_res, &mgs_res, &q_res, H_Mat1, H_Mat2, vect_sorted);

	PROTECT(binarized_vector = allocVector(INTSXP, value_count));
	PROTECT(threshold1 = allocVector(REALSXP, 1));
	PROTECT(threshold2 = allocVector(REALSXP, 1));
	PROTECT(p_value = allocVector(REALSXP, 1));

	f_res.binarized_vector = init_int_array(INTEGER(binarized_vector), value_count, 0);
	f_res.p = REAL(p_value);
	f_res.threshold1 = REAL(threshold1);
	f_res.threshold2 = REAL(threshold2);

	calc_final_results_tri_min(&f_res, v_res.v, vector, vect_sorted, *REAL(tau), *INTEGER(numberofSamples));

	SET_VECTOR_ELT(other_results, 0, smoothed);
	SET_VECTOR_ELT(other_results, 1, zerocrossing);
	SET_VECTOR_ELT(other_results, 2, deriv);
	SET_VECTOR_ELT(other_results, 3, steps);
	SET_VECTOR_ELT(other_results, 4, H1);
	SET_VECTOR_ELT(other_results, 5, H2);
	SET_VECTOR_ELT(other_results, 6, index);
	SET_VECTOR_ELT(other_results, 7, v_vec);
	SET_VECTOR_ELT(other_results, 8, smoothedX);
	SET_VECTOR_ELT(other_results, 9, meanlist);
	
	SET_VECTOR_ELT(result, 0, binarized_vector);
	SET_VECTOR_ELT(result, 1, threshold1);
	SET_VECTOR_ELT(result, 2, threshold2);
	SET_VECTOR_ELT(result, 3, p_value);
	SET_VECTOR_ELT(result, 4, other_results);

	destroy_dbl_matrix(mgs_res.smoothed);
	destroy_int_matrix(mgs_res.zerocrossing);
	destroy_dbl_array(mgs_res.deriv);
	destroy_dbl_array(vector);
	destroy_dbl_array(vect_sorted);
	destroy_dbl_array(s);
	destroy_dbl_matrix(b);
	destroy_int_matrix(b_returned);
	b = 0;
	b_returned = 0;
	destroy_dbl_matrix(H_Mat1);
	destroy_dbl_matrix(H_Mat2);
	destroy_int_matrix(q_res.steps);
	destroy_int_array(q_res.index);
	destroy_int_matrix(v_res.v);
	destroy_dbl_matrix(v_res.meanlist);
	destroy_dbl_matrix(v_res.smoothedX);
	destroy_int_array(f_res.binarized_vector);

	UNPROTECT(16);

	return result;
}
Пример #7
0
void mexFunction(
    int nlhs,   mxArray  *plhs[],
    int nrhs,   const mxArray  *prhs[] )

{   double   *Q, *R, *Rout, *indextmp, *normrout, *nreout;

    mwIndex  subs[2];
    mwSize   nsubs=2;
    mwIndex  *index;
    mwSize   n, k1, k, j, nre, method;
    double   alpha, normr, normrold;

    /* CHECK FOR PROPER NUMBER OF ARGUMENTS */

    if (nrhs < 3) {
        mexErrMsgTxt("mexreorth: requires at least 2 input arguments.");
    }
    if (nlhs > 4) {
        mexErrMsgTxt("mexreorth: requires at most 4 output argument.");
    }

    /* CHECK THE DIMENSIONS */

    n  = mxGetM(prhs[0]);
    k1 = mxGetN(prhs[0]);
    if (mxIsSparse(prhs[0])) {
        mexErrMsgTxt("mexreorth: sparse Q not allowed.");
    }
    Q = mxGetPr(prhs[0]);
    if (mxIsSparse(prhs[1])) {
        mexErrMsgTxt("mexreorth: sparse R not allowed.");
    }
    if (mxGetM(prhs[1])!=n || mxGetN(prhs[1])!=1) {
        mexErrMsgTxt("mexreorth: R is not compatible.");
    }
    R = mxGetPr(prhs[1]);
    if (nrhs < 3) {
        normr = sqrt(realdot(R,R,n));
    } else {
        normr = *mxGetPr(prhs[2]);
    }
    if (nrhs < 4) {
        k = k1;
        index = mxCalloc(k,sizeof(mwSize));
        for (j=0; j<k; j++) {
            index[j]=j;
        }
    } else {
        indextmp = mxGetPr(prhs[3]);
        if (indextmp == NULL) {
            mexErrMsgTxt("mexreorth: index is empty");
        }
        k = MAX(mxGetM(prhs[3]),mxGetN(prhs[3]));
        index = mxCalloc(k,sizeof(mwSize));
        for (j=0; j<k; j++) {
            index[j] = (mwSize) (indextmp[j]-1);
        }
    }
    if (nrhs< 5) {
        alpha = 0.5;
    }
    else {
        alpha = *mxGetPr(prhs[4]);
    }
    if (nrhs==5) {
        method = (mwSize)*mxGetPr(prhs[5]);
    }
    else {
        method = 0;
    }

    /***** create return argument *****/
    plhs[0]  = mxCreateDoubleMatrix(n,1,mxREAL);
    Rout     = mxGetPr(plhs[0]);
    plhs[1]  = mxCreateDoubleMatrix(1,1,mxREAL);
    normrout = mxGetPr(plhs[1]);
    plhs[2]  = mxCreateDoubleMatrix(1,1,mxREAL);
    nreout   = mxGetPr(plhs[2]);

    memcpy(mxGetPr(plhs[0]),mxGetPr(prhs[1]),(n)*sizeof(double));

    /***** main  *****/
    normrold = 0;
    nre = 0;
    while ((normr<alpha*normrold) || (nre==0)) {
        mgs(n,Q,Rout,index,k);
        normrold = normr;
        normr = sqrt(realdot(Rout,Rout,n));
        nre = nre+1;
        if (nre > 4) {
            /** printf("R is in span(Q)"); **/
            for (j=0; j<n; j++) {
                Rout[j] = 0;
            }
            normr = 0;
            break;
        }
    }
    normrout[0] = normr;
    nreout[0] = nre;
    return;
}
Пример #8
0
msym_error_t generateOrbitalSubspaces(msym_point_group_t *pg, int esl, msym_equivalence_set_t *es, msym_permutation_t **perm, int basisl, msym_orbital_t basis[basisl], msym_thresholds_t *thresholds, int *subspacel, msym_subspace_t **subspace, int **pspan){
    msym_error_t ret = MSYM_SUCCESS;
    int lmax = -1, nmax = -1, eslmax = -1;
    for(int i = 0;i < basisl;i++){
        lmax = basis[i].l > lmax ? basis[i].l : lmax;
        nmax = basis[i].n > nmax ? basis[i].n : nmax;
    }
    
    if(lmax < 0){ret = MSYM_INVALID_ORBITALS; return ret;} //if we goto err here, code will get ugly due to scope
    
    for(int i = 0;i < esl;i++) eslmax = es[i].length > eslmax ? es[i].length : eslmax;
    
    struct _ltransforms {int d; void *t;} *lts = calloc(lmax+1,sizeof(struct _ltransforms));
    double (*mkron)[(2*lmax+1)*pg->order] = malloc(sizeof(double[(2*lmax+1)*pg->order][(2*lmax+1)*pg->order]));
    double (*mperm)[pg->order] = malloc(sizeof(double[pg->order][pg->order]));
    
    double (*mproj)[pg->ct->l+1][(2*lmax+1)*pg->order][(2*lmax+1)*pg->order] = malloc(sizeof(double[lmax+1][pg->ct->l+1][(2*lmax+1)*pg->order][(2*lmax+1)*pg->order]));
    double (*lspan)[pg->ct->l] = malloc(sizeof(double[lmax+1][pg->ct->l]));
    int (*ispan) = calloc(pg->ct->l,sizeof(int));
    int *aspan = calloc(pg->ct->l,sizeof(int));
    int *nl = malloc(sizeof(int[lmax+1]));
    
    msym_orbital_t *(*omap)[nmax][lmax][2*lmax+1] = malloc(sizeof(msym_orbital_t *[eslmax][nmax+1][lmax+1][2*lmax+1]));
    
    *subspace = NULL;
    
    msym_subspace_t *iss = calloc(pg->ct->l, sizeof(msym_subspace_t));
    for(int k = 0;k < pg->ct->l;k++){
        iss[k].type = ATOMIC_ORBITAL;
        iss[k].irrep = k;
        iss[k].subspacel = esl;
        iss[k].subspace = calloc(esl, sizeof(msym_subspace_t));
    }
    
    for(int l = 0; l <= lmax;l++){
        lts[l].d = 2*l+1;
        lts[l].t = malloc(sizeof(double[pg->sopsl][lts[l].d][lts[l].d]));
        if(MSYM_SUCCESS != (ret = generateOrbitalTransforms(pg->sopsl, pg->sops, l, lts[l].t))) goto err;
    }
    
    for(int i = 0; i < esl;i++){
        int esilmax = -1, esinmax = -1;
        
        memset(nl,0,sizeof(int[lmax+1]));
        for(int j = 0;j < es[i].elements[0]->aol;j++){
            esilmax = esilmax < es[i].elements[0]->ao[j]->l ? es[i].elements[0]->ao[j]->l : esilmax;
            esinmax = esinmax < es[i].elements[0]->ao[j]->n ? es[i].elements[0]->ao[j]->n : esinmax;
            nl[es[i].elements[0]->ao[j]->l] += es[i].elements[0]->ao[j]->m == 0;
        }
        
        msym_orbital_t *(*esomap)[esinmax+1][esilmax+1][2*esilmax+1] = omap;
        
        memset(esomap,0,sizeof(msym_orbital_t *[es->length][esinmax+1][esilmax+1][2*esilmax+1]));
        for(int a = 0;a < es[i].length;a++){
            for(int ao = 0;ao < es[i].elements[a]->aol;ao++){
                msym_orbital_t *o = es[i].elements[a]->ao[ao];
                esomap[a][o->n][o->l][o->m+o->l] = o;
            }
        }
        
        memset(lspan,0,sizeof(double[lmax+1][pg->ct->l]));
        
        for(int l = 0;l <= esilmax;l++){
            int d = es[i].length*lts[l].d;
            double (*mlproj)[d][d] = mproj[l];
            memset(mlproj,0,sizeof(double[pg->ct->l][d][d]));
            memset(ispan,0,sizeof(int[pg->ct->l]));
            
            for(int s = 0;s < pg->sopsl;s++){
                double (*lt)[lts[l].d][lts[l].d] = lts[l].t;
                permutationMatrix(&perm[i][s], mperm);
                kron(perm[i][s].p_length,mperm,lts[l].d,lt[s],d,mkron);
                
                //printSymmetryOperation(&pg->sops[s]);
                //printTransform(d, d, mkron);
                
                for(int k = 0;k < pg->ct->l;k++){
                    lspan[l][k] += pg->ct->irrep[k].v[pg->sops[s].cla]*mltrace(d, mkron);
                    mlscale(pg->ct->irrep[k].v[pg->sops[s].cla], d, mkron, mlproj[pg->ct->l]); //mproj[pg->ct.l] is a workspace
                    mladd(d, mlproj[pg->ct->l], mlproj[k], mlproj[k]); //Could do this based on the span later, but it's not a huge amount of work
                }
            }
            memset(mlproj[pg->ct->l],0,sizeof(double[d][d]));
            int nirrepl = 0;
            for(int k = 0;k < pg->ct->l;k++){
                int lirrepl = nirrepl;
                msym_subspace_t *ss = &iss[k].subspace[i];
                ispan[k] = (((int)round(lspan[l][k]))/pg->order);
                mlscale(((double) pg->ct->irrep[k].d)/pg->order, d, mlproj[k], mlproj[k]);
                nirrepl = mgs(d, mlproj[k], mlproj[pg->ct->l], nirrepl, thresholds->orthogonalization/basisl);
                
                if(nirrepl - lirrepl != ispan[k]*pg->ct->irrep[k].d){
                    //printTransform(d, d, mlproj[k]);
                    ret = MSYM_ORBITAL_ERROR;
                    msymSetErrorDetails("Ortogonal subspace of dimension (%d) inconsistent with span (%d) in %s",nirrepl - lirrepl,ispan[k]*pg->ct->irrep[k].d,pg->ct->irrep[k].name);
                    goto err;
                    
                }
                
                ss->type = ATOMIC_ORBITAL;
                ss->irrep = k;
                
                if(ispan[k] > 0){
                    ss->subspace = realloc(ss->subspace, sizeof(msym_subspace_t[ss->subspacel+nl[l]]));
                    for(int n = l+1; n <= esinmax;n++){
                        if(esomap[0][n][l][0] == NULL) continue;
                        
                        aspan[k] += ispan[k]*pg->ct->irrep[k].d;
                        msym_subspace_t *nss = &ss->subspace[ss->subspacel];
                        memset(nss,0,sizeof(msym_subspace_t));

                        nss->type = ATOMIC_ORBITAL;
                        nss->irrep = ss->irrep;
                        nss->d = ispan[k]*pg->ct->irrep[k].d;
                        double (*space)[d] = malloc(sizeof(double[nss->d][d]));
                        for(int dim = 0; dim < ss->subspace[ss->subspacel].d;dim++){
                            vlnorm2(d, mlproj[pg->ct->l][lirrepl+dim], space[dim]);
                        }
                        nss->space = (double*) space;
                        nss->basisl = 0;
                        nss->basis.o = malloc(sizeof(msym_orbital_t *[d]));
                        for(int e = 0;e < es[i].length;e++){
                            for(int m = -l;m <= l;m++){
                                nss->basis.o[nss->basisl++] = esomap[e][n][l][m+l];
                            }
                        }
                        ss->subspacel++;
                        if(nss->basisl != d) {
                            ret = MSYM_ORBITAL_ERROR;
                            msymSetErrorDetails("Basis length (%d) inconsistent with projection operator dimensions (%d)",nss->basisl,d);
                            goto err;
                        }
                    }
                }
            }
        }
    }

    printf("Subspace span (vectors) = ");
    for(int k = 0;k < pg->ct->l;k++){
        printf(" + %d%s",aspan[k],pg->ct->irrep[k].name);
    }
    printf("\n");
    
    msym_subspace_t tss = {.subspacel = pg->ct->l, .subspace = iss, .d = 0, .basisl = 0, .space = NULL};
    filterSubspace(&tss);
    *subspace = tss.subspace;
    *subspacel = tss.subspacel;
    *pspan = aspan;
    
    free(omap);
    free(nl);
    free(ispan);
    free(lspan);
    free(mproj);
    free(mperm);
    free(mkron);
    for(int l = 0;l <= lmax;l++){
        free(lts[l].t);
    }
    free(lts);
    
    return ret;
    
err:
    free(aspan);
    free(omap);
    free(nl);
    free(ispan);
    free(lspan);
    free(mproj);
    free(mperm);
    free(mkron);
    for(int l = 0;l < lmax;l++){
        free(lts[l].t);
    }
    free(lts);
    for(int k = 0;k < pg->ct->l;k++){
        freeSubspace(&iss[k]);
    }
    free(iss);
    return ret;
}

msym_error_t getOrbitalSubspaces(int ssl, msym_subspace_t ss[ssl], int basisl, msym_orbital_t basis[basisl], double c[basisl][basisl]){
    msym_error_t ret = MSYM_SUCCESS;
    int index = 0;
    memset(c,0,sizeof(double[basisl][basisl]));
    for(int i = 0;i < ssl;i++){
        if(MSYM_SUCCESS != (ret = getOrbitalSubspaceCoefficients(&ss[i],basisl,basis,&index,c))) goto err;
    }
    
    if(index != basisl){
        msymSetErrorDetails("Subspace index (%d) does not match basis length (%d)",index,basisl);
        ret = MSYM_INVALID_SUBSPACE;
        goto err;
    }
    
    return ret;
err:
    return ret;
}