Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C中的移动平均_Objective C_Nsarray_Moving Average - Fatal编程技术网

Objective-C中的移动平均

Objective-C中的移动平均,objective-c,nsarray,moving-average,Objective C,Nsarray,Moving Average,我试图找出如何从麦克风接收到的特定值中获得移动平均值。我有一个frequencychangedwhithvalue函数调用我的测量方法。这意味着我得到的频率值在一秒钟内最多变化10次。我现在感兴趣的是如何从所有这些变化的值中得出一个平均数。我该怎么做 代码 我有一个: // MovingAverage.h @interface MovingAverage : NSObject @property (readonly, nonatomic) float movingAverage; @prop

我试图找出如何从麦克风接收到的特定值中获得移动平均值。我有一个
frequencychangedwhithvalue
函数调用我的测量方法。这意味着我得到的频率值在一秒钟内最多变化10次。我现在感兴趣的是如何从所有这些变化的值中得出一个平均数。我该怎么做

代码 我有一个:

// MovingAverage.h

@interface MovingAverage : NSObject

@property (readonly, nonatomic) float movingAverage;
@property (readonly, nonatomic) float cumulativeAverage;

- (id)initWithPeriod:(NSUInteger)period;
- (void)addDatum:(NSNumber *)datum;

@end


// MovingAverage.m

#import "MovingAverage.h"

@interface MovingAverage ()
@property (strong, nonatomic) NSMutableArray *queue;
@property (assign, nonatomic) NSUInteger period;
@property (assign, nonatomic) NSUInteger count;
@property (assign, nonatomic) float movingAverage;
@property (assign, nonatomic) float cumulativeAverage;
@end

@implementation MovingAverage

- (id)initWithPeriod:(NSUInteger)period {

    self = [self init];
    if (self) {
        _period = period;
        // with arc
        _queue = [NSMutableArray array];
        // without arc
        _queue = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)addDatum:(NSNumber *)datum {

    [self.queue insertObject:datum atIndex:0];

    float removed = 0;
    float datumf = [datum floatValue];

    if (self.queue.count > self.period) {
        removed = [[self.queue lastObject] floatValue];
        [self.queue removeLastObject];
    }

    self.movingAverage = self.movingAverage - (removed / self.period) + (datumf / self.period);

    // compute the cumulative average
    self.cumulativeAverage = self.cumulativeAverage + (datumf - self.cumulativeAverage) / ++self.count;
}

// if non-ARC
- (void)dealloc {
    [_queue release];
    [super dealloc];
}

@end

只需保存一个数组和元素总数即可。由于它是移动平均数,因此元素计数可能高于数组元素的总计数,您需要计算此计数的剩余部分

例如:

@property (nonatomic,retain) NSMutableArray* elements;   
@property (nonatomic,assign) NSUInteger lastIndex;
@property (nonatomic,assign) double average;
初始化元素并使其保持N个值(长值的NSNumber)。您应该能够通过调用以下简单方法来更改平均值:

- (void) changeAverage: (long) newValue
{
    NSUInteger index= (++lastIndex) % elements.count;
    NSNumber* oldValue= elements[index]; // same as [elements objectAtIndex: index];
    average+= (double)newValue/elements.count -  (double)[oldValue longValue]/elements.count;   
    // The cast is to don't lose the decimal precision while dividing these numbers.
    [elements replaceObjectAtIndex: index withObject: @(newValue)];  
    // @(newValue) is the same as [NSNumber numberWithLong: newValue];
}

在这里可以看到一个类似的问题:因为您没有使用ARC,所以在这种情况下pool=nil是无用的。通常,如果没有相反的理由,你会使用。代码非常简单,不需要从某个地方抄袭它。@RamyAlZuhouri-但通常都是很好的做法。就我看来,它更多的是一种冗余,而不是一种好的做法。我认为您可能需要在构造函数中的某个地方初始化队列(NSMutableArray)。这一点很好。我在getter中有一个懒惰的init,我没有粘贴到这里。将添加到init。好的,但对于非Arc,您正在释放dealloc中的队列(这对我来说很好),但在创建时它实际上不会被保留。您可能需要考虑:_queue=[[NSMutableArray alloc]initWithCapacity:_period];而不是_queue=[NSMutableArray]再次右击。我忘了底部有非圆弧选项。
- (void) changeAverage: (long) newValue
{
    NSUInteger index= (++lastIndex) % elements.count;
    NSNumber* oldValue= elements[index]; // same as [elements objectAtIndex: index];
    average+= (double)newValue/elements.count -  (double)[oldValue longValue]/elements.count;   
    // The cast is to don't lose the decimal precision while dividing these numbers.
    [elements replaceObjectAtIndex: index withObject: @(newValue)];  
    // @(newValue) is the same as [NSNumber numberWithLong: newValue];
}