mardi 15 juin 2021

Error of undefined reference to X when creating custom matrix class with templated vectors [duplicate]

So, I'm trying to build a matrix class which functions with arbitrary vectors. One such vector would be a standard std::vector while another would be an abstract vector of elements (some form of simd thing) which is treated as a vector too

So, instances of my matrices might be of type

MyMatrix<std::vector<std::double<complex>>>
MyMatrix<std::vector<SimdVector>>

My header file, EMatrix.h


#include <string>
#include <vector>
#include <iostream>
#include <random>

using cdVec = std::vector<std::complex<double>>;
using eVec = std::vector<std::complex<double>>;  // for example


template<typename VType>  // encrypted vector or vector<int> or vector<float> or vector<complex>
class EMatrix {
 public:

  EMatrix<VType>(int m, int n, std::string packing, bool repeated) :
      m_m(m), m_n(n), m_packing(packing), m_isRepeated(repeated) {};


  static EMatrix<VType> createInstance(int m, int n, bool init, std::string packing, bool repeated) {
      auto newMatrix = EMatrix<VType>(m, n, packing, repeated);
      if (!init) {
          return newMatrix;
      }
      if (packing.compare("vertical") == 0) {
          newMatrix.m_cols = std::vector<VType>(n);
          return newMatrix;
      } else {
          newMatrix.m_rows = std::vector<VType>(m);
          return newMatrix;
      }
  }
 
  static EMatrix<cdVec> makeRandomNormal(
      int m,
      int n,
      string packing = "vertical",
      bool repeated = false,
      float mean = 0.0,
      float stddev = 1.0);


 private:
  int m_m = 0;
  int m_n = 0;
  std::string m_packing = "vertical";
  bool m_isRepeated = false;
  bool m_isEncrypted = false;
  std::vector<VType> m_cols;
  std::vector<VType> m_rows;

};

notice how in the last 2 private attrs, our m_cols and m_rows are of type std::vector so they should be flexible and work as in the two examples above.

My implementation file, EMatrix.cpp


template<typename VType>
EMatrix<cdVec> EMatrix<VType>::makeRandomNormal(int m, int n, string packing, bool repeated, float mean, float stddev) {

    auto em = EMatrix<cdVec>(m, n, std::move(packing), repeated);

    std::default_random_engine generator;
    std::normal_distribution<double> distribution(mean, stddev);
    auto mContainer = std::vector<cdVec>();
    if (em.m_packing.compare("horizontal") == 0) {
        for (int vecI = 0; vecI <= m; vecI++) {
            auto vContainer = cdVec();
            for (int sI = 0; sI <= n; sI++) {
                vContainer.emplace_back(std::complex<double>(distribution(generator)));
            }
            mContainer.emplace_back(vContainer);
        }
        em.m_rows = mContainer;
        return em;
    }
    for (int vecI = 0; vecI <= n; vecI++) {
        auto vContainer = cdVec();
        for (int sI = 0; sI <= m; sI++) {
            vContainer.emplace_back(std::complex<double>(distribution(generator)));
        }
        mContainer.emplace_back(vContainer);
    }
    em.m_cols = mContainer;
    return em;

}

Note that we want to output a complex double from the makeRandomNormal call which is why I specified the return type as such (this is correct, yes?)

when running my main.cpp,

#include "include/EMatrix.h"
#include <cstdio>
#include <iostream>

int main() {
    std::cout << "Hello there!" << std::endl;
    EMatrix<cdVec> a = EMatrix<cdVec>::createInstance(5, 10, true, "vertical", true);
    auto b = EMatrix<cdVec>::makeRandomNormal(5, 5 );

}

I run into undefined reference to EMatrix<std::vector<std::complex<double>, std::allocator<std::complex<double> > > >::makeRandomNormal(int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, float, float)'

I'm not sure how the issue is coming about. I take it that the function signature is wrong? I'm not sure how it is getting EMatrix<std::vector<std::complex<double>, std::allocator<std::complex<double> > > > from what I put in.

I tried to do a quick sanity check with the createInstance and that seemed to work fine

Aucun commentaire:

Enregistrer un commentaire