1

変動する時間にキャプチャされたいくつかのメトリックを、一定のタイミング間隔に線形補間したいと考えています。

let original_times:[Double] = [0.0,1.3,2.2,3.4,4.2,5.5,6.6,7.2,8.4,9.5,10.0]
let metric_1:[Double] = [4,3,6,7,4,5,7,4,2,7,2]

let wanted_times:[Double] = [0,1,2,3,4,5,6,7,8,9,10]

//linearly resample metric_1 (with corresponding sampling times 'original_times') to fixed time interval times 'wanted_times'

AcceleratevDSP_vlintを提供していますが、アプリケーションに実装する方法を理解するのに苦労しています。

func vDSP_vlint(_ __A: UnsafePointer<Float>, _ __B: UnsafePointer<Float>, _ __IB: vDSP_Stride, _ __C: UnsafeMutablePointer<Float>, _ __IC: vDSP_Stride, _ __N: vDSP_Length, _ __M: vDSP_Length)
4

3 に答える 3

1

Accelerate のものを使用しない別のソリューションを次に示します。

public class Resampler {


///
/// ### Class method to resample some data
///
/// ### Inputs
/// - Actual time data that may not be regularly sampled
/// - Desired times you want the metric found at
/// - Metric data corresponding with actual time data
///
public class func resample( acualTimes atimes: [Double], desiredTimes dtimes: [Double], metric: [Double] ) ->[Double]
{
    //
    // Initialize the desired metrics array
    //
    var desiredMetrics: [Double] = [Double](count: dtimes.count, repeatedValue: 0);

    // Initialize a counter to keep track of which metric value we are on
    var counter: Int = 0;

    // Loop through the desired times
    for dtime in dtimes {

        // Find the bounding indices, based on actual time data, for the desired time
        // using a binary search
        let (li, ri) = binarySearch(0,highBound: atimes.count-1, desiredTime: dtime, timeData: atimes);

        // Find the desired metric using an interpolation
        desiredMetrics[counter] = linearInterpolate(lowTime: atimes[li],
                                                    highTime: atimes[ri],
                                                    lowMetric: metric[li],
                                                    highMetric: metric[ri],
                                                    desiredTime: dtime);
        // Increment the counter
        counter++;
    }

    // Return the desired metrics
    return desiredMetrics;
}


///
/// ### Binary search code to find the bounding time value indices
///
private class func binarySearch(  lowBound: Int,
                            highBound: Int,
                            desiredTime: Double,
                            timeData: [Double]) -> (leftIndex: Int, rightIndex: Int)
{
    if( highBound-lowBound == 1 ){
        return (lowBound, highBound);
    }else{
        let center: Int = (lowBound + highBound)/2;
        if( desiredTime <= timeData[center]){
            return binarySearch(lowBound, highBound: center, desiredTime: desiredTime, timeData: timeData);
        }else{
            return binarySearch(center, highBound: highBound, desiredTime: desiredTime, timeData: timeData);
        }
    }
}


///
/// ### Linear interpolation method
///
private class func linearInterpolate(   lowTime lt: Double,
                                        highTime ht: Double,
                                        lowMetric lm: Double,
                                        highMetric hm: Double,
                                        desiredTime dt: Double ) -> Double
{
    return lm + (dt-lt)*(hm-lm)/(ht-lt);
}

}

そして、次のようにするだけで実行できます。

    let times: [Double] = [0.0,1.3,2.2,3.4,4.2,5.5,6.6,7.2,8.4,9.5,10.0];
    let desiredTimes: [Double] = [0,1,2,3,4,5,6,7,8,9,10];
    let metricData: [Double] = [4,3,6,7,4,5,7,4,2,7,2];

    let desiredMetrics = Resampler.resample(acualTimes: times, desiredTimes: desiredTimes, metric: metricData);
    print(desiredMetrics)

上記の例では、次のように出力されます。

[4.0, 3.23076923076923, 5.33333333333333, 6.66666666666667, 4.75, 4.61538461538461, 5.90909090909091, 5.0, 2.66666666666667, 4.72727272727273, 2.0]
于 2015-09-27T06:32:40.400 に答える