Esempio n. 1
0
        /// <summary>
        /// Instantiates an initialized instance.
        /// Supports data resampling (including simple detection of signal begin/end) and amplitude unification.
        /// </summary>
        /// <param name="inputData">1D array containing the pattern input data</param>
        /// <param name="numOfVariables">Number of pattern variables</param>
        /// <param name="variablesSchema">Schema of variables organization in the 1D input pattern</param>
        /// <param name="detrend">Specifies whether to remove trend from the variables' data</param>
        /// <param name="unifyAmplitudes">Specifies whether to unify amplitude of variable's data over the time dimension</param>
        /// <param name="signalBeginThreshold">If specified (GT 0), signal begin will be decided at timepoint Tx where (abs(s(Tx) - s(T0)) / s(max) - s(min)) >= given threshold (x in order 0..last)</param>
        /// <param name="signalEndThreshold">If specified (GT 0), signal end will be decided at timepoint Tx where (abs(s(Tx) - s(T last)) / s(max) - s(min)) >= given threshold (x in order last..0)</param>
        /// <param name="uniformTimeScale">If false then each variable will have its own time dimension</param>
        /// <param name="targetTimePoints">If specified, resulting parttern variable's data will be upsampled and/or downsampled to have specified fixed length (time points)</param>
        public InputPattern(double[] inputData,
                            int numOfVariables,
                            VariablesSchema variablesSchema,
                            bool detrend                = false,
                            bool unifyAmplitudes        = false,
                            double signalBeginThreshold = 0d,
                            double signalEndThreshold   = 0d,
                            bool uniformTimeScale       = true,
                            int targetTimePoints        = -1
                            )
            : this(numOfVariables)
        {
            List <double[]> patternRawData = PatternDataFromArray(inputData, 0, inputData.Length, numOfVariables, variablesSchema);
            int             rawTimePoints  = patternRawData[0].Length;
            //Remove trend?
            if (detrend)
            {
                //Trend removal -> convert data to differences
                for (int varIdx = 0; varIdx < numOfVariables; varIdx++)
                {
                    double[] detrended = new double[patternRawData[varIdx].Length];
                    detrended[0] = 0;
                    for (int i = 1; i < patternRawData[varIdx].Length; i++)
                    {
                        detrended[i] = patternRawData[varIdx][i] - patternRawData[varIdx][i - 1];
                    }
                    patternRawData[varIdx] = detrended;
                }
            }
            //Initially set begin and end signal indexes to full range
            int[] signalBeginIdxs = new int[numOfVariables];
            signalBeginIdxs.Populate(0);
            int[] signalEndIdxs = new int[numOfVariables];
            signalEndIdxs.Populate(rawTimePoints - 1);
            //Detection of signal begin?
            if (signalBeginThreshold > 0d)
            {
                int minSignalBeginIdx = -1;
                for (int varIdx = 0; varIdx < numOfVariables; varIdx++)
                {
                    signalBeginIdxs[varIdx] = DetectSignalBegin(patternRawData[varIdx], signalBeginThreshold);
                    if (minSignalBeginIdx == -1 || minSignalBeginIdx > signalBeginIdxs[varIdx])
                    {
                        minSignalBeginIdx = signalBeginIdxs[varIdx];
                    }
                }
                if (uniformTimeScale)
                {
                    signalBeginIdxs.Populate(minSignalBeginIdx);
                }
            }
            //Detection of signal end?
            if (signalEndThreshold > 0d)
            {
                int maxSignalEndIdx = -1;
                for (int varIdx = 0; varIdx < numOfVariables; varIdx++)
                {
                    signalEndIdxs[varIdx] = DetectSignalEnd(patternRawData[varIdx], signalEndThreshold);
                    if (maxSignalEndIdx == -1 || maxSignalEndIdx < signalEndIdxs[varIdx])
                    {
                        maxSignalEndIdx = signalEndIdxs[varIdx];
                    }
                }
                if (uniformTimeScale)
                {
                    signalEndIdxs.Populate(maxSignalEndIdx);
                }
            }
            //Correct begin/end indexes
            for (int varIdx = 0; varIdx < numOfVariables; varIdx++)
            {
                if (signalEndIdxs[varIdx] <= signalBeginIdxs[varIdx])
                {
                    signalBeginIdxs[varIdx] = 0;
                    signalEndIdxs[varIdx]   = rawTimePoints - 1;
                }
            }

            //Resampling
            targetTimePoints = Math.Max(2, targetTimePoints == -1 ? rawTimePoints : targetTimePoints);
            for (int varIdx = 0; varIdx < numOfVariables; varIdx++)
            {
                int signalLength = (signalEndIdxs[varIdx] - signalBeginIdxs[varIdx]) + 1;
                if (signalLength != rawTimePoints || targetTimePoints != rawTimePoints)
                {
                    //Perform resampling
                    int lcm = Discrete.LCM(signalLength, targetTimePoints, out _);
                    //Upsample
                    double[] upsampledData = Upsample(patternRawData[varIdx], signalBeginIdxs[varIdx], signalEndIdxs[varIdx], lcm);
                    //Downsample
                    double[] downsampledData = Downsample(upsampledData, targetTimePoints);
                    VariablesDataCollection.Add(downsampledData);
                }
                else
                {
                    //No resampling is necessary so simply use the unchanged raw data
                    double[] signalData = new double[signalLength];
                    for (int i = 0; i < signalLength; i++)
                    {
                        signalData[i] = patternRawData[varIdx][signalBeginIdxs[varIdx] + i];
                    }
                    VariablesDataCollection.Add(signalData);
                }
            }

            //Unify amplitudes
            if (unifyAmplitudes)
            {
                UnifyAmplitudes();
            }
            return;
        }
Esempio n. 2
0
        /// <summary>
        /// Extracts variables' data from 1D array
        /// </summary>
        /// <param name="inputData">1D array containing pattern input data</param>
        /// <param name="dataStartIndex">Specifies the zero-based starting index of pattern input data in the given 1D input data array</param>
        /// <param name="dataLength">Specifies the length of pattern input data in the given 1D input data array</param>
        /// <param name="numOfVariables">Number of pattern variables</param>
        /// <param name="varDataOrganization">Variables' time-order data organization in the given 1D input data array</param>
        public List <double[]> PatternDataFromArray(double[] inputData, int dataStartIndex, int dataLength, int numOfVariables, VariablesSchema varDataOrganization)
        {
            //Check data length
            if (dataLength < numOfVariables || (dataLength % numOfVariables) != 0)
            {
                throw new FormatException("Incorrect length of input data.");
            }
            //Pattern data
            int             timePoints  = dataLength / numOfVariables;
            List <double[]> patternData = new List <double[]>(numOfVariables);

            for (int i = 0; i < numOfVariables; i++)
            {
                patternData.Add(new double[timePoints]);
            }
            Parallel.For(0, timePoints, timeIdx =>
            {
                for (int i = 0; i < numOfVariables; i++)
                {
                    double varValue         = varDataOrganization == VariablesSchema.Groupped ? inputData[dataStartIndex + timeIdx * numOfVariables + i] : inputData[dataStartIndex + i * timePoints + timeIdx];
                    patternData[i][timeIdx] = varValue;
                }
            });//timeIdx
            return(patternData);
        }