void Game::spirale() { map.resize(512, 512, 1, 3); map.fill(255); m_size = 512; m_stateCard = 2; m_colorCard = 2; m_automate = new Triplet*[m_stateCard]; for(int i = 0; i < m_stateCard; ++i) m_automate[i] = new Triplet[m_colorCard]; m_automate[0][0] = Triplet(1, 1, 1); m_automate[0][1] = Triplet(1, 8, 0); m_automate[1][0] = Triplet(1, 2, 1); m_automate[1][1] = Triplet(0, 1, 0); m_color = new uchar*[m_colorCard]; m_color[0] = new uchar[3]; m_color[0][0] = 255; m_color[0][1] = 255; m_color[0][2] = 255; m_color[1] = new uchar[3]; m_color[1][0] = 0; m_color[1][1] = 0; m_color[1][2] = 0; }
void FastMassSpring::fillJMatrix(TripletList& triplets, Edges& edges, int edge_counts) { for (decltype(edges.size()) i = 0; i != edges.size(); ++i) { for (int j = 0; j < 3; ++j) { triplets.push_back(Triplet(3 * edges[i].first + j, 3 * (i + edge_counts) + j, 1)); triplets.push_back(Triplet(3 * edges[i].second + j, 3 * (i + edge_counts) + j, -1)); } } }
void MeshGeometry::extract_faces_from_tets() { const VectorI& voxels = m_voxels; typedef std::map<Triplet, int> FaceCounter; FaceCounter face_counter; for (size_t i=0; i<voxels.size(); i+= m_vertex_per_voxel) { VectorI voxel = voxels.segment(i, m_vertex_per_voxel); // Note that the order of vertices below are predefined by MSH format, // each face should have normal pointing outward. assert(voxel.size() == 4); Triplet voxel_faces[4] = { Triplet(voxel[0], voxel[2], voxel[1]), Triplet(voxel[0], voxel[1], voxel[3]), Triplet(voxel[0], voxel[3], voxel[2]), Triplet(voxel[1], voxel[2], voxel[3]) }; for (size_t j=0; j<4; j++) { if (face_counter.find(voxel_faces[j]) == face_counter.end()) { face_counter[voxel_faces[j]] = 1; } else { face_counter[voxel_faces[j]] += 1; } } } std::vector<int> vertex_buffer; for (FaceCounter::const_iterator itr = face_counter.begin(); itr!=face_counter.end(); itr++) { if (itr->second != 1 && itr->second != 2) { const Vector3I& triplet = itr->first.get_ori_data(); std::stringstream err_msg; err_msg << "Non-manifold mesh detected!" << std::endl; err_msg << "Face <" << triplet[0] << ", " << triplet[1] << ", " << triplet[2] << "> has " << itr->second << " adjacent volume elements"; throw RuntimeError(err_msg.str()); } if (itr->second == 1) { const VectorI& f = itr->first.get_ori_data(); assert(f.size() == 3); vertex_buffer.push_back(f[0]); vertex_buffer.push_back(f[1]); vertex_buffer.push_back(f[2]); } } m_faces.resize(vertex_buffer.size()); std::copy(vertex_buffer.begin(), vertex_buffer.end(), m_faces.data()); m_vertex_per_face = 3; }
void FastMassSpring::fillLMatrix(TripletList& triplets, Edges& edges) { for (auto& i : edges) { for (int j = 0; j < 3; ++j) { triplets.push_back(Triplet(3 * i.first + j, 3 * i.first + j, 1)); triplets.push_back(Triplet(3 * i.first + j, 3 * i.second + j, -1)); triplets.push_back(Triplet(3 * i.second + j, 3 * i.first + j, -1)); triplets.push_back(Triplet(3 * i.second + j, 3 * i.second + j, 1)); } } }
IMEXIntegrator::IMEXIntegrator(std::vector<RodEnergy*>& energies, Rod& r) : Integrator(r, energies) { // Fill hess base std::vector<Triplet> triplets; for (int i=1; i < r.numEdges()-1; i++) { if (i > 1) { triplets.push_back(Triplet(i-1, i-2, -2.0*r.getCS()[i].twistCoeff()/r.restVoronoiLength(i))); } if (i < r.numEdges()-2) { triplets.push_back(Triplet(i-1, i, -2.0*r.getCS()[i+1].twistCoeff()/r.restVoronoiLength(i+1))); } } hessBase = Eigen::SparseMatrix<real>(r.numEdges()-2, r.numEdges()-2); hessBase.setFromTriplets(triplets.begin(), triplets.end()); }
/** * Return the coefficients for KRON. * * Parameters: linOp LIN with type KRON * Returns: vector containing the coefficient matrix for the Kronecker product. */ std::vector<Matrix> get_kron_mat(LinOp &lin) { assert(lin.type == KRON); Matrix constant = get_constant_data(lin, false); int lh_rows = constant.rows(); int lh_cols = constant.cols(); int rh_rows = lin.args[0]->size[0]; int rh_cols = lin.args[0]->size[1]; int rows = rh_rows * rh_cols * lh_rows * lh_cols; int cols = rh_rows * rh_cols; Matrix coeffs(rows, cols); std::vector<Triplet> tripletList; tripletList.reserve(rh_rows * rh_cols * constant.nonZeros()); for ( int k = 0; k < constant.outerSize(); ++k ) { for ( Matrix::InnerIterator it(constant, k); it; ++it ) { int row = (rh_rows * rh_cols * (lh_rows * it.col())) + (it.row() * rh_rows); int col = 0; for(int j = 0; j < rh_cols; j++){ for(int i = 0; i < rh_rows; i++) { tripletList.push_back(Triplet(row + i, col, it.value())); col++; } row += lh_rows * rh_rows; } } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
/** * Return the coefficients for RMUL (right multiplication): a ROWS * N * by COLS * N matrix given by the kronecker product between the * transpose of the constant matrix CONSTANT and a N x N identity matrix. * * Parameters: linOp of type RMUL * * Returns: vector containing the corresponding coefficient matrix COEFFS * */ std::vector<Matrix> get_rmul_mat(LinOp &lin) { assert(lin.type == RMUL); Matrix constant = get_constant_data(lin, false); int rows = constant.rows(); int cols = constant.cols(); int n = lin.size[0]; Matrix coeffs(cols * n, rows * n); std::vector<Triplet> tripletList; tripletList.reserve(n * constant.nonZeros()); for ( int k = 0; k < constant.outerSize(); ++k ) { for ( Matrix::InnerIterator it(constant, k); it; ++it ) { double val = it.value(); // each element of CONSTANT occupies an N x N block in the matrix int row_start = it.col() * n; int col_start = it.row() * n; for (int i = 0; i < n; i++) { int row_idx = row_start + i; int col_idx = col_start + i; tripletList.push_back(Triplet(row_idx, col_idx, val)); } } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
void static calcRotEqs(const Rod& r, const VecXe& rot, const std::vector<Vec3e>& curveBinorm, VecXe& grad, std::vector<Triplet>& triplets) { Eigen::Matrix<real, 2, 2> J; J << 0.0, -1.0, 1.0, 0.0; for (int i=1; i<r.numEdges()-1; i++) { Vec3e m1 = cos(rot(i)) * r.next().u[i] + sin(rot(i)) * r.next().v(i); Vec3e m2 = -sin(rot(i)) * r.next().u[i] + cos(rot(i)) * r.next().v(i); Vec2e curvePrev(curveBinorm[i-1].dot(m2), -curveBinorm[i-1].dot(m1)); // omega ^i _i Vec2e curveNext(curveBinorm[i].dot(m2), -curveBinorm[i].dot(m1)); // omega ^i _i+1 real dWprev = 1.0 / r.restVoronoiLength(i) * curvePrev.dot(J * r.getCS()[i].bendMat() * (curvePrev - r.restCurveNext(i))); real dWnext = 1.0 / r.restVoronoiLength(i+1) * curveNext.dot(J * r.getCS()[i+1].bendMat() * (curveNext - r.restCurvePrev(i+1))); real twistPrev = rot(i) - rot(i-1) + r.next().refTwist(i); real twistNext = rot(i+1) - rot(i) + r.next().refTwist(i+1); grad(i-1) = -(dWprev + dWnext + 2.0 * r.getCS()[i].twistCoeff() * (twistPrev/r.restVoronoiLength(i) - twistNext/r.restVoronoiLength(i+1))); real hess = 2.0*(r.getCS()[i].twistCoeff()/r.restVoronoiLength(i) + r.getCS()[i+1].twistCoeff()/r.restVoronoiLength(i+1)); hess += 1.0 / r.restVoronoiLength(i) * (curvePrev.dot(J.transpose() * r.getCS()[i].bendMat() * J * curvePrev) - curvePrev.dot(r.getCS()[i].bendMat() * (curvePrev - r.restCurveNext(i)))); hess += 1.0 /r.restVoronoiLength(i+1) * (curveNext.dot(J.transpose() * r.getCS()[i+1].bendMat() * J * curveNext) - curveNext.dot(r.getCS()[i+1].bendMat() * (curveNext - r.restCurvePrev(i+1)))); triplets.push_back(Triplet(i-1, i-1, hess)); } }
/** * Return the coefficients for MUL (left multiplication): a NUM_BLOCKS * ROWS * by NUM_BLOCKS * COLS block diagonal matrix where each diagonal block is the * constant data BLOCK. * * Parameters: linOp with type MUL * * Returns: vector containing coefficient matrix COEFFS * */ std::vector<Matrix> get_mul_mat(LinOp &lin) { assert(lin.type == MUL); Matrix block = get_constant_data(lin, false); int block_rows = block.rows(); int block_cols = block.cols(); // Don't replicate scalars if(block_rows == 1 && block_cols == 1){ return build_vector(block); } int num_blocks = lin.size[1]; Matrix coeffs (num_blocks * block_rows, num_blocks * block_cols); std::vector<Triplet> tripletList; tripletList.reserve(num_blocks * block.nonZeros()); for (int curr_block = 0; curr_block < num_blocks; curr_block++) { int start_i = curr_block * block_rows; int start_j = curr_block * block_cols; for ( int k = 0; k < block.outerSize(); ++k ) { for ( Matrix::InnerIterator it(block, k); it; ++it ) { tripletList.push_back(Triplet(start_i + it.row(), start_j + it.col(), it.value())); } } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
/** * Return the coefficients for UPPER_TRI: an ENTRIES by ROWS * COLS matrix * where the i, j entry in the original matrix has a 1 in row COUNT and * corresponding column if j > i and 0 otherwise. * * Parameters: LinOp with type UPPER_TRI. * Returns: vector of coefficients for upper triangular matrix linOp */ std::vector<Matrix> get_upper_tri_mat(LinOp &lin) { assert(lin.type == UPPER_TRI); int rows = lin.args[0]->size[0]; int cols = lin.args[0]->size[1]; int entries = lin.size[0]; Matrix coeffs(entries, rows * cols); std::vector<Triplet> tripletList; tripletList.reserve(entries); int count = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { if (j > i) { // index in the extracted vector int row_idx = count; count++; // index in the original matrix int col_idx = j * rows + i; tripletList.push_back(Triplet(row_idx, col_idx, 1.0)); } } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
Triplet rot2eularZYX(T& m) { float rx = atan2(m[1][2], m[2][2])*DEG_PER_PI; float c2 = sqrt(m[0][0]*m[0][0] + m[0][1]*m[0][1]); float ry = atan2(-m[0][2], c2)*DEG_PER_PI; float rz = atan2(m[0][1], m[0][0])*DEG_PER_PI; return Triplet(rz, ry, rx); }
// Calculated via MatLAB, here we only import its result. std::vector<Triplet> Triplet::delaunay_triangulation() { std::vector<Triplet> result; for( int i = 0; i < TRIPLET_SIZE; i++ ) result.push_back( Triplet( hrtf_triplets[ i ] ) ); return result; }
void TriMesh::buildHeatKernel(SparseMatrix& A, double timestep) const { VectorXd diag; computeVertArea(diag); std::map< std::pair<unsigned,unsigned>, double > offdiag; for (unsigned face = 0; face < numFaces(); ++face) { std::vector<unsigned> fVert; getFaceVerts(face, fVert); assert(fVert.size() == 3); for (unsigned i = 0; i < 3; ++i) { unsigned vert0 = fVert[(i+1)%3]; unsigned vert1 = fVert[(i+2)%3]; if (vert0 > vert1) std::swap(vert0, vert1); std::pair<unsigned,unsigned> edge(vert0,vert1); double value = timestep * 0.5 * computeFaceCotan(face, i); diag(vert0) += value; diag(vert1) += value; if (offdiag.find(edge) == offdiag.end()) offdiag[edge] = -value; else offdiag[edge] -= value; } } std::vector<Triplet> triplet; for(unsigned i = 0; i < diag.size(); ++i) { triplet.push_back(Triplet(i,i,diag(i))); } for(std::map< std::pair<unsigned,unsigned>, double >::const_iterator it = offdiag.begin(); it != offdiag.end(); ++it) { triplet.push_back(Triplet(it->first.first,it->first.second,it->second)); triplet.push_back(Triplet(it->first.second,it->first.first,it->second)); } A.resize(numVerts(), numVerts()); A.setFromTriplets(triplet.begin(),triplet.end()); }
/** * Return the coefficients for INDEX: a N by ROWS*COLS matrix * where N is the number of total elements in the slice. Element i, j * is 1 if element j in the vectorized matrix is the i-th element of the * slice and 0 otherwise. * * Parameters: LinOp of type INDEX * * Returns: vector containing coefficient matrix COEFFS * */ std::vector<Matrix> get_index_mat(LinOp &lin) { assert(lin.type == INDEX); int rows = lin.args[0]->size[0]; int cols = lin.args[0]->size[1]; Matrix coeffs (lin.size[0] * lin.size[1], rows * cols); /* If slice is empty, return empty matrix */ if (coeffs.rows () == 0 || coeffs.cols() == 0) { return build_vector(coeffs); } std::vector<std::vector<int> > slices = get_slice_data(lin, rows, cols); /* Row Slice Data */ int row_start = slices[0][0]; int row_end = slices[0][1]; int row_step = slices[0][2]; /* Column Slice Data */ int col_start = slices[1][0]; int col_end = slices[1][1]; int col_step = slices[1][2]; /* Set the index coefficients by looping over the column selection * first to remain consistent with CVXPY. */ std::vector<Triplet> tripletList; int col = col_start; int counter = 0; while (true) { if (col < 0 || col >= cols) { break; } int row = row_start; while (true) { if (row < 0 || row >= rows) { break; } int row_idx = counter; int col_idx = col * rows + row; tripletList.push_back(Triplet(row_idx, col_idx, 1.0)); counter++; row += row_step; if ((row_step > 0 && row >= row_end) || (row_step < 0 && row <= row_end)) { break; } } col += col_step; if ((col_step > 0 && col >= col_end) || (col_step < 0 && col <= col_end)) { break; } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
bool List_Triplets(const GraphT & g, std::vector< Triplet > & vec_triplets) { // Algorithm // //-- For each node // - list the outgoing not visited edge // - for each tuple of edge // - if their end are connected // Detected cyle of length 3 // Mark first edge as visited typedef typename GraphT::OutArcIt OutArcIt; typedef typename GraphT::NodeIt NodeIterator; typedef typename GraphT::template EdgeMap<bool> BoolEdgeMap; BoolEdgeMap map_edge(g, false); // Visited edge map // For each nodes for (NodeIterator itNode(g); itNode != INVALID; ++itNode) { // For each edges (list the not visited outgoing edges) std::vector<OutArcIt> vec_edges; for (OutArcIt e(g, itNode); e!=INVALID; ++e) { if (!map_edge[e]) // If not visited vec_edges.push_back(e); } // For all tuples look of ends of edges are linked while(vec_edges.size()>1) { OutArcIt itPrev = vec_edges[0]; // For all tuple (0,Inth) for(size_t i=1; i < vec_edges.size(); ++i) { // Check if the extremity is linked typename GraphT::Arc cycleEdge = findArc(g, g.target(itPrev), g.target(vec_edges[i])); if (cycleEdge!= INVALID && !map_edge[cycleEdge]) { // Elementary cycle found (make value follow a monotonic ascending serie) int triplet[3] = { g.id(itNode), g.id(g.target(itPrev)), g.id(g.target(vec_edges[i]))}; std::sort(&triplet[0], &triplet[3]); vec_triplets.push_back(Triplet(triplet[0],triplet[1],triplet[2])); } } // Mark the current ref edge as visited map_edge[itPrev] = true; // remove head to list remaining tuples vec_edges.erase(vec_edges.begin()); } } return (!vec_triplets.empty()); }
void HashSparseMatrix::Add( int i, int j, double value, TripletVector & data ) { int key = i + j * 65536; HashMapIterator it = map_.find( key ); if ( it == map_.end() ) { map_.insert( IntPair( key, data.size() ) ); data.push_back( Triplet( i + ioffset_, j + joffset_, value ) ); } else { data[ it->second ].m_value += value; } }
VectorF convert_voxel_attribute_to_face_attribute( Mesh& mesh, const VectorF& attribute) { const size_t num_faces = mesh.get_num_faces(); const size_t num_voxels = mesh.get_num_voxels(); const size_t attr_size = attribute.size(); const size_t stride = attr_size / num_voxels; const size_t vertex_per_voxel = mesh.get_vertex_per_voxel(); const size_t vertex_per_face = mesh.get_vertex_per_face(); if (vertex_per_voxel != 4) throw NotImplementedError("Voxel type is not yet supported"); if (vertex_per_face != 3) throw NotImplementedError("Face type is not yet supported"); const VectorI& faces = mesh.get_faces(); const VectorI& voxels = mesh.get_voxels(); std::map<Triplet, VectorF> per_face_values; for (size_t i=0; i<num_voxels; i++) { const VectorI& voxel = voxels.segment( i*vertex_per_voxel, vertex_per_voxel); const VectorF& value = attribute.segment( i*stride, stride); per_face_values[Triplet(voxel[0], voxel[1], voxel[2])] = value; per_face_values[Triplet(voxel[0], voxel[1], voxel[3])] = value; per_face_values[Triplet(voxel[0], voxel[2], voxel[3])] = value; per_face_values[Triplet(voxel[1], voxel[2], voxel[3])] = value; } VectorF result = VectorF::Zero(num_faces*stride); for (size_t i=0; i<num_faces; i++) { const VectorI& face = faces.segment(i*vertex_per_face, vertex_per_face); result.segment(i*stride, stride) = per_face_values[ Triplet(face[0], face[1], face[2])]; } return result; }
Matrix sparse_reshape_to_vec(Matrix &mat) { int rows = mat.rows(); int cols = mat.cols(); Matrix out(rows * cols, 1); std::vector<Triplet> tripletList; tripletList.reserve(rows * cols); for ( int k = 0; k < mat.outerSize(); ++k) { for (Matrix::InnerIterator it(mat, k); it; ++it) { tripletList.push_back(Triplet(it.col() * rows + it.row(), 0, it.value())); } } out.setFromTriplets(tripletList.begin(), tripletList.end()); out.makeCompressed(); return out; }
/** * Return the coefficients for MUL_ELEM: an N x N diagonal matrix where the * n-th element on the diagonal corresponds to the element n = j*rows + i in * the data matrix CONSTANT. * * Parameters: linOp of type MUL_ELEM * * Returns: vector containing the coefficient matrix COEFFS * */ std::vector<Matrix> get_mul_elemwise_mat(LinOp &lin) { assert(lin.type == MUL_ELEM); Matrix constant = get_constant_data(lin, true); int n = constant.rows(); // build a giant diagonal matrix std::vector<Triplet> tripletList; tripletList.reserve(n); for ( int k = 0; k < constant.outerSize(); ++k ) { for ( Matrix::InnerIterator it(constant, k); it; ++it ) { tripletList.push_back(Triplet(it.row(), it.row(), it.value())); } } Matrix coeffs(n, n); coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
/** * Return the coefficients for DIAG_VEC (vector to diagonal matrix): a * N^2 by N matrix where each column I has a 1 in row I * N + I * corresponding to the diagonal entry and 0 otherwise. * * Parameters: linOp of type DIAG_VEC * * Returns: vector containing coefficient matrix COEFFS * */ std::vector<Matrix> get_diag_vec_mat(LinOp &lin) { assert(lin.type == DIAG_VEC); int rows = lin.size[0]; Matrix coeffs(rows * rows, rows); std::vector<Triplet> tripletList; tripletList.reserve(rows); for (int i = 0; i < rows; i++) { // index in the diagonal matrix int row_idx = i * rows + i; //index in the original vector int col_idx = i; tripletList.push_back(Triplet(row_idx, col_idx, 1.0)); } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
/** * Return the coefficients for TRANSPOSE: a ROWS*COLS by ROWS*COLS matrix * such that element ij in the vectorized matrix is mapped to ji after * multiplication (i.e. entry (rows * j + i, i * cols + j) = 1 and else 0) * * Parameters: linOp of type TRANSPOSE * * Returns: vector containing coefficient matrix COEFFS * */ std::vector<Matrix> get_transpose_mat(LinOp &lin) { assert(lin.type == TRANSPOSE); int rows = lin.size[0]; int cols = lin.size[1]; Matrix coeffs(rows * cols, rows * cols); std::vector<Triplet> tripletList; tripletList.reserve(rows * cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { int row_idx = rows * j + i; int col_idx = i * cols + j; tripletList.push_back(Triplet(row_idx, col_idx, 1.0)); } } coeffs.setFromTriplets(tripletList.begin(), tripletList.end()); coeffs.makeCompressed(); return build_vector(coeffs); }
CRDFTriplet CRDFNode::addEdge(const CRDFPredicate & predicate, CRDFNode * pObject) { CRDFTriplet Failed; CRDFTriplet Triplet(this, predicate, pObject); // We do not want any duplicate triplets; if (mGraph.getTriplets().count(Triplet) > 0) return Failed; // If this is a bag node the only predicate allowed is rdf_li. if (isBagNode() && predicate != CRDFPredicate::rdf_li) return Failed; // If the predicate is rdf:li and this is not a bag node we bagify it. if (!isBagNode() && predicate == CRDFPredicate::rdf_li) { // Bagify the node. CRDFObject Object; Object.setType(CRDFObject::RESOURCE); Object.setResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag", false); if (!mGraph.addTriplet(this->getSubject(), CRDFPredicate(CRDFPredicate::rdf_type), Object)) return Failed; } // We now can safely insert any edge with the predicate rdf_li if (predicate == CRDFPredicate::rdf_li) { if (!addTripletToGraph(Triplet)) return Failed; return Triplet; } if (!addTripletToGraph(Triplet)) return Failed; return Triplet; }
/** * Builds and returns the stacked coefficient matrices for both horizontal * and vertical stacking linOps. * * Constructs coefficient matrix COEFF for each argument of LIN. COEFF is * essentially an identity matrix with an offset to account for stacking. * * If the stacking is vertical, the columns of the matrix for each argument * are interleaved with each other. Otherwise, if the stacking is horizontal, * the columns are laid out in the order of the arguments. * * Parameters: linOP LIN that performs a stacking operation (HSTACK or VSTACK) * boolean VERTICAL: True if vertical stack. False otherwise. * * Returns: vector COEFF_MATS containing the stacked coefficient matrices * for each argument. * */ std::vector<Matrix> stack_matrices(LinOp &lin, bool vertical) { std::vector<Matrix> coeffs_mats; int offset = 0; int num_args = lin.args.size(); for (int idx = 0; idx < num_args; idx++) { LinOp arg = *lin.args[idx]; /* If VERTICAL, columns that are interleaved. Otherwise, they are laid out in order. */ int column_offset; int offset_increment; if (vertical) { column_offset = lin.size[0]; offset_increment = arg.size[0]; } else { column_offset = arg.size[0]; offset_increment = arg.size[0] * arg.size[1]; } std::vector<Triplet> tripletList; tripletList.reserve(arg.size[0] * arg.size[1]); for (int i = 0; i < arg.size[0]; i++) { for (int j = 0; j < arg.size[1]; j++) { int row_idx = i + (j * column_offset) + offset; int col_idx = i + (j * arg.size[0]); tripletList.push_back(Triplet(row_idx, col_idx, 1)); } } Matrix coeff(lin.size[0] * lin.size[1], arg.size[0] * arg.size[1]); coeff.setFromTriplets(tripletList.begin(), tripletList.end()); coeff.makeCompressed(); coeffs_mats.push_back(coeff); offset += offset_increment; } return coeffs_mats; }
/** * Return the coefficients for CONV operator. The coefficient matrix is * constructed by creating a toeplitz matrix with the constant vector * in DATA as the columns. Multiplication by this matrix is equivalent * to convolution. * * Parameters: linOp LIN with type CONV. Data should should contain a * column vector that the variables are convolved with. * * Returns: vector of coefficients for convolution linOp */ std::vector<Matrix> get_conv_mat(LinOp &lin) { assert(lin.type == CONV); Matrix constant = get_constant_data(lin, false); int rows = lin.size[0]; int nonzeros = constant.rows(); int cols = lin.args[0]->size[0]; Matrix toeplitz(rows, cols); std::vector<Triplet> tripletList; tripletList.reserve(nonzeros * cols); for (int col = 0; col < cols; col++) { int row_start = col; for ( int k = 0; k < constant.outerSize(); ++k ) { for ( Matrix::InnerIterator it(constant, k); it; ++it ) { int row_idx = row_start + it.row(); tripletList.push_back(Triplet(row_idx, col, it.value())); } } } toeplitz.setFromTriplets(tripletList.begin(), tripletList.end()); toeplitz.makeCompressed(); return build_vector(toeplitz); }
void BatchTripletLossLayer<Dtype>::Forward_cpu( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // The forward pass computes the pairwise distances. const Dtype* feat_data = bottom[0]->cpu_data(); const Dtype* label = bottom[1]->cpu_data(); Dtype* loss_data = top[0]->mutable_cpu_data(); Dtype* accy_data = top[1]->mutable_cpu_data(); int num = bottom[0]->num(); int dim = bottom[0]->count() / num; bool sample = this->layer_param_.triplet_loss_param().sample(); /** * Computing the pairwise Euclidean distance */ Dtype* norm_data = norm_.mutable_cpu_data(); memset(norm_data, 0, norm_.count() * sizeof(norm_data[0])); triplets_.clear(); pos_pairs_.clear(); Dtype* dist_data = dist_.mutable_cpu_data(); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasTrans, num, num, dim, Dtype(-2), feat_data, feat_data, Dtype(0), dist_data); for (int i=0; i<num; ++i) { norm_data[i] = -0.5 * dist_.data_at(i, i, 0, 0); } for (int i=0; i<num; ++i) { dist_data = dist_.mutable_cpu_data() + dist_.offset(i); for (int j=0; j<num; ++j) { dist_data[j] += (norm_data[i] + norm_data[j]); } } /** * Find boundary of different classes. * A batch is composed by small groups with items belongs to the same class. * e.g. gruop size is 3, batch size is 15: * 1 1 1 2 2 2 3 3 3 1 1 1 4 4 4 */ vector<int> boundary; Dtype prev = Dtype(-1); for (int i=0; i<num; ++i) { if (prev != label[i]) { boundary.push_back(i); prev = label[i]; } } boundary.push_back(num); /** * Sampling triplets and computing the loss */ Dtype pair_loss = Dtype(0); Dtype rank_loss = Dtype(0); Dtype smp_rank_loss = Dtype(0); int num_tri = 0; int num_err = 0; Dtype cur_rank_loss; Dtype pos_dist; Dtype neg_dist; Dtype one_minus_mu = Dtype(1) - mu_; if (one_minus_mu > Dtype(0)) { // classes for (int c=0; c<boundary.size()-1; c++) { // query for (int i=boundary[c]; i<boundary[c+1]; ++i) { const Dtype * dist_data = dist_.cpu_data() + dist_.offset(i); // positive for (int j=boundary[c]; j<boundary[c+1]; ++j) { if (i == j) { continue; } pair_loss += dist_data[j]; pos_pairs_.push_back(make_pair<int, int>(i, j)); } } } } int num_pair = pos_pairs_.size(); pair_loss = num_pair > 0 ? pair_loss / num_pair : 0; // classes for (int c=0; c<boundary.size()-1; c++) { // query for (int i=boundary[c]; i<boundary[c+1]; ++i) { const Dtype * dist_data = dist_.cpu_data() + dist_.offset(i); // positive for (int j=boundary[c]; j<boundary[c+1]; ++j) { if (i == j) { continue; } pos_dist = dist_data[j]; // negative groups for (int m=0; m<boundary.size()-1; m++) { if (label[boundary[m]] == label[i]) { continue; } // negative for (int k=boundary[m]; k<boundary[m+1]; ++k) { ++num_tri; neg_dist = dist_data[k]; // DLOG(INFO) << "\t" << pos_dist << "\t" << neg_dist; cur_rank_loss = margin_ + pos_dist - neg_dist; // LOG(INFO) << cur_rank_loss; num_err += (pos_dist >= neg_dist); if (cur_rank_loss > 0) { rank_loss += cur_rank_loss; if (!sample || neg_dist > pos_dist) { smp_rank_loss += cur_rank_loss; triplets_.push_back(Triplet(i, j, k)); } } } // end of negative } // end of negative groups } // end of positive } // end of query } // end of classes rank_loss = num_tri > 0 ? rank_loss / num_tri : 0; // average loss among all triplets loss_data[0] = rank_loss * mu_ + pair_loss * one_minus_mu; // average accuracy among all triplets accy_data[0] = Dtype(1) - (num_tri > 0 ? Dtype(num_err) / num_tri : 0); if (top.size() == 3) { int num_smp = triplets_.size(); Dtype* debug_data = top[2]->mutable_cpu_data(); // 0: average rank loss over sampled triplets debug_data[0] = num_smp > 0 ? smp_rank_loss / num_smp : 0; // 1: average rank loss over all triplets debug_data[1] = rank_loss; // 2: average pair loss debug_data[2] = pair_loss; // 3: number of possible triplets debug_data[3] = num_tri; // 4: number of sampled triplets debug_data[4] = num_smp; } }
Ref<Mesh> MeshReader::read(const String& name, const Path& path) { std::ifstream stream(path.name().c_str(), std::ios::in | std::ios::binary); if (stream.fail()) { logError("Failed to open mesh %s", name.c_str()); return nullptr; } String line; uint lineNumber = 0; std::vector<vec3> positions; std::vector<vec3> normals; std::vector<vec2> texcoords; std::vector<Triplet> triplets; std::vector<FaceGroup> groups; FaceGroup* group = nullptr; while (std::getline(stream, line)) { const char* text = line.c_str(); ++lineNumber; if (!interesting(&text)) continue; try { String command = parseName(&text); if (command == "g") { // Silently ignore group names } else if (command == "o") { // Silently ignore object names } else if (command == "s") { // Silently ignore smoothing } else if (command == "v") { vec3 vertex; vertex.x = parseFloat(&text); vertex.y = parseFloat(&text); vertex.z = parseFloat(&text); positions.push_back(vertex); } else if (command == "vt") { vec2 texcoord; texcoord.x = parseFloat(&text); texcoord.y = parseFloat(&text); texcoords.push_back(texcoord); } else if (command == "vn") { vec3 normal; normal.x = parseFloat(&text); normal.y = parseFloat(&text); normal.z = parseFloat(&text); normals.push_back(normalize(normal)); } else if (command == "usemtl") { String materialName = parseName(&text); group = nullptr; for (auto& g : groups) { if (g.name == materialName) group = &g; } if (!group) { groups.push_back(FaceGroup()); groups.back().name = materialName; group = &(groups.back()); } } else if (command == "mtllib") { // Silently ignore .mtl material files } else if (command == "f") { if (!group) throw Exception("Expected \'usemtl\' before \'f\'"); triplets.clear(); while (*text != '\0') { triplets.push_back(Triplet()); Triplet& triplet = triplets.back(); triplet.vertex = parseInteger(&text); triplet.texcoord = 0; triplet.normal = 0; if (*text == '/') { if (std::isdigit(*(++text))) triplet.texcoord = parseInteger(&text); if (*text == '/') { if (std::isdigit(*(++text))) triplet.normal = parseInteger(&text); } } while (std::isspace(*text)) text++; } for (size_t i = 2; i < triplets.size(); i++) { group->faces.push_back(Face()); Face& face = group->faces.back(); face.p[0] = triplets[0]; face.p[1] = triplets[i - 1]; face.p[2] = triplets[i]; } } else { logWarning("Unknown command %s in mesh %s line %d", command.c_str(), name.c_str(), lineNumber); } } catch (Exception& e) { logError("%s in mesh %s line %d", e.what(), name.c_str(), lineNumber); return nullptr; } } Ref<Mesh> mesh = new Mesh(ResourceInfo(cache, name, path)); mesh->vertices.resize(positions.size()); for (size_t i = 0; i < positions.size(); i++) mesh->vertices[i].position = positions[i]; VertexTool tool(mesh->vertices); for (auto& g : groups) { mesh->sections.push_back(MeshSection()); MeshSection& geometry = mesh->sections.back(); const FaceList& faces = g.faces; geometry.materialName = g.name; geometry.triangles.resize(faces.size()); for (size_t i = 0; i < faces.size(); i++) { const Face& face = faces[i]; MeshTriangle& triangle = geometry.triangles[i]; for (size_t j = 0; j < 3; j++) { const Triplet& point = face.p[j]; vec3 normal; if (point.normal) normal = normals[point.normal - 1]; vec2 texcoord; if (point.texcoord) texcoord = texcoords[point.texcoord - 1]; triangle.indices[j] = tool.addAttributeLayer(point.vertex - 1, normal, texcoord); } } } tool.realizeVertices(mesh->vertices); return mesh; }
Game::Game(const char * filename) { std::ifstream infile(filename); if (!infile.is_open()) std::cout << "File not found" << std::endl; std::string line; std::vector<int>::iterator tableIt; bool colorsPlease = false; bool rulesPlease = false; bool ok = false; int cpt = 0; // count the number of color or the number of rules while(std::getline(infile, line)) { // comments and new lines if (line[0] == '\n') continue; if (line[0] == '#') continue; // create the game if(!colorsPlease && !rulesPlease) { if(sscanf(line.c_str(), "size %d", &m_size) == 1) { map.resize(m_size, m_size, 1, 3); map.fill(255); } if(sscanf(line.c_str(), "nbstates %d", &m_stateCard) == 1) { m_automate = new Triplet*[m_stateCard]; } if(sscanf(line.c_str(), "nbcolors %d", &m_colorCard) == 1) { for(int i = 0; i < m_stateCard; ++i) m_automate[i] = new Triplet[m_colorCard]; m_color = new uchar*[m_colorCard]; colorsPlease = true; } } else if(colorsPlease) { int r,g,b; if(sscanf(line.c_str(), "%d %d %d", &r, &g, &b) == 3) { m_color[cpt]= new uchar[3]; m_color[cpt][0] = r; m_color[cpt][1] = g; m_color[cpt][2] = b; cpt++; } if( cpt >= m_colorCard) { colorsPlease = false; rulesPlease = true; cpt = 0; } } else if(rulesPlease) { int color, turn, state; if(sscanf(line.c_str(), "%d %d %d", &color, &turn, &state) == 3) { int i = cpt / m_stateCard; int j = cpt - i * m_stateCard ; m_automate[i][j] = Triplet(color, turn, state); cpt++; } if( cpt >= m_colorCard*m_stateCard) { colorsPlease = false; rulesPlease = false; ok = true; break; } } } if(!ok) std::cout << "your config file is corrupted" << std::endl; }
void GeodesicInHeat::initialization() { int n = mesh.n_vertices(); int f = mesh.n_faces(); int count = 0; Laplacian.resize(n, n); LaplacianDirichlet.resize(n, n); Grad_x.resize(f, n); Grad_y.resize(f, n); Grad_z.resize(f, n); Div_x.resize(n, f); Div_y.resize(n, f); Div_z.resize(n, f); AreaMatrix.resize(n, n); std::vector<Triplet> Laplist; std::vector<Triplet> LapDList; std::vector<Triplet> Arealist; std::vector<Triplet> Grad_x_list; std::vector<Triplet> Grad_y_list; std::vector<Triplet> Grad_z_list; std::vector<Triplet> Div_x_list; std::vector<Triplet> Div_y_list; std::vector<Triplet> Div_z_list; /* v_k (cot_theta_1) /\ div_edge_2 / \ <----triangle /____\ v_i v_j (cot_theta_2) grad_edge div_edge_1 */ Vertex v_j, v_k, v_alpha, v_beta; Halfedge alpha_edge, beta_edge; Face triangle; Point p_i, p_j, p_k, p_alpha, face_normal, grad_edge, grad_cross, div_edge_1, div_edge_2, cot_edge_1, cot_edge_2, grad_ele; Scalar cot_alpha, cot_beta, cot_theta_1, cot_theta_2, div_sum, tri_area,cots,epsilon=1e-10; for (auto const& v_i : mesh.vertices()) { Scalar Area = 0.0; Scalar CotSum = 0.0; for (auto const& edge : mesh.halfedges(v_i)) { Halfedge edge_oppo = mesh.opposite_halfedge(edge); v_j = mesh.to_vertex(edge); avglength += (mesh.position(v_j) - mesh.position(v_i)).norm(); ++count; if (mesh.face(edge_oppo).is_valid()) alpha_edge = mesh.next_halfedge(mesh.opposite_halfedge(edge)); else alpha_edge = mesh.next_halfedge(edge); if (mesh.face(edge).is_valid()) beta_edge = mesh.next_halfedge(edge); else beta_edge = mesh.next_halfedge(mesh.opposite_halfedge(edge)); // v_beta = v_k v_k = mesh.to_vertex(beta_edge); v_alpha = mesh.to_vertex(alpha_edge); p_i = mesh.position(v_i); p_j = mesh.position(v_j); p_k = mesh.position(v_k); p_alpha = mesh.position(v_alpha); //laplacian operator //compute cot alpha and cot beta and add to the list //beta cot_edge_1 = (p_i - p_k); cot_edge_2 = (p_j - p_k); cot_beta = cot_edge_1.dot(cot_edge_2) / cot_edge_1.cross(cot_edge_2).norm(); //alpha cot_edge_1 = (p_i - p_alpha); cot_edge_2 = (p_j - p_alpha); cot_alpha = cot_edge_1.dot(cot_edge_2) / cot_edge_1.cross(cot_edge_2).norm(); if (!mesh.face(edge).is_valid()) cot_beta = 0; if (!mesh.face(edge_oppo).is_valid()) cot_alpha = 0; cots = cot_beta + cot_alpha + epsilon; //Dirichlet condition, if v_j is boundary, then set it zero, do not push in the Matrix. if (!mesh.is_boundary(v_j)) LapDList.push_back(Triplet(v_i.idx(), v_j.idx(), 0.5*cots)); Laplist.push_back(Triplet(v_i.idx(), v_j.idx(), 0.5*cots)); CotSum += 0.5*cots; //Divergence operator if (mesh.face(edge).is_valid()) { triangle = mesh.face(edge); div_edge_1 = p_j - p_i; div_edge_2 = p_k - p_i; tri_area = 0.5*(div_edge_1.cross(div_edge_2)).norm(); Area += (1 / 3.0f)*tri_area; face_normal = (div_edge_1.cross(div_edge_2)).normalized(); //compute cot theta1 cot_edge_1 = (p_j - p_k); cot_edge_2 = (p_i - p_k); cot_theta_1 = cot_edge_1.dot(cot_edge_2) / cot_edge_1.cross(cot_edge_2).norm(); //compute cot theta2 cot_edge_1 = (p_k - p_j); cot_edge_2 = (p_i - p_j); cot_theta_2 = cot_edge_1.dot(cot_edge_2) / cot_edge_1.cross(cot_edge_2).norm(); //add to x ,y ,z list respectively div_sum = cot_theta_1*div_edge_1(0) + cot_theta_2*div_edge_2(0); Div_x_list.push_back(Triplet(v_i.idx(), triangle.idx(), (0.5*div_sum))); div_sum = cot_theta_1*div_edge_1(1) + cot_theta_2*div_edge_2(1); Div_y_list.push_back(Triplet(v_i.idx(), triangle.idx(), (0.5*div_sum))); div_sum = cot_theta_1*div_edge_1(2) + cot_theta_2*div_edge_2(2); Div_z_list.push_back(Triplet(v_i.idx(), triangle.idx(), (0.5*div_sum))); //construct Gradient operator on triangles in x , y ,z separatly grad_edge = p_j - p_i; grad_cross = face_normal.cross(grad_edge); grad_ele = (1 / (2 * tri_area))*grad_cross; Grad_x_list.push_back(Triplet(triangle.idx(), v_k.idx(), grad_ele(0))); Grad_y_list.push_back(Triplet(triangle.idx(), v_k.idx(), grad_ele(1))); Grad_z_list.push_back(Triplet(triangle.idx(), v_k.idx(), grad_ele(2))); } } if (!mesh.is_boundary(v_i)) LapDList.push_back(Triplet(v_i.idx(), v_i.idx(), -CotSum)); Arealist.push_back(Triplet(v_i.idx(), v_i.idx(), Area)); Laplist.push_back(Triplet(v_i.idx(), v_i.idx(),-CotSum)); } AreaMatrix.setFromTriplets(Arealist.begin(), Arealist.end()); LaplacianDirichlet.setFromTriplets(LapDList.begin(), LapDList.end()); Laplacian.setFromTriplets(Laplist.begin(), Laplist.end()); Grad_x.setFromTriplets(Grad_x_list.begin(), Grad_x_list.end()); Grad_y.setFromTriplets(Grad_y_list.begin(), Grad_y_list.end()); Grad_z.setFromTriplets(Grad_z_list.begin(), Grad_z_list.end()); Div_x.setFromTriplets(Div_x_list.begin(), Div_x_list.end()); Div_y.setFromTriplets(Div_y_list.begin(), Div_y_list.end()); Div_z.setFromTriplets(Div_z_list.begin(), Div_z_list.end()); avglength /=float(count); initialized = true; }