Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

AdunDataMatrix.m

/*
   Project: Adun

   Copyright (C) 2006 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   Created: 2005-06-02 15:34:11 +0200 by michael johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include "AdunKernel/AdunDataMatrix.h"

00027 @implementation AdDataMatrix

00029 + (AdDataMatrix*) matrixFromGSLVector: (gsl_vector*) aVector
{
      int i, j;
      AdDataMatrix* newMatrix;

      newMatrix = [[AdDataMatrix alloc] initWithRows: aVector->size
                  columns: 1];

      for(i=0; i<(int)aVector->size; i++)
            for(j=0; j<1; j++)
                  [newMatrix setElementAtRow: i
                        column: j
                        withValue: [NSNumber 
                              numberWithDouble: gsl_vector_get(aVector, i)]];

      return [newMatrix autorelease];
}

00047 + (AdDataMatrix*) matrixFromGSLMatrix: (gsl_matrix*) aMatrix
{
      int i, j;
      AdDataMatrix* newMatrix;

      newMatrix = [[AdDataMatrix alloc] initWithRows: aMatrix->size1
                  columns: aMatrix->size2];

      for(i=0; i<(int)aMatrix->size1; i++)
            for(j=0; j<(int)aMatrix->size2; j++)
                  [newMatrix setElementAtRow: i
                        column: j
                        withValue: [NSNumber 
                              numberWithDouble: gsl_matrix_get(aMatrix, i, j)]];

      return [newMatrix autorelease];
}

+ (AdDataMatrix*) matrixFromADMatrix: (AdMatrix*) aMatrix
{
      int i, j;
      AdDataMatrix* newMatrix;

      newMatrix = [[AdDataMatrix alloc] initWithRows: aMatrix->no_rows
                  columns: aMatrix->no_columns];

      for(i=0; i<aMatrix->no_rows; i++)
            for(j=0; j<aMatrix->no_columns; j++)
                  [newMatrix setElementAtRow: i
                        column: j
                        withValue: [NSNumber 
                              numberWithDouble: aMatrix->matrix[i][j]]];

      return [newMatrix autorelease];
}

00083 - (AdDataMatrix*) initWithRows: (int) rowValue columns: (int) columnValue;
{
      int i, j;
      NSMutableArray* row;

      if(self = [super init])
      {
            numberOfRows = rowValue;
            numberOfColumns = columnValue;

            matrix = [NSMutableArray new];

            for(i=0; i<numberOfRows; i++)
            {
                  row = [NSMutableArray array];
                  for(j=0; j<numberOfColumns; j++)
                        [row addObject: [NSNumber numberWithDouble: 0.0]];

                  [matrix addObject: row];
            }
            columnHeaders = nil;
            name = ;
      }

      return self;
}

- (id) init
{
      return [self initWithRows: 0 columns: 0];
}

- (void) dealloc
{
      [matrix release];
      [columnHeaders release];
      [name release];
      [super dealloc];
}


/****************

Setting Elements

******************/

00130 - (void) setElementAtRow: (int) rowIndex 
      column: (int) columnIndex 
      withValue: (NSNumber*) value;
{
      [[matrix objectAtIndex: rowIndex] replaceObjectAtIndex: columnIndex
            withObject: value];
}

00138 - (NSNumber*) elementAtRow: (int) rowIndex
       column: (int) columnIndex;
{
      return [[matrix objectAtIndex: rowIndex] objectAtIndex: columnIndex];
}

00144 - (NSArray*) matrixRows
{
      return matrix;
}

- (void) setMatrixRows: (NSMutableArray*) rowArray
{
      [matrix release];
      matrix = [rowArray retain];
}

00155 - (void) extendMatrixWithRow: (NSArray*) anArray
{
      //have to copy the numberOfRows elements into the matrix
      //since who knows whats going to happen to the array later
      //(it may be mutable)   

      if((int)[anArray count] == numberOfColumns)
      {     
            [matrix addObject: [NSMutableArray arrayWithArray: anArray]];
            numberOfRows++;
      }
      else if(numberOfColumns == 0) 
      {
            numberOfColumns = [anArray count];
            [matrix addObject: [NSMutableArray arrayWithArray: anArray]];
            numberOfRows++;
      }
      else
      {
            [NSException raise: NSInvalidArgumentException
                  format: @"Incorrect number of elements in array (%d, %d)",
                  [anArray count], numberOfColumns];  
      }
}     

