//
//  SMUGRealDoubleVector.h
//  SMUGMath
//
//  Created by Christopher Liscio on 1/18/11.
//  Copyright 2011 SuperMegaUltraGroovy. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SMUGRealVector.h"

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

#pragma mark Initializers

- (id)initWithLength:(uint64_t)N;
- (id)initWithBytesNoCopy:(double*)inBytes length:(uint64_t)inLength;

#pragma mark Convenience Constructors

+ (id)realDoubleVectorWithOnes:(uint64_t)N;
+ (id)realDoubleVectorWithLength:(uint64_t)N;
+ (id)realDoubleVectorWithComponents:(uint64_t)N,...;
+ (id)realDoubleVectorWithBytesNoCopy:(double*)inBytes length:(uint64_t)inLength;
+ (instancetype)realDoubleVectorWithContentsOfRealVector:(SMUGRealVector *)inVector;

#pragma mark Ranged Accessors

- (SMUGRealDoubleVector *)realDoubleVectorInRange:(NSRange)range;
- (SMUGRealDoubleVector *)realDoubleVectorInRangeNoCopy:(NSRange)inRange;

#pragma mark Accessors

- (uint64_t)length;
- (void)setLength:(uint64_t)N;

- (double*)components;
- (void)setComponent:(double)val atIndex:(uint64_t)index;
- (double)componentAtIndex:(uint64_t)index;

#pragma mark Indexed Accessors

- (id)objectAtIndexedSubscript:(NSUInteger)index;
- (void)setObject:(id)inObject atIndexedSubscript:(NSUInteger)index;

#pragma mark Manipulation

- (void)circularShiftBy:(int)amount;

#pragma mark Range Operations

- (void)replaceComponentsInRange:(NSRange)range withDoubles:(double*)data;
- (void)replaceComponentsInRange:(NSRange)range withRealDoubleVector:(SMUGRealDoubleVector*)v;

#pragma mark Minimum/Maximum

- (void)getMaximum:(double*)oMax location:(uint64_t*)oLoc;

#pragma mark Basic Math

- (void)subtract:(SMUGRealDoubleVector *)inVector;
- (void)multiplyBy:(SMUGRealDoubleVector*)x;
- (void)scaleBy:(double)scalar;
- (void)divideByScalar:(double)scalar;

- (void)sqrt;
- (double)dotProductWithVector:(SMUGRealDoubleVector *)inVector;

#pragma mark Other Math

- (double)sumOfElementSquares;
- (double)norm;

#pragma mark Conversion

- (SMUGRealVector*)realVectorCopy;
- (instancetype)initWithContentsOfRealVector:(SMUGRealVector *)inVector;

@end

@interface SMUGRealVector(SMUGRealDoubleVectorSupport)
- (id)initWithContentsOfRealDoubleVector:(SMUGRealDoubleVector *)inVector;
@end
