Beispiel #1
0
void fill_row_q(int imin, int imax, int q,
                std::vector< std::vector<ldouble> > & S,
                std::vector< std::vector<size_t> > & J,
                const std::vector<ldouble> & sum_x,
                const std::vector<ldouble> & sum_x_sq,
                const std::vector<ldouble> & sum_w,
                const std::vector<ldouble> & sum_w_sq,
                const enum DISSIMILARITY criterion)
{
  // Assumption: each cluster must have at least one point.
  for(int i=imin; i<=imax; ++i) {
    S[q][i] = S[q-1][i-1];
    J[q][i] = i;
    int jmin = std::max(q, (int)J[q-1][i]);
    for(int j=i-1; j>=jmin; --j) {
      ldouble Sj(S[q-1][j-1] +
        dissimilarity(criterion, j, i, sum_x, sum_x_sq, sum_w, sum_w_sq)
                   // ssq(j, i, sum_x, sum_x_sq, sum_w)
      );

      if(Sj < S[q][i]) {
        S[q][i] = Sj;
        J[q][i] = j;
      }
    }
  }
}
Beispiel #2
0
/*
 *  find the location of queen q
 */
void solve_queen_at(int q, int* i, int* j)
{
	if(q < 0 || q >= SOLVE_NQUEENS || !queen_on(q))
		*i = *j = -1;
	else
	{
		*i = Si(q);
		*j = Sj(q);
	}
}
Beispiel #3
0
/*
 *  set the board to either add or remove queen q
 */
static int sr_queen(int q, int inc)
{
	int i, j;
	int qi = Si(q);
	int qj = Sj(q);

	if(!queen_on(q))
		return -1;

	// spot
	board[qi][qj] += inc;

	// row
	for(j = 0; j < SOLVE_SIZE; ++j)
		if(j != qj)
			board[qi][j] += inc;

	// col
	for(i = 0; i < SOLVE_SIZE; ++i)
		if(i != qi)
			board[i][qj] += inc;

	// diag - right & down
	for(i = qi + 1, j = qj + 1; i < SOLVE_SIZE && j < SOLVE_SIZE; ++i, ++j)
		board[i][j] += inc;

	// diag - right & up
	for(i = qi - 1, j = qj + 1; i >= 0 && j < SOLVE_SIZE; --i, ++j)
		board[i][j] += inc;

	// diag - left & down
	for(i = qi + 1, j = qj - 1; i < SOLVE_SIZE && j >= 0; ++i, --j)
		board[i][j] += inc;

	// diag - left & up
	for(i = qi - 1, j = qj - 1; i >= 0 && j >= 0; --i, --j)
		board[i][j] += inc;

	return 0;
}
BasicMesh MeshTransferer::transfer(const vector<PhGUtils::Matrix3x3d> &S1grad)
{
  if( !(S0set && T0set) ) {
    throw "S0 or T0 not set.";
  }

  auto &S = S1grad;
  auto &T = T0grad;

  int nfaces = S0.faces.nrow;
  int nverts = S0.verts.nrow;

  // assemble sparse matrix A
  int nrowsA = nfaces * 3;
  int nsv = stationary_vertices.size();
  int nrowsC = nsv;
  int nrows = nrowsA + nrowsC;
  int ncols = nverts;
  int ntermsA = nfaces*9;
  int ntermsC = stationary_vertices.size();
  int nterms = ntermsA + ntermsC;
  SparseMatrix A(nrows, ncols, nterms);
  // fill in the deformation gradient part
  for(int i=0, ioffset=0;i<nfaces;++i) {
    /*
     * Ai:
     *     1 2 3 4 5 ... nfaces*3
     *     1 2 3 4 5 ... nfaces*3
     *     1 2 3 4 5 ... nfaces*3
     * Ai = reshape(Ai, 1, nfaces*9)
     *
     * Aj = reshape(repmat(S0.faces', 3, 1), 1, nfaces*9)
     * Av = reshape(cell2mat(T)', 1, nfaces*9)
     */
    int *f = S0.faces.rowptr(i);

    auto Ti = T[i];

    A.append(ioffset, f[0], Ti(0));
    A.append(ioffset, f[1], Ti(1));
    A.append(ioffset, f[2], Ti(2));
    ++ioffset;

    A.append(ioffset, f[0], Ti(3));
    A.append(ioffset, f[1], Ti(4));
    A.append(ioffset, f[2], Ti(5));
    ++ioffset;

    A.append(ioffset, f[0], Ti(6));
    A.append(ioffset, f[1], Ti(7));
    A.append(ioffset, f[2], Ti(8));
    ++ioffset;
  }

  // fill in the lower part of A, stationary vertices part
  for(int i=0;i<nsv;++i) {
    A.append(nrowsA+i, stationary_vertices[i], 1);
  }

  ofstream fA("A.txt");
  fA<<A;
  fA.close();

  // fill in c matrix
  DenseMatrix c(nrows, 3);
  for(int i=0;i<3;++i) {
    for(int j=0, joffset=0;j<nfaces;++j) {
      auto &Sj = S[j];
      c(joffset, i) = Sj(0, i); ++joffset;
      c(joffset, i) = Sj(1, i); ++joffset;
      c(joffset, i) = Sj(2, i); ++joffset;
    }
  }
  for(int i=0;i<3;++i) {
    for(int j=0, joffset=nrowsA;j<nsv;++j,++joffset) {
      auto vj = T0.verts.rowptr(stationary_vertices[j]);
      c(joffset, i) = vj[i];
    }
  }

  cholmod_sparse *G = A.to_sparse();
  cholmod_sparse *Gt = cholmod_transpose(G, 2, global::cm);

  // compute GtD
  // just multiply Dsi to corresponding elemenets
  double *Gtx = (double*)Gt->x;
  const int* Gtp = (const int*)(Gt->p);
  for(int i=0;i<nrowsA;++i) {
    int fidx = i/3;
    for(int j=Gtp[i];j<Gtp[i+1];++j) {
      Gtx[j] *= Ds(fidx);
    }
  }

  // compute GtDG
  cholmod_sparse *GtDG = cholmod_ssmult(Gt, G, 0, 1, 1, global::cm);
  GtDG->stype = 1;

  // compute GtD * c
  cholmod_dense *GtDc = cholmod_allocate_dense(ncols, 3, ncols, CHOLMOD_REAL, global::cm);
  double alpha[2] = {1, 0}; double beta[2] = {0, 0};
  cholmod_sdmult(Gt, 0, alpha, beta, c.to_dense(), GtDc, global::cm);

  // solve for GtDG \ GtDc
  cholmod_factor *L = cholmod_analyze(GtDG, global::cm);
  cholmod_factorize(GtDG, L, global::cm);
  cholmod_dense *x = cholmod_solve(CHOLMOD_A, L, GtDc, global::cm);

  // make a copy of T0
  BasicMesh Td = T0;

  // change the vertices with x
  double *Vx = (double*)x->x;
  for(int i=0;i<nverts;++i) {
    Td.verts(i, 0) = Vx[i];
    Td.verts(i, 1) = Vx[i+nverts];
    Td.verts(i, 2) = Vx[i+nverts*2];
  }

  // release memory
  cholmod_free_sparse(&G, global::cm);
  cholmod_free_sparse(&Gt, global::cm);
  cholmod_free_sparse(&GtDG, global::cm);
  cholmod_free_dense(&GtDc, global::cm);
  cholmod_free_factor(&L, global::cm);
  cholmod_free_dense(&x, global::cm);

  return Td;
}
Beispiel #5
0
/*
 *  make the next solve move
 */