00180 - (void) extendMatrixWithColumn: (NSArray*) anArray
{
      int i;

      //check if its the right size

      if((int)[anArray count] != numberOfRows)
            [NSException raise: NSInvalidArgumentException
                  format: @"Incorrect number of elements in array (%d, %d)",
                  [anArray count], numberOfRows];     

      for(i=0; i<numberOfRows; i++)
            [[matrix objectAtIndex: i] addObject: 
                        [[anArray objectAtIndex: i] copy]];

      numberOfColumns++; 

      //expand columnHeaders if they exist

      if(columnHeaders != nil)
            [columnHeaders addObject: @""];
}


00204 - (void) removeRowsWithIndexes: (NSIndexSet*) indexSet
{
      int* buffer;

      //maybe one day this will be implemented - only in Cocoa for now
      //[matrix removeObjectsWithIndexes: indexSet];

      buffer = (int*)malloc([indexSet count]*sizeof(int));
      [indexSet getIndexes: buffer 
                  maxCount: [indexSet count]
                  inIndexRange: NULL];
      [matrix     removeObjectsFromIndices: buffer numIndices: [indexSet count]];
      free(buffer); 

      numberOfRows = [matrix count];
}

/**
\todo Add validation
\note maybe we should copy this matrix?
*/

00226 - (void) extendMatrixWithMatrix: (AdDataMatrix*) extendingMatrix
{
      NSEnumerator* rowEnum;
      id row;

      //if we are adding this to an empty matrix numberOfColumns will be 0
      //need to give it the correct value

      if(numberOfColumns == 0)
            numberOfColumns = [extendingMatrix numberOfColumns];

      rowEnum = [[extendingMatrix matrixRows] objectEnumerator];

      while(row = [rowEnum nextObject])
            [matrix addObject: [NSMutableArray arrayWithArray: row]];
      
      numberOfRows += [extendingMatrix numberOfRows];
}

00245 - (void) printMatrix
{
      int i;

      for(i=0; i<numberOfRows; i++)
            NSLog(@"%@\n", [matrix objectAtIndex: i]);
}           

00253 - (BOOL) writeMatrixToFile: (NSString*) filename
{
      int i;
      FILE* file_p;

      file_p = fopen([filename cString], "w");
      
      if(file_p == NULL)
            return NO;

      if(columnHeaders != nil)
            GSPrintf(file_p, @"%@\n", 
                  [columnHeaders componentsJoinedByString: @" "]);

      for(i=0;i<numberOfRows; i++)
            GSPrintf(file_p, @"%@\n", 
                  [[matrix objectAtIndex: i] 
                  componentsJoinedByString: @" "]);

      fclose(file_p);

      return YES;
}

00277 - (NSMutableArray*) column: (int) columnIndex
{
      int i;
      NSMutableArray* columnCopy;

      columnCopy = [NSMutableArray arrayWithCapacity:1];

      for(i = 0; i<numberOfRows; i++)
            [columnCopy addObject: 
                  [[[matrix objectAtIndex: i] 
                  objectAtIndex: columnIndex] copy]];

      return columnCopy;
}

00292 - (int) numberOfRows
{
      return numberOfRows;
}

00297 - (int) numberOfColumns
{
      return numberOfColumns;
}

/*******
NSCoding Methods
********/

