/// <summary> /// R/S анализ ряда (последовательные вычисления) /// </summary> /// <param name="A">Массив входных данных</param> /// <param name="periodLength">Стартовая длина периода</param> /// <param name="startGIndex">Начальный индекс в массиве, с которого берутся данные</param> /// <param name="endGIndex">Конечный индекс в массиве, до которого берутся данные (включительно)</param> /// <param name="maxPeriodLength">Максимальная длина периода, до которого ведется расчет</param> /// <returns>Таблицу полученных R/S-точек и коэффициенты регрессии (A - соответствет H)</returns> public static ResultRS RS_Analyse(float[] A, int periodLength, int startGIndex, int endGIndex, int maxPeriodLength) { //кол-во RS-результатов int resLength = maxPeriodLength - periodLength + 1; //результаты RS-анализа PointRS[] result = new PointRS[resLength]; //последний индекс в массиве int lastIndex = endGIndex; //первый индекс в массиве //конечный локальный индекс int startIndex, endIndex, startIndexNow; //ср. значение RS для данного периода float averageRS; int j = 0; //текущая длина периода int currentPeriodLength = periodLength; //Кол-во периодов int periodCount = (endGIndex - startGIndex + 1) / currentPeriodLength; //Устанавливаем длину прогресбара CalculateStart.CreateEvent(resLength + 1, "R/S analyse..."); do { startIndex = lastIndex; endIndex = lastIndex; averageRS = 0; for (int i = 1; i <= periodCount; i++) { startIndex = endIndex - currentPeriodLength + 1; averageRS += GetRS(A, startIndex, endIndex); endIndex -= startIndex - 1; } startIndexNow = startIndex; averageRS /= periodCount; result[j].n = Math.Log10((float)currentPeriodLength / 2); result[j].rs = Math.Log10(averageRS); result[j].h = result[j].rs / result[j].n; j++; currentPeriodLength++; //Кол-во периодов periodCount = (endGIndex - startGIndex + 1) / currentPeriodLength; //Увеличиваем прогресбар Calculus.CreateEvent(j); }while (currentPeriodLength <= maxPeriodLength); KRegression regression = MathProcess.SimpleRegression(result); ResultRS res; res.points = result; res.regression = regression; return(res); }
/// <summary> /// Вычисление R/S анализа в потоке /// </summary> public void RS_Analyse() { //кол-во RS-результатов int resLength = maxPeriodLength - currentPeriodLength + 1; //результаты RS-анализа result = new PointRS[resLength]; //последний индекс в массиве int lastIndex = endGIndex; //первый индекс в массиве //конечный локальный индекс int startIndex, endIndex; //ср. значение RS для данного периода double averageRS; int j = 0; //Кол-во периодов int periodCount = (endGIndex - startGIndex + 1) / currentPeriodLength; do { startIndex = lastIndex; endIndex = lastIndex; averageRS = 0; for (int i = 1; i <= periodCount; i++) { startIndex = endIndex - currentPeriodLength + 1; averageRS += ChaosLogic.GetRS(A, startIndex, endIndex); endIndex -= startIndex - 1; } averageRS /= periodCount; result[j].n = Math.Log10((float)currentPeriodLength / 2); result[j].rs = Math.Log10(averageRS); result[j].h = result[j].rs / result[j].n; result[j].h0 = averageRS / currentPeriodLength; j++; currentPeriodLength++; //Кол-во периодов periodCount = (endGIndex - startGIndex + 1) / currentPeriodLength; //Увеличиваем прогресбар Calculus.CreateEvent(j, threadNum); }while (currentPeriodLength <= maxPeriodLength); }
/// <summary> /// Простая линейная регрессия y=Ax+B /// </summary> /// <param name="A">Массив наблюдений</param> /// <returns>Коэффициенты A и B</returns> public static KRegression SimpleRegression(PointRS[] A) { double sumX = 0; double sumY = 0; double sumX2 = 0; double sumXY = 0; CalculateStart.CreateEvent(A.Length, "Simple regression ..."); for (int i = 0; i < A.Length; i++) { sumX += A[i].n; sumY += A[i].rs; sumX2 += A[i].n * A[i].n; sumXY += A[i].n * A[i].rs; Calculus.CreateEvent(i); } double nSumX2 = A.Length * sumX2; KRegression res; res.A = (A.Length * sumXY - sumX * sumY) / (nSumX2 - sumX * sumX); res.B = (sumX2 * sumY - sumX * sumXY) / (nSumX2 - sumX2 * sumX2); return(res); }
public static KRegression SimpleRegression(double[,] A, int startIndex, int endIndex) { double sumX = 0; double sumY = 0; double sumX2 = 0; double sumXY = 0; int len = endIndex - startIndex + 1; CalculateStart.CreateEvent(len, "Simple regression ..."); for (int i = startIndex; i < len; i++) { sumX += A[i, 0]; sumY += A[i, 1]; sumX2 += A[i, 0] * A[i, 0]; sumXY += A[i, 0] * A[i, 1]; Calculus.CreateEvent(i); } double nSumX2 = len * sumX2; KRegression res; res.A = (len * sumXY - sumX * sumY) / (nSumX2 - sumX * sumX); res.B = (sumX2 * sumY - sumX * sumXY) / (nSumX2 - sumX2 * sumX2); return(res); }