Расширить DEIF, загрузку CAN и общую обработку сигналов
Добавить общее ядро DEIF, эмуляцию приборов и переносимые панели Python/Qt. Расширить загрузчики F2812 и F28335, обновление Flash и профиль STM Invertor. Добавить альтернативный МНК Eigen, модели неисправностей и диагностику сигналов. Обновить справочники устройств, проекты CCS и регрессионные проверки.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Альтернативный МНК Eigen QR
|
||||
|
||||
Необязательный настольный модуль выполняет полиномиальный МНК через
|
||||
`Eigen::ColPivHouseholderQR`. Исходный двухпроходный решатель остаётся вариантом
|
||||
по умолчанию. Прошивки и основная SETProtocol DLL продолжают собираться как C99.
|
||||
|
||||
Путь вызова: GUI → Python/ctypes → `setsignal_eigen` → общая подготовка
|
||||
`set_signal.c` → callback Eigen → общие вычисление кривой и RMSE.
|
||||
Сортировка, усреднение повторов X, нормировка, сетка, рабочий буфер и аннотации
|
||||
формул совпадают у обоих вариантов. Порог ранга Eigen относительный: `1e-12`;
|
||||
он может иначе классифицировать пограничные данные, чем исходная ортогонализация.
|
||||
Модуль не зависит от Qt и не участвует в обмене с устройствами.
|
||||
|
||||
| Файл | Назначение и зависимости |
|
||||
| --- | --- |
|
||||
| `signal_eigen.cpp` | Решатель QR и экспорт `set_signal_reconstruct_eigen`; C++14, Eigen, `set_signal.h` |
|
||||
| `build.py` | Сборка DLL/SO, проверка и распаковка локального архива; Python 3.8+ и C/C++ компиляторы |
|
||||
| `vendor/eigen-3.4.0.tar.gz` | Оригинальный архив зависимости, без изменений |
|
||||
| `../../python/set_devices/signal_eigen.py` | Ленивый ctypes-загрузчик отдельного компонента |
|
||||
|
||||
Зависимость: [Eigen 3.4.0, официальный архив](https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz).
|
||||
SHA-256: `8586084f71f9bde545ee7fa6d00288b264a2b7ac3607b974e54d13e7162c1c72`.
|
||||
Заголовки компилируются с `EIGEN_MPL2_ONLY`; `Eigen-COPYING.MPL2` копируется
|
||||
рядом с библиотекой и включается в пакет SETGUI. Сборка не требует интернета.
|
||||
|
||||
Из каталога SETGUI:
|
||||
|
||||
```powershell
|
||||
.venv/Scripts/python.exe third_party/templates/cpp/signal-eigen/build.py --output src/gui_desktop/native/setsignal_eigen.dll # Собираем 64-битный настольный компонент рядом с основной DLL.
|
||||
```
|
||||
|
||||
Для 32-битного приложения добавьте `--arch x86`. Компилятор C обрабатывает
|
||||
общий алгоритм отдельно от C++14-решателя. Windows-модуль использует статический
|
||||
CRT и PE-подсистему 6.01; работоспособность на самой Windows 7 требует проверки
|
||||
на соответствующей машине. Для Linux/macOS укажите имя `libsetsignal_eigen.so`
|
||||
или `libsetsignal_eigen.dylib`. `scripts/build_exe.py` собирает и упаковывает
|
||||
компонент автоматически, включая вариант Windows 7 x86.
|
||||
|
||||
Контракт `set_signal_fit_fn` описан в `c/set-protocol/include/set_signal.h`:
|
||||
callback получает уникальные нормированные X/Y, количество точек и степень 1…5,
|
||||
возвращает коэффициенты по возрастанию степеней аргумента `2*x-1`.
|
||||
Владение выходами остаётся у вызывающего; Eigen выделяет временные матрицы
|
||||
только в настольном порте. Коды ошибок: 0 — успех, 1 — параметры, 2 — нечисловой
|
||||
результат, 3 — недостаточный ранг, 5 — память/ошибка C++-решателя.
|
||||
Исключения не пересекают C ABI. Общих изменяемых рабочих буферов нет.
|
||||
|
||||
Загрузчик ищет компонент рядом с выбранной SETProtocol DLL. Переменная
|
||||
`SETSIGNAL_EIGEN_LIBRARY` позволяет явно задать путь для тестов. Отсутствующая
|
||||
библиотека вызывает понятную ошибку после выбора Eigen; скрытой замены
|
||||
на исходный решатель нет. Используется в обработке графиков и генераторе SETGUI.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
|
||||
#define EIGEN_MPL2_ONLY // Ограничиваем подключаемые части Eigen лицензией MPL-2.0.
|
||||
#include <Eigen/QR> // Подключаем QR с выбором ведущего столбца для полиномиального МНК.
|
||||
#include <cmath> // Проверяем конечность вычисленных коэффициентов перед передачей в C.
|
||||
#include <new> // Перехватываем ошибку выделения памяти внутри границы C ABI.
|
||||
#include "set_signal.h" // Используем общую подготовку точек, вычисление кривой и стабильный C ABI.
|
||||
|
||||
static int eigen_fit(const double *x,const double *y,size_t count,unsigned degree,double *coefficients) { // Вычисляем только коэффициенты по уже нормированным уникальным точкам.
|
||||
try { // Исключения C++ не должны пересекать границу ctypes или C-ядра.
|
||||
Eigen::MatrixXd design(count,degree+1); // Матрица имеет одну строку на точку и до шести степеней, включая свободный член.
|
||||
for(size_t i=0;i<count;++i) { // Заполняем нормированную матрицу Вандермонда в том же базисе, что исходный МНК.
|
||||
double power=1.0; // Нулевая степень задаёт столбец свободного члена без вызова pow.
|
||||
for(unsigned j=0;j<=degree;++j) { // Последовательно строим степени от нулевой до выбранной пользователем.
|
||||
design(i,j)=power; // Сохраняем коэффициент при соответствующей степени в строке измерения.
|
||||
power*=2.0*x[i]-1.0; // Переводим нормированное время из [0,1] в [-1,1], сохраняя обусловленность исходного алгоритма.
|
||||
} // Заканчиваем заполнение строки матрицы по одной временной точке.
|
||||
} // Все точки участвуют в МНК с одинаковым весом после общего усреднения повторов X.
|
||||
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qr(design); // Используем отражения Хаусхолдера с перестановкой столбцов вместо собственной ортогонализации.
|
||||
qr.setThreshold(1e-12); // Относительный порог ранга соответствует порядку допуска исходного решателя; он не является абсолютной погрешностью сигнала.
|
||||
if(qr.rank()!=static_cast<Eigen::Index>(degree+1)) return 3; // Отклоняем вырожденный базис, не выдавая неоднозначные коэффициенты за корректную кривую.
|
||||
Eigen::Map<const Eigen::VectorXd> values(y,count); // Читаем нормированные амплитуды из памяти C без дополнительного копирования входного вектора.
|
||||
Eigen::VectorXd solution=qr.solve(values); // Находим минимум суммы квадратов без формирования нормальных уравнений AᵀA.
|
||||
for(unsigned j=0;j<=degree;++j) { // Возвращаем степени в исходном порядке: Eigen отменяет перестановку столбцов при solve.
|
||||
if(!std::isfinite(solution[j])) return 2; // Не разрешаем NaN или бесконечности попасть в оценку кривой и RMSE.
|
||||
coefficients[j]=solution[j]; // Передаём коэффициент в буфер общего C-алгоритма вычисления полинома.
|
||||
} // Весь выходной полином проверен до передачи управления C-ядру.
|
||||
return 0; // Сообщаем общий для двух реализаций код успешного расчёта.
|
||||
} catch(const std::bad_alloc &) { // Преобразуем нехватку памяти необязательного настольного решателя в детерминированный код.
|
||||
return 5; // Код 5 обозначает невозможность выполнить расчёт, включая выделение матриц.
|
||||
} catch(...) { // Защищаем потребителей C ABI от остальных исключений библиотеки C++.
|
||||
return 5; // Возвращаем явную ошибку без подмены выбранного пользователем решателя.
|
||||
} // Завершаем защиту границы между C++ и C.
|
||||
} // Решатель не хранит глобальных данных и допускает независимые параллельные вызовы.
|
||||
|
||||
extern "C" PCAN_ABI_API int set_signal_reconstruct_eigen( // Отдельный экспорт сохраняет возможность загрузить модуль без изменения основной DLL.
|
||||
const double *x,const double *y,size_t count,int method,unsigned degree, // Формат точек и предел степени совпадают с исходным API.
|
||||
size_t output_count,int endpoint,double *out_x,double *out_y, // Временная сетка и включение конечной точки рассчитываются общим C-ядром.
|
||||
double *meta,double *work,size_t work_count) { // Метаданные и рабочая память сохраняют формат аннотаций формулы GUI.
|
||||
if(method!=SET_SIGNAL_POLYNOMIAL) return 1; // Eigen доступен только для МНК; остальные методы не маскируются под альтернативный решатель.
|
||||
return set_signal_reconstruct_with_fit(x,y,count,method,degree,output_count,endpoint,out_x,out_y,meta,work,work_count,eigen_fit); // Повторно используем C99-подготовку, обработку повторов, вычисление кривой и RMSE.
|
||||
} // Завершаем экспорт с соглашением вызова C для x86 и x64.
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user