From 9d862728ef676f1ee89d2934703dc1dbaa626892 Mon Sep 17 00:00:00 2001 From: Aleksey_K Date: Fri, 17 May 2024 16:03:52 +0900 Subject: [PATCH] mask_funk was updated, add harm corr, spec corr --- mask_func.js | 118 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 28 deletions(-) diff --git a/mask_func.js b/mask_func.js index 12794e4..58f4719 100644 --- a/mask_func.js +++ b/mask_func.js @@ -1,64 +1,94 @@ export function spec_model(spec, tol) { + let result = {}; //результат let model = spec.base; //исходный массив точек для построения упрощенной модели спектра - let imin = 0; //левый соседний индекс - let imax = 0; //правая соседний индекс + let imin = 0; //левая граница коридора + let imax = 0; //правая граница коридора for (let i = 0; i < spec.peaks.length; i++) { let freq = spec.peaks[i].freq; //получаем значение частоты гармоники из массива обнаруженных гармоник let level = spec.peaks[i].level; //получаем значение уровня гармоники из массива обнаруженных гармоник imin = Math.round((freq - freq * 0.5 * tol / 100) / spec.resolution); imax = Math.round((freq + freq * 0.5 * tol / 100) / spec.resolution); + if (imax > spec.base.length) { imax = spec.base.length - 1 }; //проверяем выход границы за размер массива for (let j = imin; j <= imax; j++) { model[j] = spec.base[j] + level }; }; - //отрисовка пользовательского графика + //формируем результат + result["name"] = "model_" + spec.name; + result["resolution"] = spec.resolution; + result["data"] = model; + + //отрисовка графика на plot gtl.plot.add( { color: 0x44944A, - name: "model_" + spec.name, - x: spec.resolution, + name: result.name, + x: result.resolution, y: model } ); - return model; + return result; }; //построение упрощенной модели спектра export function mask(obj) { - let mask = obj.spec.base; //исходный массив точек для построения портрета дефекта + let result = {}; //результат + let data = obj.src1.data; //массив точек спектра для сравнения с портретом + let mask = obj.src2.base; //исходный массив точек для построения портрета дефекта + let harms = obj.harms; //гармоник портрета + if (obj.freq * harms > obj.src2.frequency) { harms = Math.trunc(obj.src2.frequency / obj.freq) }; //проверяем максимальное кол-во гармоник в портрете let df = 0; //отношение ширины фильтра частотному разрешению спектра let dl = obj.lvl; //разность уровней гармонической и случайной составляющей вибрации if (obj.filter != 0) { - df = obj.filter.width / obj.spec.resolution; + df = obj.filter.width / obj.src2.resolution; dl = 10 * Math.log10((obj.lvl ** 2) * df + 1); }; - let k = 0; //коэффициент затухания + let k = obj.coef; //коэффициент затухания let xmin = 0; //левая граница коридора let xmax = 0; //правая граница коридора + let correlation = 0; //коэффициент корреляции + + function corr(a, b) { + let a_sum = 0; //сумма значений массива 1 + let b_sum = 0; //сумма значений массива 2 + let X = 0; //аргумент 1 + let Y = 0; //аргумент 2 + let Z = 0; //аргумент 3 + for (let i = 0; i < a.length; i++) { a_sum += a[i] }; + for (let i = 0; i < b.length; i++) { b_sum += b[i] }; + let a_avg = a_sum / a.length; + let b_avg = b_sum / b.length; + + for (let i = 0; i < a.length; i++) { + X += (a[i] - a_avg) * (b[i] - b_avg); + Y += (a[i] - a_avg) ** 2; + Z += (b[i] - b_avg) ** 2; + }; + gtl.log.info("Корреляция гармоники:", X / (Math.sqrt(Y) * Math.sqrt(Z))); + return X / (Math.sqrt(Y) * Math.sqrt(Z)); + }; switch (obj.type) { - case 0: //маска износа: коэффициент затухания 30-50% - for (let i = 1; i <= obj.harms; i++) { - k = 0.5; - xmin = Math.round(i * (obj.freq - obj.freq * 0.5 * obj.tol / 100) / obj.spec.resolution); //определяем индекс левой границы коридора - xmax = Math.round(i * (obj.freq + obj.freq * 0.5 * obj.tol / 100) / obj.spec.resolution); //определяем индекс правой границы коридора; - for (let j = xmin; j <= xmax; j++) { mask[j] = obj.spec.base[j] + dl }; //записываем значение глубины модуляции для коридора - dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания - }; - break; - case 1: //маска дефекта: коэффициент затухания 5-10% + case 0: //обычный ряд for (let i = 1; i <= harms; i++) { - k = 0.1; - xmin = Math.round(i * (obj.freq - obj.freq * 0.5 * obj.tol / 100) / obj.spec.resolution); //определяем индекс левой границы коридора - xmax = Math.round(i * (obj.freq + obj.freq * 0.5 * obj.tol / 100) / obj.spec.resolution); //определяем индекс правой границы коридора; - for (let j = xmin; j <= xmax; j++) { mask[j] = obj.spec.base[j] + dl }; //записываем значение глубины модуляции для коридора + let arr1 = []; + let arr2 = []; + xmin = Math.round(i * (obj.freq - obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс левой границы коридора + xmax = Math.round(i * (obj.freq + obj.freq * 0.5 * obj.tol / 100) / obj.src2.resolution); //определяем индекс правой границы коридора + if (xmax > obj.src2.base.length) { xmax = obj.src2.base.length - 2 }; //проверяем выход границы за размер массива + for (let j = xmin; j <= xmax; j++) { mask[j] = obj.src2.base[j] + dl }; //записываем значение глубины модуляции для коридора + for (let j = xmin - 2; j <= xmax + 2; j++) { + arr1.push(mask[j]); + arr2.push(data[j]); + }; //формируем массивы портретной гармоники и спектра (модели) под портретом + correlation += corr(arr1, arr2); //рассчитываем корреляцию данных из массивов dl = dl - (k * dl); //снижаем глубину модуляции с коэффициентом затухания }; break; - case 2: //маска перекоса: коэффициент выраженности 0-20% + case 1: //четные составляющие for (let i = 1; i < obj.harms; i++) { if (i % 2 > 0) { - k = 0.1; + }; }; @@ -67,18 +97,50 @@ export function mask(obj) { break; }; - //отрисовка пользовательского графика + //формируем результат + result["name"] = obj.name; //имя маски дефекта + result["corr"] = correlation / harms; //средняя корреляция + result["data"] = mask; //массив данных портрета + + //отрисовка графика на plot gtl.plot.add( { color: 0xff0000, name: obj.name, - x: obj.spec.resolution, + x: obj.src2.resolution, y: mask } ); - return mask; + return result; }; //построение портрета дефекта +export function corr(spec1, spec2) { + let result = {}; //результат + let plot = []; //массив значений корреляции для графика + let corr = 0; //коэффициент корреляции + let arr1 = spec1.data; + let arr2 = spec2.data; + let arr1_sum = 0; //сумма значений массива 1 + let arr2_sum = 0; //сумма значений массива 2 + let X = 0; //аргумент 1 + let Y = 0; //аргумент 2 + let Z = 0; //аргумент 3 + for (let i = 0; i < arr1.length; i++) { arr1_sum += arr1[i] }; + for (let i = 0; i < arr2.length; i++) { arr2_sum += arr2[i] }; + let arr1_avg = arr1_sum / arr1.length; + let arr2_avg = arr2_sum / arr2.length; + for (let i = 0; i < arr1.length; i++) { + X += (arr1[i] - arr1_avg) * (arr2[i] - arr2_avg); + Y += (arr1[i] - arr1_avg) ** 2; + Z += (arr2[i] - arr2_avg) ** 2; + plot.push(X / (Math.sqrt(Y) * Math.sqrt(Z))); + }; + corr = X / (Math.sqrt(Y) * Math.sqrt(Z)); + result["corr"] = corr; + result["plot"] = plot; + + return result; +}; //рассчет корреляции спектров