#include "scope_demo.h" // Проверяем тот же переносимый источник, который подключён к настоящему DSView. #include // Ошибка физической модели должна завершать нативную проверку ненулевым кодом. #include // Нечисловые значения воспроизводят повреждённые входные параметры. int main() { // Проверка не требует Qt, аппаратного анализатора или платы Zynq. const double epsilon = 1e-9; // Допуск 1 нВ учитывает погрешность вычисления sin, сохраняя проверку амплитуды в вольтах. for (unsigned channel = 0; channel < 4; ++channel) { // Все каналы проверяются независимо, включая две разные формы сигнала. const double period = 1 / set_scope::hz[channel]; // Период в секундах рассчитывается из частоты исходного эмулятора Zynq. assert(std::abs(set_scope::value(channel, period / 4) - set_scope::peak[channel]) < epsilon); // Четверть периода даёт положительный пик у обеих форм. assert(std::abs(set_scope::value(channel, 3 * period / 4) + set_scope::peak[channel]) < epsilon); // Три четверти периода дают отрицательный пик. assert(std::abs(set_scope::value(channel, -period / 4) + set_scope::peak[channel]) < epsilon); // Отрицательное время сохраняет непрерывность фазы при прокрутке. assert(std::abs(set_scope::value(channel, period / 8) - set_scope::value(channel, period * 5.125)) < epsilon); // Сдвиг на пять целых периодов не изменяет напряжение. const auto full = set_scope::extrema(channel, 0, 500); // Пятьсот секунд моделируют очень длинную развёртку с сотнями тысяч периодов в пикселе. assert(full.low == -set_scope::peak[channel] && full.high == set_scope::peak[channel]); // Огибающая обязана сохранять оба пика без алиасинга. const auto narrow = set_scope::extrema(channel, period * 0.20, period * 0.30); // Внутренний максимум нельзя обнаружить только по концам интервала. assert(narrow.high == set_scope::peak[channel]); // Аналитический расчёт обязан найти пик между экранными отсчётами. const auto reverse = set_scope::extrema(channel, period * 0.30, period * 0.20); // Переставленные границы воспроизводят обратное направление выделения. assert(reverse.low == narrow.low && reverse.high == narrow.high); // Направление просмотра не должно менять диапазон напряжения. for (int index = 0; index < 300; ++index) { // Непериодическая сетка интервалов выявляет ошибки поиска внутренних экстремумов. const double first = (index - 150) * period / 37, last = first + period / 13; // Интервалы охватывают отрицательное время и разные положения относительно фронтов. const auto range = set_scope::extrema(channel, first, last); // Огибающая вычисляется производственным алгоритмом с постоянной сложностью. for (int sample = 0; sample <= 100; ++sample) { // Плотная независимая выборка проверяет отсутствие потерянных пиков и фронтов. const double value = set_scope::value(channel, first + (last - first) * sample / 100); // Напряжение берётся внутри проверяемого временного интервала. assert(value >= range.low - epsilon && value <= range.high + epsilon); // Ни одно значение идеального источника не должно выходить за рассчитанную огибающую. } // Проверка включает меандр с разрывами и гладкий синус. } // Всего проверяется более 120 тысяч точек на различных интервалах. } // Проверены частоты, амплитуды, фаза и длинная развёртка всех четырёх источников. assert(set_scope::value(4, 0) == 0); // Несуществующий пятый канал безопасно отклоняется. assert(set_scope::value(0, std::numeric_limits::infinity()) == 0); // Бесконечное время не распространяет NaN в геометрию Qt. assert(set_scope::extrema(0, 0, std::numeric_limits::quiet_NaN()).high == 0); // Повреждённая граница интервала возвращает определённый пустой диапазон. return 0; // Нулевой код сообщает об успешной нативной проверке модели Zynq. } // Исполняемый файл можно запускать на любой платформе с компилятором C++11.