Esempio n. 1
0
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");
  }