int solve_next_move()
{
	int moved = 0;
	int on; 

	// done - found solution
	if(queen == SOLVE_NQUEENS)
	{
		sprintf(move_buff[(move_count++)%MOVE_WRAP], "Complete!!!");
		return 1;
	} 
	// done - did not find solution
	if(queen < 0)
	{
		sprintf(move_buff[(move_count++)%MOVE_WRAP], "Failed.");
		return -1;
	}

	// should only run once or twice
	while(!moved)
	{
		on = queen_on(queen);
		moved = 1;
		// from last time
		if(on)
		{
			remove_queen(queen); 
		}
		// add to board
		else
		{
			stack[queen].di = rand()%SOLVE_SIZE;
			stack[queen].dj = rand()%SOLVE_SIZE;
			stack[queen].i = 0;
		}

		// find open spot
		do
		{
			// increment position
			++stack[queen].j;
			if(stack[queen].j == SOLVE_SIZE){
				stack[queen].j = 0;
				++stack[queen].i;

				// exhausted - backtrack
				if(stack[queen].i == SOLVE_SIZE)
				{
					stack[queen].i = stack[queen].j = -1;
					--queen;
					if(on){
						mn = 0;
						sprintf(move_buff[(move_count++)%MOVE_WRAP],
								"...Exhausted spaces for Queen %d.", queen+2);
						return 0;
					}
					mn = 1;
					sprintf(move_buff[(move_count++)%MOVE_WRAP],
							"...No place for Queen %d.", queen+2);

					moved = 0;
					break;
				}
			}
		} while(!solve_spot_open(Si(queen), Sj(queen)));
	}
	mn = 0;
	sprintf(move_buff[(move_count++)%MOVE_WRAP], 
			"Move Queen %d to %c%d.", queen+1, Si(queen)+'A', Sj(queen)+1);

	// place queen
	set_queen(queen);

	// get next queen
	++queen;

	return 0;
}