Есть немало причин для появления такой ошибки.
> Хотя компилятор то библиотеку находит (это факт), но получается, что
> эта функция не определена, хотя есть в хедерах.
Заголовочный файл используется при собственно компиляции. Он содержит
просто определение фукнции. Он не связан напрямую с библиотекой, где
находится эта функция. У ваш ошибка идет от linker, который не может
найти эту функцию в библиотеках.
> Может кто подскажет куда идти дальше, уже много перерыл, не знаю куда
> обращаться.
Хорошее начало - это использование программы nm, скажем
nm liblapack.a | grep cgels
Это позволит вам найти ответ на вопрос, есть ли такая фукнция в
библиотеке и как она точно там называется.
Далее, в С++ имена функций при формирования объектного файла меняются
(name mangling). Поэтому имеет смысл с помощью nm проверить, а как
называется функция cgels_ в вашем объектном файле. Если вы компилируете
в С++ и не используете extern "C", то она там называется совсем по
другому. Тогда сборщик может не найти ее в библиотеке, если она даже там
есть под названием cgels_.
Еще пара комментариев.
1) Разумнее всего компилировать LAPACK непосредственно, поскольку
CLAPACK получен с помощью f2c, а это может дать не самую лучшую
производительность.
2) LAPACK зависит от BLAS, поэтому библиотеки должны идти как -llapack
-lblas
3) Для оптимальной производительности рекомендуется использоваться
оптимизированный BLAS, см. например здесь
Это говорит, что в библиотеке присутствует объект cgels_. Буква T
показывает, что он есть, а не вызывается.
> $ nm main.o | grep cge
> U _Z6cgels_PcPlS0_S0_P7complexS0_S2_S0_S2_S0_S0_
А вот ваш файл вызывает (буква U) совсем другую функцию. Понятно, что
сборщик не находит такой фукнции в библиотеке. Надо сказать, чтобы С++
не менял название функции. Это достигается с помощью
extern "C" {
#include <lapack.h>
}
> g++ -Wl,-rpath,/opt/qt4/lib -o ../bin/vt main.o -L/opt/qt4/lib -L./
> lib -llapack -lblas -lQtCore -L/opt/qt4/lib -lz -lm -pthread -
> lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread
> ./lib/liblapack.a(cunmlq.o): In function `cunmlq_':
> cunmlq.f:(.text+0x47b): undefined reference to
> `_gfortran_concat_string'
g++ умолчанию не подключает стандартных библиотек Фортрана. Это надо
сделать вручную. Если бы вы использовали g77, то надо было бы добавить
-lg2c. Я не знаю, какие библиотеки использует gfortran. Это можно
посмотреть, если что-то скомпилировать им и задать ключ -v. В этом
случае все компиляторы gcc пишут полные команды, которые они подают. Там
все можно и найти. Также можно найти подходящую библиотеку с помощью nm.
Но проще, наверное, взглянуть на документацию gfortran.
Скорее всего вы неправильно вызываете подпрограмму. Это наиболее частая
ошибка.
В LAPACK есть тесты. Может быть начать с них. Скажем для вашей
подрограммы это
http://www.netlib.org/lapack/testing/lin/cdrvls.f
Правда, я не знаю, есть ли это в СLAPACK.
С другой стороны, можно сделать простой пример с небольшими матрицами в
чем угодно, Matlab, Mathematica, SciPy или даже на бумаге. И затем
прогнать его. Чтобы проверить, правильно ли вы вызываете подрограмму,
вставьте в нее распечатку входных параметров.
Сложно сказать. Я бы ожидал, что в LAPACK есть проверки, чтобы исключить
деление на нуль, но чего только не бывает. Я сам не работал с этой
подпрограммой.
Проверьте еще раз и попробуйте обратиться в поддержку
http://www.netlib.org/lapack/support.html
Но там как раз рекомендуют вначале запустить тесты LAPACK.
>Аналогичная функция в clapack есть
>http://www.netlib.org/lapack/testing/lin/cdrvls.f
>Только что ней делать? Не совсем понятно для меня
Это часть тестов LAPACK. Там при компиляции можно указать, чтобы
скомпилировать и прогнать все тесты. Я как-то раз это делал, но только
для версии double.
Недавно мне потребовалось решение системы линейных уравнений с
комплексной матрицей. У меня zgesv работает.
http://www.netlib.org/lapack/lug/node27.html
Если вы запишите вашу матрицу и вектор, с котороми происходит деление на
нуль, в текстовой файл, то я мог бы попробовать решить эту задачу в
SciPy - там есть LAPACK интерфейс. Правда я боюсь, что смогу сделать это
только в конце следующей недели.