/** \file ivcmp.h
 * Библиотека для сравнения ВАХ.
 */

#ifndef IVCMP_H
#define IVCMP_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdint.h>
#if defined(_WIN32) || defined (_WIN64)
#define EXPORT __declspec(dllexport)
#define CCONV __cdecl
#else
#define EXPORT
#define CCONV
#endif

/** 
 * Функция установки порогов масштабирования при нормировке токов и напряжений.
 * Установка этих параметров обязательна для корректной работы библиотеки.
 * При сравнении кривых производится нормировка токов и напряжений.
 * Шумы, которые есть в любой системе, могут оказывать влияние на результат сравнения.
 * Если шумы не учитывать, то при сравнении визуально совпадающих кривых,
 * библиотека может выдать ненулевую степень различия из-за неправильной нормировки.
 * Чтобы этого не произошло, установите порог нормировки с помощью данной функции.
 * Сохранённые значения будут использоваться для всех последующих сравнений кривых
 * до тех пор пока масштабы не будут обновлены путём вызова данной функции 
 * или функции SetMinVarVCFromCurves().
 * 
 * Способы определения порогов масштабирования:
 * - Ручной:
 *     - Произвести измерения шумов по току и напряжению.
 *     - Определить их стандартные отклонения.
 *     - Задать пороги, равные трём стандартным отклонениям.
 * - Автоматический:
 *     - Измерить сигнатуры разрыва и короткого замыкания.
 *     - Воспользоваться процедурой автоматического определения с помощью функции SetMinVarVCFromCurves().
 * - Ручной грубый:
 *     - Задать пороги сравнения, равные 3% от диапазонов измерения по току и напряжению.
 *
 * При любом способе определения пороги масштабирования зависят от диапазонов измерения.
 * Поэтому значения необходимо обновлять при каждом изменении настроек измерителя.
 *
 * @param[in] NewMinVarV Характерный масштаб по напряжению. Единицы измерения: Вольты.
 * @param[in] NewMinVarC Характерный масштаб по току. Единицы измерения: мА.
 */
EXPORT void CCONV SetMinVarVC(double NewMinVarV, double NewMinVarC);

/**
 * Функция автоматического определения и установки порогов масштабирования при нормировке токов и напряжений.
 * Функция принимает две сигнатуры:
 * - первая должна быть измерена при разомкнутых щупах (измеряется нулевой ток);
 * - вторая должна быть измерена в случае, когда щупы замкнуты накоротко (измеряется напряжение КЗ).
 * На основе полученных сигнатур функция определяет характерные масштабы шумов
 * и задаёт пороги масштабирования при нормировке.
 * Установленные значения будут использоваться для всех последующих сравнений кривых
 * до тех пор пока пороги не будут обновлены путём вызова данной функции
 * или функции SetMinVarVC().
 * Данная функция является альтернативой для функции SetMinVarVC().
 * Если Вы не знаете уровень шумов, но у Вас есть сигнатуры короткого замыкания
 * и разрыва, используйте эту функцию. Если у Вас нет сигнатур или
 * Вы хотите произвести оценки самостоятельно, используйте функцию SetMinVarVC().
 *
 * @param[in] VoltagesOpenC Массив напряжений сигнатуры, снятой при разомкнутых щупах [Вольты]
 * @param[in] CurrentsOpenC Массив токов сигнатуры, снятой при разомкнутых щупах [мА]
 * @param[in] CurveLengthOpenC Количество элементов в массивах VoltagesOpenC и CurrentsOpenC (должно быть одинаковым).
 * @param[in] VoltagesShortC Массив напряжений сигнатуры, снятой при коротко замкнутых щупах [Вольты]
 * @param[in] CurrentsShortC Массив токов сигнатуры, снятой при коротко замкнутых щупах [Вольты]
 * @param[in] CurveLengthShotC Количество элементов в массивах VoltagesShortC и CurrentsShortC (должно быть одинаковым).
 */
EXPORT void CCONV SetMinVarVCFromCurves(double *VoltagesOpenC, double *CurrentsOpenC, uint32_t CurveLengthOpenC,
                                        double *VoltagesShortC, double *CurrentsShortC, uint32_t CurveLengthShotC);

/**
 * Функция для получения текущих значений порогов масштабирования при нормировке токов и напряжений.
 * Подробнее о порогах см. описание функции SetMinVarVC.
 *
 * @param[out] NewMinVarVPtr - указатель, по которому будет записан характерный масштаб по напряжению. Единицы измерения: Вольты.
 * @param[out] NewMinVarCPtr - указатель, по которому будет записан характерный масштаб по напряжению. Единицы измерения: Вольты.
 */
EXPORT void CCONV GetMinVarVC(double *NewMinVarVPtr, double *NewMinVarCPtr);

/**
 * Функция для сравнения двух сигнатур (ВАХ).
 * Возвращает степень различия в диапазоне [0, 1]
 * (0 - кривые совпадают, 1 - кривые совсем разные).
 * Степень различия соответствует визуальному различию кривых.
 * Совпадающими сигнатурами являются те, которые совпадают при наложении.
 * Максимальным различием обладают сигнатуры разрыва и короткого замыкания
 * (в одной из них меняется только напряжение, в другой меняется только ток).
 * Если сигнатуры имеют некоторые общие черты, но не совпадают
 * (например, сопротивления разных номиналов
 * или сопротивление и сопротивление с ёмкостью), степень различия будет промежуточной.
 * Передаваемые массивы токов и напряжений должны иметь одинаковую длину
 * и содержать по одному периоду пробного сигнала
 * (один цикл замкнутой кривой).
 * @param[in] VoltagesA Массив напряжений первой кривой для сравнения [Вольты]
 * @param[in] CurrentsA Массив токов первой кривой для сравнения [мА]
 * @param[in] CurveLengthA Количество элементов в массивах VoltagesA и CurrentsA (должно быть одинаковым).
 * @param[in] VoltagesB Массив напряжений второй кривой для сравнения [Вольты]
 * @param[in] CurrentsB Массив токов второй кривой для сравнения [мА]
 * @param[in] CurveLengthB Количество элементов в массивах VoltagesA и CurrentsA (должно быть одинаковым).
 * @return Score Степень различия (0 - кривые совпадают, 1 - кривые совсем разные).
 */
EXPORT double CCONV CompareIVC(double *VoltagesA, double *CurrentsA, uint32_t CurveLengthA,
                               double *VoltagesB, double *CurrentsB, uint32_t CurveLengthB);
#ifdef __cplusplus
}
#endif

#endif /* IVCMP_H */
