mardi 28 juin 2016

Objective-C XCTAssertEqualObjects unit test fails even though objects are identical

I'm developing an artificial neural net in objective c, so I've written some methods for matrix-vector arithmetic. For example, below is the code for the outer product calculation. The code is working fine and returns the desired results, but my unit test fails when comparing the method-returned NSMutableArray object to the one created in the unit test. I've been lost on this for a few days now. Does anyone know why XCTAssertEqualObjects fails despite the fact that the objects seem identical?

Here is the relevant code to return the outer product of 2 vectors (NSArrays) in MLNNeuralNet.m:

-(NSMutableArray *)outerProduct:(NSArray *)matrix1 by:(NSArray *)matrix2 {

/*Tensor Product of 2 vectors treated as column and row matrices, respectively*/

/*Example: if matrix1 is @[2, 4, 6] and matrix2 @[3, 4, 5], then calculation is:
 [2 * 3, 2 * 4, 2 * 5], [4 * 3, etc...]
 and result is:
 @[@[6, 8, 10], @[12, 16, 20], @[18, 24, 30]]
 */

NSMutableArray *result = [[NSMutableArray alloc] init];

for (int i = 0; i < [matrix1 count]; i++) {
    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    for (int j = 0; j < [matrix2 count]; j++) {
        double product = [[matrix1 objectAtIndex:i] doubleValue] * [[matrix2 objectAtIndex:j] doubleValue];
        [tempArray addObject:@(product)];
    }
    [result addObject:tempArray];
}

return result;
}

And here is the code for the unit test:

@interface MLNNeuralNetTests : XCTestCase

@property (strong, nonatomic) MLNNeuralNet *neuralNet;

@end

@implementation MLNNeuralNetTests

- (void)setUp {
    [super setUp];
    _neuralNet = [[MLNNeuralNet alloc] init];
}

-(void)testOuterProduct {

NSMutableArray *matrix1 = [[NSMutableArray alloc] initWithArray:@[@(1.0), @(2.0), @(3.0)]];
NSMutableArray *matrix2 = [[NSMutableArray alloc] initWithArray:@[@(4.2), @(5.2), @(6.2)]];

NSMutableArray *layer1 = [[NSMutableArray alloc] initWithArray:@[@(4.2), @(5.2), @(6.2)]];
NSMutableArray *layer2 = [[NSMutableArray alloc] initWithArray:@[@(8.4), @(10.4), @(12.4)]];
NSMutableArray *layer3 = [[NSMutableArray alloc] initWithArray:@[@(12.6), @(15.6), @(18.6)]];
NSMutableArray *correctMatrix = [[NSMutableArray alloc]
                                 initWithArray:@[layer1, layer2, layer3]];

NSMutableArray *testMatrix = [self.neuralNet outerProduct:matrix1 by:matrix2];

XCTAssertEqualObjects(correctMatrix, testMatrix, @"Matrix outer product failed");
}

And here is the error I'm getting:

I thought it might be due to my creating the NSNumber literals in the unit test version like @(4.2) etc...

so I tried first creating doubles and then wrapping in NSNumber like this:

double number1 = 4.2;
NSMutableArray *layer1 = [[NSMutableArray alloc] initWithArray:@[@(number1), etc...

but this also did not work.

Am I missing something here?

Aucun commentaire:

Enregistrer un commentaire