#import <Foundation/Foundation.h>

@class SMUGComplexVector;

@interface SMUGRealVector : NSObject <NSCopying,NSCoding>
{
    void *mBytes;
    uint64_t mByteLength;
    BOOL mFreeWhenDone;
}

#pragma mark Initializers
- (id)initWithLength:(uint64_t)N;
- (id)initWithData:(NSData*)data;
- (id)initWithBytesNoCopy:(float*)inBytes length:(uint64_t)inLength;

#pragma mark Convenience Constructors
+ (id)realVectorWithLength:(uint64_t)N;
+ (id)realVectorWithComponents:(uint64_t)N,...;
+ (id)realVectorWithData:(NSData*)data;
+ (id)realVectorWithBytesNoCopy:(float*)inBytes length:(uint64_t)inLength;
+ (id)realVectorWithContentsOfMappedFile:(NSString*)path;

#pragma mark Specialized Convenience Constructors
+ (id)onesWithLength:(uint64_t)N;
+ (id)realVectorWithIntegersRangingFrom:(int64_t)begin 
                                     to:(int64_t)end;

#pragma mark Serialization
- (void)writeToFile:(NSString*)path;

#pragma mark Accessors
- (uint64_t)length;
- (float*)components NS_RETURNS_INNER_POINTER;
- (void)setComponent:(float)val atIndex:(uint64_t)index;
- (float)componentAtIndex:(uint64_t)index;

#pragma mark Indexed Accessors
- (id)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject:(id)inObject atIndexedSubscript:(NSUInteger)index;

#pragma mark Range Operations
- (SMUGRealVector*)realVectorInRange:(NSRange)range;
- (SMUGRealVector*)realVectorInRangeNoCopy:(NSRange)inRange;
- (void)replaceComponentsInRange:(NSRange)range withFloats:(float*)data;
- (void)replaceComponentsInRange:(NSRange)range withRealVector:(SMUGRealVector*)floatData;

#pragma mark Resizing
- (void)setLength:(uint64_t)N;
- (void)increaseLengthBy:(uint64_t)N;
- (void)appendVector:(SMUGRealVector*)v;
- (void)appendComponent:(float)c;

#pragma mark Manipulation Routines
- (void)reverse;
- (void)circularShiftBy:(int)amount;
- (void)overlapAddRealVector:(SMUGRealVector*)inVector atComponent:(uint64_t)inStartIndex;

#pragma mark Minimum/Maximum
- (void)getMinimum:(float*)min location:(uint64_t*)loc;
- (void)getMaximum:(float*)max location:(uint64_t*)loc;
- (void)getMaximumMagnitude:(float*)max location:(uint64_t*)loc;
- (void)getRMSMaximum:(float*)max location:(uint64_t*)loc;

#pragma mark Basic Math
- (void)add:(SMUGRealVector*)x;
- (void)subtract:(SMUGRealVector*)x;
- (void)scaleBy:(float)scalar;
- (void)divideByScalar:(float)inScalar;
- (void)multiplyBy:(SMUGRealVector*)x;
- (void)divideBy:(SMUGRealVector*)x;

#pragma mark Intermediate Math
- (void)square;
- (void)sqrt;
- (void)invert;
- (void)normalize;

#pragma mark Euclidean Norm
- (float)sumOfElementSquares;
- (float)norm;
- (float)dotProductWithVector:(SMUGRealVector *)inVector;

#pragma mark Summation/Averaging
- (float)cumsum;
- (void)integrate;
- (float)RMSAverage;

#pragma mark Combinations of Vectors
+ (SMUGRealVector*)sumOfVectors:(NSArray*)vectors;
+ (SMUGRealVector*)differenceOfVectors:(NSArray*)vectors;
+ (SMUGRealVector*)RMSAverageOfVectors:(NSArray*)vectors;
+ (SMUGRealVector*)averageOfVectors:(NSArray*)vectors;

#pragma mark Downsample/Upsample
- (void)downsampleBy:(uint64_t)n withOffset:(uint64_t)offset;
- (void)upsampleBy:(uint64_t)n;

#pragma mark Windowing
+ (SMUGRealVector*)realVectorWithHammingWindowOfLength:(uint64_t)inLength;
+ (SMUGRealVector*)realVectorWithHanningWindowOfLength:(uint64_t)inLength;

@end


