void faction_setorigin(faction * f, int id, int x, int y) { origin **urp; assert(f != NULL); for (urp = &f->origin; *urp; urp = &(*urp)->next) { origin *ur = *urp; if (ur->id == id) { ur->x += x; ur->y += y; return; } } *urp = new_origin(id, x, y); }
std::vector< ValuesSimplex<T> > ValuesSimplex<T>::cross_product(const ValuesSimplex<T>& s) const { if (s.domain_dim == 2) { if (domain_dim == 2) { transformation<T> trafos[6] = { { { { 0, 1 }, { 1, 1 } }, { { 1, -1, 0, -1 }, { 1, 0, 0, 1 } }, { { 0, 1 }, { 0, 0 } } }, { { { 1, 1 }, { 0, 1 } }, { { 1, 0, 0, 1 }, { 1, -1, 0, -1 } }, { { 0, 0 }, { 0, 1 } } }, { { { 1, 1 }, { 0, 1 } }, { { -1, 0, -1, 1 }, { -1, 1, -1, 0 } }, { { 1, 0 }, { 1, 0 } } }, { { { 0, 1 }, { 1, 1 } }, { { -1, 1, -1, 0 }, { -1, 0, -1, 1 } }, { { 1, 0 }, { 1, 0 } } }, { { { 0, 1 }, { 1, 1 } }, { { 0, 1, 1, 0 }, { 0, -1, 1, -1 } }, { { 0, 0 }, { 0, 1 } } }, { { { 1, 1 }, { 0, 1 } }, { { 0, -1, 1, -1 }, { 0, 1, 1, 0 } }, { { 0, 1 }, { 0, 0 } } } }; std::vector< ValuesSimplex<T> > result; result.reserve(6); std::vector<T> new_matrix((value_dim + s.value_dim) * (domain_dim + s.domain_dim)); std::vector<T> new_origin( value_dim + s.value_dim ); for (int i = 0; i < 6; ++i) { Blas<T>::gemm('N', 'N', value_dim, domain_dim, domain_dim, trafos[i].factors[0][0], &matrix[0], value_dim, &trafos[i].matrix[0][0], domain_dim, 0, &new_matrix[0], value_dim + s.value_dim); Blas<T>::gemm('N', 'N', value_dim, domain_dim, domain_dim, trafos[i].factors[0][1], &matrix[0], value_dim, &trafos[i].matrix[0][0], domain_dim, 0, &new_matrix[(value_dim + s.value_dim)*domain_dim], value_dim + s.value_dim); Blas<T>::gemm('N', 'N', s.value_dim, domain_dim, domain_dim, trafos[i].factors[1][0], &s.matrix[0], s.value_dim, &trafos[i].matrix[1][0], domain_dim, 0, &new_matrix[value_dim], value_dim + s.value_dim); Blas<T>::gemm('N', 'N', s.value_dim, domain_dim, domain_dim, trafos[i].factors[1][1], &s.matrix[0], s.value_dim, &trafos[i].matrix[1][0], domain_dim, 0, &new_matrix[(value_dim + s.value_dim)*domain_dim + value_dim], value_dim + s.value_dim); Blas<T>::copy(value_dim, &origin[0], 1, &new_origin[0], 1); Blas<T>::copy(s.value_dim, &s.origin[0], 1, &new_origin[value_dim], 1); Blas<T>::gemv('N', value_dim, domain_dim, 1, &matrix[0], value_dim, &trafos[i].origin[0][0], 1, 1, &new_origin[0], 1); Blas<T>::gemv('N', s.value_dim, domain_dim, 1, &s.matrix[0], s.value_dim, &trafos[i].origin[1][0], 1, 1, &new_origin[value_dim], 1); // std::vector<const typename Mesh<T>::Simplex*> new_original_simplices; // new_original_simplices.reserve(original_simplices.size() + s.original_simplices.size()); // new_original_simplices.assign(original_simplices.begin(), original_simplices.end()); // new_original_simplices.insert(new_original_simplices.end(), s.original_simplices.begin(), s.original_simplices.end()); result.push_back(ValuesSimplex<T>(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, /*new_original_simplices,*/ - factor * s.factor)); } return result; } else if (domain_dim == 1) { return s.cross_product(*this); } } else if (s.domain_dim == 1) { if (domain_dim == 2) { std::vector< ValuesSimplex<T> > result; result.reserve(3); std::vector<T> new_origin(value_dim + s.value_dim); Blas<T>::copy(value_dim, &origin[0], 1, &new_origin[0], 1); Blas<T>::copy(s.value_dim, &s.origin[0], 1, &new_origin[value_dim], 1); std::vector<T> new_matrix((value_dim + s.value_dim) * 3); Blas<T>::copy(value_dim, &matrix[0], 1, &new_matrix[0], 1); Blas<T>::copy(value_dim, &matrix[value_dim], 1, &new_matrix[value_dim + s.value_dim], 1); Blas<T>::copy(s.value_dim, &s.matrix[0], 1, &new_matrix[2 * (value_dim + s.value_dim) + value_dim], 1); result.push_back(ValuesSimplex(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, factor * s.factor)); Blas<T>::axpy(s.value_dim, 1, &s.matrix[0], 1, &new_origin[value_dim], 1); Blas<T>::copy(value_dim, &matrix[value_dim], 1, &new_matrix[2 * (value_dim + s.value_dim)], 1); Blas<T>::scal(s.value_dim, -1, &new_matrix[2 * (value_dim + s.value_dim) + value_dim], 1); result.push_back(ValuesSimplex(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, - factor * s.factor)); Blas<T>::copy(value_dim, &matrix[0], 1, &new_matrix[2 * (value_dim + s.value_dim)], 1); Blas<T>::axpy(s.value_dim, -1, &s.matrix[0], 1, &new_matrix[(value_dim + s.value_dim) + value_dim], 1); result.push_back(ValuesSimplex(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, - factor * s.factor)); return result; } else if (domain_dim == 1) { std::vector<T> new_origin(value_dim + s.value_dim); Blas<T>::copy(value_dim, &origin[0], 1, &new_origin[0], 1); Blas<T>::copy(s.value_dim, &s.origin[0], 1, &new_origin[value_dim], 1); std::vector<T> new_matrix((value_dim + s.value_dim) * 2); Blas<T>::copy(value_dim, &matrix[0], 1, &new_matrix[0], 1); Blas<T>::copy(value_dim, &matrix[0], 1, &new_matrix[value_dim + s.value_dim], 1); Blas<T>::copy(s.value_dim, &s.matrix[0], 1, &new_matrix[value_dim + s.value_dim + value_dim], 1); std::vector< ValuesSimplex<T> > result; result.reserve(2); result.push_back(ValuesSimplex(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, factor * s.factor)); Blas<T>::scal(value_dim, 0.0, &new_matrix[0], 1); Blas<T>::copy(s.value_dim, &s.matrix[0], 1, &new_matrix[value_dim], 1); result.push_back(ValuesSimplex(domain_dim + s.domain_dim, value_dim + s.value_dim, new_matrix, new_origin, - factor * s.factor)); return result; } } throw std::runtime_error("Cross product only implemented for dimensions up to two"); }