- (id) initWithCoder: (NSCoder*) decoder
{     
      int i,j;
      int matrixElements;
      int length, count;
      double *matrixStore;
      NSMutableArray* matrixRow;
      NSNumber *element, *number;

      if([decoder allowsKeyedCoding])
      {
            matrix = [NSMutableArray new];
            numberOfRows = [decoder decodeIntForKey: @"Rows"];
            numberOfColumns = [decoder decodeIntForKey: @"Columns"];
            matrixStore = (double*)[decoder decodeBytesForKey: @"Matrix"
                              returnedLength: &length];
            matrixElements = length/sizeof(double);
            for(i=0, count=0; i<numberOfRows; i++)
            {
                  matrixRow = [NSMutableArray arrayWithCapacity: 1];
                  for(j=0; j<numberOfColumns; j++)
                  {
                        element = [NSNumber numberWithDouble: matrixStore];
                        [matrixRow addObject: element];
                        count++;
                  }
                  [matrix addObject: matrixRow];
            }

            columnHeaders = [decoder decodeObjectForKey: @"ColumnHeaders"];
            [columnHeaders retain];
            name = [decoder decodeObjectForKey: @"Name"];
            [name retain];
      }
      else
      {     
            matrix = [NSMutableArray new];
            matrixStore = (double*)[decoder decodeBytesWithReturnedLength: &length];
            number = [decoder decodeObject];
            numberOfRows = [number intValue];
            number = [decoder decodeObject];
            numberOfColumns = [number intValue];
            matrixElements = length/sizeof(double);
            for(i=0, count=0; i<numberOfRows; i++)
            {
                  matrixRow = [NSMutableArray arrayWithCapacity: 1];
                  for(j=0; j<numberOfColumns; j++)
                  {
                        element = [NSNumber numberWithDouble: matrixStore];
                        [matrixRow addObject: element];
                        count++;
                  }
                  [matrix addObject: matrixRow];
            }

            columnHeaders = [decoder decodeObject];
            if([columnHeaders isEqual:@"NoHeaders"])
                  columnHeaders = nil;
            else  
                  [columnHeaders retain];
                  
            name = [decoder decodeObject];
            [name retain];
      }

      return self;
}

//probably should encode types of each number as well

- (void) encodeWithCoder: (NSCoder*) encoder
{
      int i, j, bytesLength, count;
      double* matrixStore;
      id array;

      if([encoder allowsKeyedCoding])
      {
            //FIXME: Assuming the matrix only stores numbers.
            bytesLength = numberOfRows*numberOfColumns*sizeof(double);
            matrixStore = (double*)malloc(numberOfRows*numberOfColumns*sizeof(double));
      
            for(i=0, count=0; i<numberOfRows; i++)
                  for(j=0; j<numberOfColumns; j++)
                  {
                        matrixStore = [[[matrix objectAtIndex: i] objectAtIndex: j] doubleValue]; 
                        count++;
                  }
            
            [encoder encodeBytes: (uint8_t*)matrixStore length: bytesLength forKey: @"Matrix"];
            [encoder encodeInt: numberOfRows forKey: @"Rows"];
            [encoder encodeInt: numberOfColumns forKey: @"Columns"];

            if(columnHeaders != nil)
            {
                  NSLog(@"Encoding headers %@", columnHeaders);
                  [encoder encodeObject: columnHeaders forKey: @"ColumnHeaders"];
            }     

            if(name != nil)
            {
                  [encoder encodeObject: name forKey: @"Name"];
                  NSLog(@"Encoding name %@", name);
            }     

            free(matrixStore);
      }
      else
      {
            bytesLength = numberOfRows*numberOfColumns*sizeof(double);
            matrixStore = (double*)malloc(numberOfRows*numberOfColumns*sizeof(double));
      
            for(i=0, count=0; i<numberOfRows; i++)
                  for(j=0; j<numberOfColumns; j++)
                  {
                        matrixStore = [[[matrix objectAtIndex: i] objectAtIndex: j] doubleValue]; 
                        count++;
                  }
            
            [encoder encodeBytes: (uint8_t*)matrixStore length: bytesLength];
            [encoder encodeObject: [NSNumber numberWithInt: numberOfRows]];
            [encoder encodeObject: [NSNumber numberWithInt: numberOfColumns]];

            //[encoder encodeObject: matrix];
            if(columnHeaders != nil)
                  [encoder encodeObject: columnHeaders];
            else
                  [encoder encodeObject: @"NoHeaders"];
                  
            [encoder encodeObject: name];
      }
}

00439 - (void) setColumnHeaders: (NSArray*) anArray
{
      id holder;

      if((int)[anArray count] != numberOfColumns)
            [NSException raise: NSInvalidArgumentException
                  format: @"Incorrect number of elements in array (%d, %d)",
                  [anArray count], numberOfRows];     

      if(anArray != columnHeaders)
      {
            holder = columnHeaders;
            columnHeaders = [anArray mutableCopy];
            [holder release];
      }     
}

00456 - (NSArray*) columnHeaders
{
      return columnHeaders;
}

00461 - (void) setName: (NSString*) aString
{
      id holder;

      holder = name;
      name = [aString retain];
      [holder release];
}

00470 - (NSString*) name
{
      return name;
}

@end

Generated by  Doxygen 1.6.0   Back to index