//
//  SMUGRealMatrix.h
//  Capo
//
//  Created by Christopher Liscio on 11/19/09.
//  Copyright 2009 SuperMegaUltraGroovy. All rights reserved.
//

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

@interface SMUGRealMatrix : NSObject <NSCopying, NSCoding> {
    SMUGRealVector *mVector;
    uint64_t mRows;
    uint64_t mColumns;
}

- (id)initWithRows:(uint64_t)rows columns:(uint64_t)cols;
- (id)initWithRealVector:(SMUGRealVector*)realVector rows:(uint64_t)rows columns:(uint64_t)cols;
- (id)initWithRealVectorNoCopy:(SMUGRealVector*)realVector rows:(uint64_t)rows columns:(uint64_t)cols;
+ (instancetype)onesWithRows:(uint64_t)rows columns:(uint64_t)cols;

#pragma mark Accessors
@property (readonly,assign) float* components;
@property (readonly,assign) uint64_t rows;
@property (readonly,assign) uint64_t columns;
@property (readonly,assign) SMUGRealVector *underlyingVector;

- (void)setComponent:(float)c atRow:(uint64_t)row column:(uint64_t)col;
- (float)componentAtRow:(uint64_t)row column:(uint64_t)col;

#pragma mark Indexed Accessors

- (id)objectAtIndexedSubscript:(NSUInteger)index;

#pragma mark Operations

-(SMUGRealMatrix *)transposedCopy;

// Solve Ax=b. Returns the vector x;
- (SMUGRealVector*)solutionWith_b:(SMUGRealVector*)b;

- (SMUGRealVector *)realVectorMultipliedByVector:(SMUGRealVector *)inVector;
- (SMUGRealMatrix *)realMatrixMultipliedByMatrix:(SMUGRealMatrix *)inMatrix;

- (void)pointwiseMultiplyBy:(SMUGRealMatrix *)inMatrix;
- (void)add:(SMUGRealMatrix*)inMatrix;
- (void)subtract:(SMUGRealMatrix*)inMatrix;

/*! Returns the determinant of the matrix. Assumed to be square.
 */
- (float)determinant;

/*! Returns the inverse of the matrix.
 */
- (SMUGRealMatrix *)inverse;

/*! Generates a replicated version of the input matrix.
 * \param inRows Number of rows to replicate
 * \param inColumns Number of columns to replicate
 * \returns A replicated version of the input matrix of size self.rows * inRows x self.columns * inColumns
 */
- (SMUGRealMatrix *)repmatCopyWithRows:(uint64_t)inRows columns:(uint64_t)inColumns;

@end
