Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Undefined reference error
Forum Updated to NodeBB v4.3 + New Features

Undefined reference error

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 422 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sheetkey
    wrote on last edited by
    #1

    I'm still new to both Qt and c++ so I apologize if I am missing something simple. I have found other threads relating to this topic and I have tried those solutions with no success.

    I'm creating a class that inherits qobject that will row reduce a matrix. I've tested the code that does this and it works when inside main.cpp. I have trouble getting it to work when I put the code into its own header and source files.

    The error I get is:
    main.cpp:22: error: undefined reference to `matclass::to_reduced_echelon_form(Eigen::Matrix<double, -1, -1, 0, -1, -1>&)'

    From what I've found this is likely a linking error with .o files but I'm not entirely sure how to fix that or if that is even an issue when using QtCreator. Thanks in advance for any advice!

    matclass.h

    #ifndef MATCLASS_H
    #define MATCLASS_H
    
    #include <QObject>
    #include <QObject>
    #include <Eigen>
    #include <algorithm>
    #include <cstddef>
    #include <cassert>
    
    class matclass : public QObject
    {
        Q_OBJECT
    public:
        explicit matclass(QObject *parent = nullptr);
    
        struct matrix_traits
        {
            typedef typename Eigen::MatrixXd::value_type value_type;
    
            static int min_row(Eigen::MatrixXd const& A);
            static int max_row(Eigen::MatrixXd const& A);
            static int min_column(Eigen::MatrixXd const& A);
            static int max_column(Eigen::MatrixXd const& A);
            static value_type& element(Eigen::MatrixXd& A, int i, int k);
            static value_type element(Eigen::MatrixXd const& A, int i, int k);
        };
        void swap_rows(Eigen::MatrixXd& A, int i, int k);
        void divide_row(Eigen::MatrixXd& A, int i, typename matrix_traits::value_type v);
        void add_multiple_row(Eigen::MatrixXd& A, int i, int k, typename matrix_traits::value_type v);
        void to_reduced_echelon_form(Eigen::MatrixXd& A);
    
    signals:
    
    };
    
    #endif // MATCLASS_H
    

    matclass.cpp

    #include "matclass.h"
    
    matclass::matclass(QObject *parent) : QObject(parent)
    {
    
    }
    
    struct matrix_traits
    {
        typedef typename Eigen::MatrixXd::value_type value_type;
    
        static int min_row(Eigen::MatrixXd const& A)
        {
            return A.rows() - A.rows();
        }
        static int max_row(Eigen::MatrixXd const& A)
        {
            return A.rows() - 1;
        }
        static int min_column(Eigen::MatrixXd const& A)
        {
            return A.cols() - A.cols();
        }
        static int max_column(Eigen::MatrixXd const& A)
        {
            return A.cols() - 1;
        }
        static value_type& element(Eigen::MatrixXd& A, int i, int k)
        {
            return A(i, k);
        }
        static value_type element(Eigen::MatrixXd const& A, int i, int k)
        {
            return A(i, k);
        }
    };
    
    void swap_rows(Eigen::MatrixXd& A, int i, int k)
    {
        matrix_traits mt;
    
        assert(mt.min_row(A) <= i);
        assert(i <= mt.max_row(A));
    
        assert(mt.min_row(A) <= k);
        assert(k <= mt.max_row(A));
    
        for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
        {
            std::swap(mt.element(A, i, col), mt.element(A, k, col));
        }
    }
    
    void divide_row(Eigen::MatrixXd& A, int i, typename matrix_traits::value_type v)
    {
        matrix_traits mt;
    
        assert(mt.min_row(A) <= i);
        assert(i <= mt.max_row(A));
    
        assert(v != 0);
    
        for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
        {
            mt.element(A, i, col) /= v;
        }
    }
    
    void add_multiple_row(Eigen::MatrixXd& A, int i, int k, typename matrix_traits::value_type v)
    {
        matrix_traits mt;
    
        assert(mt.min_row(A) <= i);
        assert(i <= mt.max_row(A));
    
        assert(mt.min_column(A) <= k);
        assert(k <= mt.max_row(A));
    
        for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
        {
            mt.element(A, i, col) += v * mt.element(A, k, col);
        }
    }
    
    void to_reduced_echelon_form(Eigen::MatrixXd& A)
    {
        matrix_traits mt;
    
        int lead = mt.min_row(A);
    
        for(int row = mt.min_row(A); row <= mt.max_row(A); ++row)
        {
            if(lead > mt.max_column(A))
            {
                return;
            }
            int i = row;
            while (mt.element(A, i, lead) == 0)
            {
                ++i;
                if(i > mt.max_row(A))
                {
                    i = row;
                    ++lead;
                    if(lead > mt.max_column(A))
                    {
                        return;
                    }
                }
            }
            swap_rows(A, i, row);
            divide_row(A, row, mt.element(A, row, lead));
            for(i = mt.min_row(A); i <= mt.max_row(A); ++i)
            {
                if(i != row)
                {
                    add_multiple_row(A, i, row, -mt.element(A, i, lead));
                }
            }
        }
    }
    

    mian.cpp

    #include <QCoreApplication>
    #include <QDebug>
    
    #include "matclass.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    /*
        Eigen::Matrix<double, 2, 2> M;
        M(0, 0) = 1;
        M(0, 1) = 2;
        M(1, 0) = 3;
        M(1, 1) = 4;
    */
        Eigen::MatrixXd Mat;
        Mat.resize(2, 2);
        Mat << 1, 2, 3, 4;
    
        matclass Matrix;
    
        Matrix.to_reduced_echelon_form(Mat);
    
        for(int i = 0; i < 2; i++)
        {
            for(int j = 0; j < 2; j++)
            {
                qDebug() << Mat(i, j) << " ";
            }
            qDebug() << "\n";
        }
    
        return a.exec();
    }
    

    .pro file

    QT -= gui
    
    INCLUDEPATH += C:\sdks\eigen3.3.8\eigen-3.3.8\Eigen
    
    CONFIG += c++11 console
    CONFIG -= app_bundle
    
    # You can make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
            main.cpp \
            matclass.cpp
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    HEADERS += \
        matclass.h
    
    JonBJ 1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      @sheetkey said in Undefined reference error:

      to_reduced_echelon_form

      I don't see an implemented function in the class matclass, only a free function.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      S 1 Reply Last reply
      2
      • S sheetkey

        I'm still new to both Qt and c++ so I apologize if I am missing something simple. I have found other threads relating to this topic and I have tried those solutions with no success.

        I'm creating a class that inherits qobject that will row reduce a matrix. I've tested the code that does this and it works when inside main.cpp. I have trouble getting it to work when I put the code into its own header and source files.

        The error I get is:
        main.cpp:22: error: undefined reference to `matclass::to_reduced_echelon_form(Eigen::Matrix<double, -1, -1, 0, -1, -1>&)'

        From what I've found this is likely a linking error with .o files but I'm not entirely sure how to fix that or if that is even an issue when using QtCreator. Thanks in advance for any advice!

        matclass.h

        #ifndef MATCLASS_H
        #define MATCLASS_H
        
        #include <QObject>
        #include <QObject>
        #include <Eigen>
        #include <algorithm>
        #include <cstddef>
        #include <cassert>
        
        class matclass : public QObject
        {
            Q_OBJECT
        public:
            explicit matclass(QObject *parent = nullptr);
        
            struct matrix_traits
            {
                typedef typename Eigen::MatrixXd::value_type value_type;
        
                static int min_row(Eigen::MatrixXd const& A);
                static int max_row(Eigen::MatrixXd const& A);
                static int min_column(Eigen::MatrixXd const& A);
                static int max_column(Eigen::MatrixXd const& A);
                static value_type& element(Eigen::MatrixXd& A, int i, int k);
                static value_type element(Eigen::MatrixXd const& A, int i, int k);
            };
            void swap_rows(Eigen::MatrixXd& A, int i, int k);
            void divide_row(Eigen::MatrixXd& A, int i, typename matrix_traits::value_type v);
            void add_multiple_row(Eigen::MatrixXd& A, int i, int k, typename matrix_traits::value_type v);
            void to_reduced_echelon_form(Eigen::MatrixXd& A);
        
        signals:
        
        };
        
        #endif // MATCLASS_H
        

        matclass.cpp

        #include "matclass.h"
        
        matclass::matclass(QObject *parent) : QObject(parent)
        {
        
        }
        
        struct matrix_traits
        {
            typedef typename Eigen::MatrixXd::value_type value_type;
        
            static int min_row(Eigen::MatrixXd const& A)
            {
                return A.rows() - A.rows();
            }
            static int max_row(Eigen::MatrixXd const& A)
            {
                return A.rows() - 1;
            }
            static int min_column(Eigen::MatrixXd const& A)
            {
                return A.cols() - A.cols();
            }
            static int max_column(Eigen::MatrixXd const& A)
            {
                return A.cols() - 1;
            }
            static value_type& element(Eigen::MatrixXd& A, int i, int k)
            {
                return A(i, k);
            }
            static value_type element(Eigen::MatrixXd const& A, int i, int k)
            {
                return A(i, k);
            }
        };
        
        void swap_rows(Eigen::MatrixXd& A, int i, int k)
        {
            matrix_traits mt;
        
            assert(mt.min_row(A) <= i);
            assert(i <= mt.max_row(A));
        
            assert(mt.min_row(A) <= k);
            assert(k <= mt.max_row(A));
        
            for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
            {
                std::swap(mt.element(A, i, col), mt.element(A, k, col));
            }
        }
        
        void divide_row(Eigen::MatrixXd& A, int i, typename matrix_traits::value_type v)
        {
            matrix_traits mt;
        
            assert(mt.min_row(A) <= i);
            assert(i <= mt.max_row(A));
        
            assert(v != 0);
        
            for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
            {
                mt.element(A, i, col) /= v;
            }
        }
        
        void add_multiple_row(Eigen::MatrixXd& A, int i, int k, typename matrix_traits::value_type v)
        {
            matrix_traits mt;
        
            assert(mt.min_row(A) <= i);
            assert(i <= mt.max_row(A));
        
            assert(mt.min_column(A) <= k);
            assert(k <= mt.max_row(A));
        
            for(int col = mt.min_column(A); col <= mt.max_column(A); ++col)
            {
                mt.element(A, i, col) += v * mt.element(A, k, col);
            }
        }
        
        void to_reduced_echelon_form(Eigen::MatrixXd& A)
        {
            matrix_traits mt;
        
            int lead = mt.min_row(A);
        
            for(int row = mt.min_row(A); row <= mt.max_row(A); ++row)
            {
                if(lead > mt.max_column(A))
                {
                    return;
                }
                int i = row;
                while (mt.element(A, i, lead) == 0)
                {
                    ++i;
                    if(i > mt.max_row(A))
                    {
                        i = row;
                        ++lead;
                        if(lead > mt.max_column(A))
                        {
                            return;
                        }
                    }
                }
                swap_rows(A, i, row);
                divide_row(A, row, mt.element(A, row, lead));
                for(i = mt.min_row(A); i <= mt.max_row(A); ++i)
                {
                    if(i != row)
                    {
                        add_multiple_row(A, i, row, -mt.element(A, i, lead));
                    }
                }
            }
        }
        

        mian.cpp

        #include <QCoreApplication>
        #include <QDebug>
        
        #include "matclass.h"
        
        int main(int argc, char *argv[])
        {
            QCoreApplication a(argc, argv);
        /*
            Eigen::Matrix<double, 2, 2> M;
            M(0, 0) = 1;
            M(0, 1) = 2;
            M(1, 0) = 3;
            M(1, 1) = 4;
        */
            Eigen::MatrixXd Mat;
            Mat.resize(2, 2);
            Mat << 1, 2, 3, 4;
        
            matclass Matrix;
        
            Matrix.to_reduced_echelon_form(Mat);
        
            for(int i = 0; i < 2; i++)
            {
                for(int j = 0; j < 2; j++)
                {
                    qDebug() << Mat(i, j) << " ";
                }
                qDebug() << "\n";
            }
        
            return a.exec();
        }
        

        .pro file

        QT -= gui
        
        INCLUDEPATH += C:\sdks\eigen3.3.8\eigen-3.3.8\Eigen
        
        CONFIG += c++11 console
        CONFIG -= app_bundle
        
        # You can make your code fail to compile if it uses deprecated APIs.
        # In order to do so, uncomment the following line.
        #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
        
        SOURCES += \
                main.cpp \
                matclass.cpp
        
        # Default rules for deployment.
        qnx: target.path = /tmp/$${TARGET}/bin
        else: unix:!android: target.path = /opt/$${TARGET}/bin
        !isEmpty(target.path): INSTALLS += target
        
        HEADERS += \
            matclass.h
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @sheetkey
        Not only as per @Christian-Ehrlicher has observed, but it seems all your methods in the class (swap_rows() onward) are not implemented in the class. Your error on to_reduced_echelon_form() is only because that happens to be one you call.

        1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          @sheetkey said in Undefined reference error:

          to_reduced_echelon_form

          I don't see an implemented function in the class matclass, only a free function.

          S Offline
          S Offline
          sheetkey
          wrote on last edited by sheetkey
          #4

          @Christian-Ehrlicher @JonB Thank you very much! I've managed to sort it out now.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved