PDA

View Full Version : Want to run Octave m-file



Tottish
31st March 2010, 14:20
Hello!

I have an octave (MATLAB clone) script that I want to call from my Qt C++ code.
According to this wiki (http://wiki.octave.org/wiki.pl?CategoryExternal) it is quite possible to do.
Though I can't get it to work properly...

What I would like to start with is a simple GUI where I can enter a few variables that gets sent to the octave-script when I push a button, returns a few values and write them into textlables or something like that.

Or perhaps we should just get the example to work in it's terminal form first.
Here is what I have done:
1. Start a new Qt4 console project.
2. Created the example m-file from the link and put it in the project directory.
3. Opened main.cpp and kept the include QCoreApplication and changed the rest of the content for the one in the linked example above.
4. When I try to build I get the error " 'cout' is not a member of 'std' ".
5. I tried including iostream and it stopped complaining about cout (Why wasn't it there in the first place?) but it has two warnings: Unused parameters 'argc' and 'argv' and 25 blue question marks saying "undefined reference to..."
Does this mean that the include-files doesn't contain the definitions that the code is referring to?
The last line of the Build issues is an error and says "Id returned 1 exit status"

So, anyone up for giving a true Qt/C++ noob a little help?
btw. I'm on Ubuntu 9.10 and the latest Qt Creator.

Thank you.
Have a nice day!
/Tottish

norobro
31st March 2010, 17:20
I have Octave installed on my Debian machine although I've never used it. If you post your code I'll try to help.

I did notice that there is a package named "qtoctave" in the Debian repositories. If that is not what you are looking for you could download the source code and maybe get some ideas about what to do.

Tottish
31st March 2010, 17:42
Hi!
Thanks for responding!

Qtoctave is just a GUI for octave. If I was a decent C++-programmer I'm sure the sourcecode could be very useful. However, I'm not so I'll try it this way instead since I have what seems to be a complete example here.
My sourcecode is just copied and pasted from the link to the wiki. With the few exceptions mentioned in the post above.

Cheers!
/Tottish

EDIT:
Here is the code:


#include <QtCore/QCoreApplication>
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h> /* do_octave_atexit */

int main (const int argc, char ** argv)
{
const char * argvv [] = {"" /* name of program, not relevant */, "--silent"};

octave_main (2, (char **) argvv, true /* embedded */);

octave_value_list functionArguments;

functionArguments (0) = 2;
functionArguments (1) = "D. Humble";

Matrix inMatrix (2, 3);

inMatrix (0, 0) = 10;
inMatrix (0, 1) = 9;
inMatrix (0, 2) = 8;
inMatrix (1, 0) = 7;
inMatrix (1, 1) = 6;

functionArguments (2) = inMatrix;

const octave_value_list result = feval ("exampleOctaveFunction", functionArguments, 1);

std::cout << "resultScalar is " << result (0).scalar_value () << std::endl;
std::cout << "resultString is " << result (1).string_value () << std::endl;
std::cout << "resultMatrix is\n" << result (2).matrix_value ();

do_octave_atexit ();

}


EDIT2:
Hmmm if I add the line
QCoreApplication a(argc, argv);
First thing in the body then build issues are restricted to QcoreApplication.. Am I on to something?...

pherthyl
31st March 2010, 19:24
Couple things:
You are currently not actually writing a Qt program, since as you've noticed you don't have a QApplication. Create one first (QApplication app(argc, argv);)

The warnings you can ignore.
The errors about undefined references.... Might be that you have to include the lib. Do the octave docs say anything about that? Where are those warnings?

pherthyl
31st March 2010, 19:30
Also, the octave docs show the makefile necessary to build that example. In QtCreator, you need to add the relevant parts to your project file. Most importantly the include and lib dirs. I would try adding something like this to your .pro file (at the end) and then try doing a clean and rebuild.

INCLUDEPATH += /usr/include/octave-3.0.1/ # MAKE SURE THIS PATH EXISTS or change it to your system.
LIBS += -L"/usr/lib/octave-3.0.1/" -loctinterp

Make sure those paths exist.

Tottish
31st March 2010, 21:03
OK, thanks a lot for those pointers pherthyl!
I will look into it first thing tomorrow. Right now my tired brain needs some sleep.
Much appreciated!

/Ttotish

Tottish
1st April 2010, 08:54
OK, my new .PRO file:


#-------------------------------------------------
#
# Project created by QtCreator 2010-03-31T15:03:01
#
#-------------------------------------------------

QT -= gui

TARGET = test2
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app


SOURCES += main.cpp

INCLUDEPATH += /usr/include/octave-3.2.2/
LIBS += -L"/usr/lib/octave-3.2.2/" -loctinterp



The new code: (Not sure if the last line should be there but I guess something should be returned?)


#include <QtCore/QCoreApplication>
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h> /* do_octave_atexit */

int main (int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const char * argvv [] = {"" /* name of program, not relevant */, "--silent"};

octave_main (2, (char **) argvv, true /* embedded */);

octave_value_list functionArguments;

functionArguments (0) = 2;
functionArguments (1) = "D. Humble";

Matrix inMatrix (2, 3);

inMatrix (0, 0) = 10;
inMatrix (0, 1) = 9;
inMatrix (0, 2) = 8;
inMatrix (1, 0) = 7;
inMatrix (1, 1) = 6;

functionArguments (2) = inMatrix;

const octave_value_list result = feval ("exampleOctaveFunction", functionArguments, 1);

std::cout << "resultScalar is " << result (0).scalar_value () << std::endl;
std::cout << "resultString is " << result (1).string_value () << std::endl;
std::cout << "resultMatrix is\n" << result (2).matrix_value ();

do_octave_atexit ();
return a.exec();
}



Here is the compiler output: (After a clean and attempt to build)


Running build steps for project test2...
Configuration unchanged, skipping QMake step.
Starting: /usr/bin/make -w
make: Entering directory `/home/snurr/octaveTest/qttest/Qt-call-m/test2'
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_CORE_LIB -DQT_SHARED -I../../../../qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I../../../../qtsdk-2010.02/qt/include/QtCore -I../../../../qtsdk-2010.02/qt/include -I/usr/include/octave-3.2.2 -I. -o main.o main.cpp
g++ -Wl,-rpath,/home/snurr/qtsdk-2010.02/qt/lib -o test2 main.o -L/home/snurr/qtsdk-2010.02/qt/lib -L/usr/lib/octave-3.2.2/ -loctinterp -lQtCore -L/home/snurr/qtsdk-2010.02/qt/lib -lpthread
/usr/bin/ld: warning: liboctave.so, needed by /usr/lib/octave-3.2.2//liboctinterp.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libcruft.so, needed by /usr/lib/octave-3.2.2//liboctinterp.so, not found (try using -rpath or -rpath-link)
main.o: In function `main':
/home/snurr/octaveTest/qttest/Qt-call-m/test2/main.cpp:28: undefined reference to `MatrixType::MatrixType()'
/home/snurr/octaveTest/qttest/Qt-call-m/test2/main.cpp:28: undefined reference to `MatrixType::~MatrixType()'
/home/snurr/octaveTest/qttest/Qt-call-m/test2/main.cpp:28: undefined reference to `MatrixType::~MatrixType()'
......
LOTS OF errors about undefined references here. My guess is because it cant find the .so-files?
.......
/usr/lib/octave-3.2.2//liboctinterp.so: undefined reference to `operator*(DiagMatrix const&, ComplexDiagMatrix const&)'
/usr/lib/octave-3.2.2//liboctinterp.so: undefined reference to `mx_el_ge(octave_int<unsigned int> const&, intNDArray<octave_int<long long> > const&)'
/usr/lib/octave-3.2.2//liboctinterp.so: undefined reference to `MArrayN<octave_int<unsigned char> > quotient<octave_int<unsigned char> >(MArrayN<octave_int<unsigned char> > const&, MArrayN<octave_int<unsigned char> > const&)'
collect2: ld returned 1 exit status
make: *** [test2] Error 1
Exited with code 2.
Error while building project test2
When executing build step 'Make'


This part I don't understand:
/usr/bin/ld: warning: liboctave.so, needed by /usr/lib/octave-3.2.2//liboctinterp.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libcruft.so, needed by /usr/lib/octave-3.2.2//liboctinterp.so, not found (try using -rpath or -rpath-link)
The files are indeed located in the folders specified...??? (EDIT. Clarification: They are located in the same folder as liboctinterp.so... not in /usr/bin...)
Tried using -rpath and rpath-link aftre/instead of the - locinterp line but then g++ says "unrecognized option"

So what should I do now?
Thank you for your help! I really appreciate it!
/Tottish

norobro
1st April 2010, 15:36
I started out trying to run the octave example as a c++ file(i.e. no Qt) and received the same errors. The problem is you have to tell the linker where the libs are located. As root, run "ldconfig /path/to/octave/libs". This is not permanent because the next time ldconfig is run it will not find the octave libs.

To make sure the cache gets updated every time ldconfig is run (Ubuntu is a Debian derivative so I'm assuming the procedure is the same) do this:


sudo -i
cd /etc/ld.so.conf.d
touch octave.conf
vi (your fav. editor) octave.conf
add a line: /path/to/octavelibs
save file
run ldconfig


I got it to run as a Qt app also. The only difference was I used the QApplication class.

HTH

Tottish
1st April 2010, 17:11
That's great news norobro!

I can't really get it to work here though...
I run "ldconfig /usr/lib/octave-3.2.2" (after sudo) and only get a new prompt (the same response if I misspell) . nothing else happens and the same errors when compiling. Maybe there should be a -l or something in the command?


/Tottish

EDIT:
WoHoo!
Got it to work! I thought that the second thing you listed also had to be done for it to work. Thought it only applied after reboot, proves how new I am to this I guess! =)
Anyway, a HUGE thank you from me to you!!!

norobro
1st April 2010, 17:28
Hmm, I thought that would work.
No response is the expected behavior. It updates the cache. Try "ldconfig -p | grep octave:
ldconfig -p | grep octave
liboctinterp.so (libc6) => /usr/lib/octave-3.2.4/liboctinterp.so
liboctave.so (libc6) => /usr/lib/octave-3.2.4/liboctave.so
libcruft.so (libc6) => /usr/lib/octave-3.2.4/libcruft.so

I had this problem trying to implement qwt. I don't understand why putting the libs with -L and -l in the Makefile doesn't work, but I tried a lot of different combinations to no avail. Maybe someone can enlighten me(us).

Tottish
1st April 2010, 17:42
WoHoo!
Got it to work! I thought that the second thing you listed also had to be done for it to work. Thought it only applied after reboot, proves how new I am to this I guess! =)
Anyway, a HUGE thank you from me to you!!
Still tricking around a little though but the major errors are GONE! I'll keep you posted.
/Tottish

EDIT: It works! Runs perfectly... Now row to implement my nonlinear optimization algorithm. =) Hmmm. I wonder if global variables work with this method... Probably not since they are most likely not contained within the library...

iprogram
11th March 2011, 10:12
WoHoo!
Got it to work! I thought that the second thing you listed also had to be done for it to work. Thought it only applied after reboot, proves how new I am to this I guess! =)
Anyway, a HUGE thank you from me to you!!
Still tricking around a little though but the major errors are GONE! I'll keep you posted.
/Tottish

EDIT: It works! Runs perfectly... Now row to implement my nonlinear optimization algorithm. =) Hmmm. I wonder if global variables work with this method... Probably not since they are most likely not contained within the library...

Hi,
I'm working with Windows and cannot adapt your advice from the Linux-world. Sorry!
I get lots of udefined reference errors, and don't know where to put some correct paths to libraries to solve the problem. Maybe you can help me?
Thanks!

Starting: C:/Qt/2010.02.1/mingw/bin/mingw32-make.exe -w
mingw32-make: Entering directory `C:/Qt/ExamplesFromOthers/Octave_integration'
C:/Qt/2010.02.1/mingw/bin/mingw32-make -f Makefile.Debug
mingw32-make[1]: Entering directory `C:/Qt/ExamplesFromOthers/Octave_integration'
g++ -c -g -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"..\..\2010.02.1\qt\include\QtCore" -I"..\..\2010.02.1\qt\include" -I"..\..\..\Octave\3.2.4_gcc-4.4.0\include" -I"..\..\..\Octave\3.2.4_gcc-4.4.0\include\octave-3.2.4\octave" -I"..\..\2010.02.1\qt\include\ActiveQt" -I"debug" -I"..\..\2010.02.1\qt\mkspecs\win32-g++" -o debug\main.o main.cpp
g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-subsystem,console -mthreads -Wl -o debug\test2.exe debug/main.o -L"c:\Qt\2010.02.1\qt\lib" -LC:\Octave\3.2.4_gcc-4.4.0\lib -loctinterp -LC:\Octave\3.2.4_gcc-4.4.0\bin -loctinterp -lQtCored4
mingw32-make[1]: Leaving directory `C:/Qt/ExamplesFromOthers/Octave_integration'
mingw32-make: Leaving directory `C:/Qt/ExamplesFromOthers/Octave_integration'
debug/main.o: In function `main':
C:\Qt\ExamplesFromOthers\Octave_integration/main.cpp:28: undefined reference to `MatrixType::MatrixType()'
C:\Qt\ExamplesFromOthers\Octave_integration/main.cpp:28: undefined reference to `MatrixType::~MatrixType()'
C:\Qt\ExamplesFromOthers\Octave_integration/main.cpp:28: undefined reference to `MatrixType::~MatrixType()'
C:\Qt\ExamplesFromOthers\Octave_integration/main.cpp:34: undefined reference to `operator<<(std::ostream&, Matrix const&)'
... etc ...

Tottish
11th March 2011, 10:26
Hi!
I'm no wiz at this but to me it doesn't seem like an Octave specific problem so I'm sure you can get more experienced help from others reading this if my tip is wrong/doesn't work.

You might need something like this in your .pro-file:


OCTAVE_LOCATION = C:\path\to\octave
INCLUDEPATH += $${OCTAVE_LOCATION}/path/to/sources
LIBS = -L$${OCTAVE_LOCATION}/path/to/libs \
-loctinterp #(or whatever the name of the library(s?) you want to use.


Also, try to remember to wrap the code/compiler output you post in CODE tags for increased readability and to avoid smilies. (Use the pound sign from the toolbar).
Welcome to the Forum and Good luck! Just hang in there, google 'til your eyes bleed, read any official documentation and you'll crack it.
Peace Out!
/Tottish

nicanor5
24th December 2012, 19:36
Hello, sorry to revive this old thread, but is the only reference I have found about using Qt and Octave together.

I'm currently developing an application that uses Octave to do some signal processing to an audio signal (including loading and playing it) and Qt as the GUI.

I'm having trouble when running octave embedded in a Qt project as one of the Octave functions used in my process, hanning() is returning only zeros.

This doesn't happen if I embed without Qt.

If you can help me or guide me where I can get more help, thank you very much.

nicanor5
28th December 2012, 16:22
The problem I was having is related to the version 3.2 of Octave. Testing the program with the 3.6 version everything works fine so far.