iPhone行列計算

行列をランダムに表示して計算結果を出すようなiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです。

サンプルコード

#import “ViewController.h”

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *matA;

@property (nonatomic, strong) NSMutableArray *matB;

@end

@implementation ViewController

– (void)viewDidAppear:(BOOL)animated

{

    self.view.backgroundColor = [UIColor greenColor];

    

    [self setupMatrix];

    

    for (int i=0; i<2; i++) {

        UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

        [btn setTitle:i ? @”=” : @”⋅” forState:UIControlStateNormal];

        btn.titleLabel.font = [UIFont systemFontOfSize:60];

        [btn sizeToFit];

        btn.center = CGPointMake(150 + 160*i, 150);

        [self.view addSubview:btn];

        

        [btn addTarget:self action:@selector(calc) forControlEvents:UIControlEventTouchUpInside];

    }

    

    UIButton *resetBtn = [UIButton buttonWithType:UIButtonTypeSystem];

    [resetBtn setTitle:@”→” forState:UIControlStateNormal];

    resetBtn.titleLabel.font = [UIFont systemFontOfSize:40];

    [resetBtn sizeToFit];

    resetBtn.center = CGPointMake(CGRectGetMaxX(self.view.bounds) – 50, 280);

    [self.view addSubview:resetBtn];

    

    [resetBtn addTarget:self action:@selector(reset) forControlEvents:UIControlEventTouchUpInside];

}

– (void)setupMatrix

{

    self.matA = [self createRandomMatSize:4];

    CALayer *matALayer = [self showMatrix:self.matA w:25];

    matALayer.position = CGPointMake(80, 160);

    [self.view.layer addSublayer:matALayer];

    

    self.matB = [self createRandomMatSize:4];

    CALayer *matBLayer = [self showMatrix:self.matB w:25];

    matBLayer.position = CGPointMake(220, 160);

    [self.view.layer addSublayer:matBLayer];

}

– (CALayer *)showMatrix:(NSMutableArray*)mat w:(float)w

{

    CALayer *layer = [CALayer layer];

    layer.name = @”matrix”;

    layer.frame = CGRectMake(0, 0, w * mat.count, w * mat.count);

    for (int i=0; i<mat.count; i++) {

        for (int j=0; j<mat.count; j++) {

            CATextLayer *t = [CATextLayer layer];

            t.frame = CGRectMake(0, 0, w, w);

            t.string = [mat[i][j] stringValue];

            t.fontSize = 18;

            t.alignmentMode = kCAAlignmentCenter;

            t.foregroundColor = [UIColor whiteColor].CGColor;

            t.position = CGPointMake(j*w + w/2.0, i*w + w/2.0);

            [layer addSublayer:t];

        }

    }

    return layer;

}

– (void)calc

{

    NSMutableArray *matC = [self squareMatrixMultiplyA:self.matA B:self.matB];

    CALayer *matCLayer = [self showMatrix:matC w:40];

    matCLayer.position = CGPointMake(420, 160);

    [self.view.layer addSublayer:matCLayer];

    

}

– (void)reset

{

    NSPredicate *pred = [NSPredicate predicateWithFormat:@”name == %@”, @”matrix”];

    [[self.view.layer.sublayers filteredArrayUsingPredicate:pred] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        [obj removeFromSuperlayer];

    }];

    

    [self setupMatrix];

}

– (NSMutableArray *)createRandomMatSize:(int)size

{

    NSMutableArray *mat = [NSMutableArray arrayWithCapacity:size];

    for (int i=0; i<size; i++) {

        mat[i] = [NSMutableArray arrayWithCapacity:size];

        for (int j=0; j<size; j++) {

            mat[i][j] = @(arc4random() % 10);

        }

        

    }

    return mat;

}

– (NSMutableArray *)squareMatrixMultiplyA:(NSMutableArray*)matA B:(NSMutableArray*)matB

{

    NSUInteger n = matA.count;

    NSMutableArray *matC = [NSMutableArray arrayWithCapacity:n];

    

    for (int i=0; i<n; i++) {

        matC[i] = [NSMutableArray arrayWithCapacity:n];

        for (int j=0; j<n; j++) {

            matC[i][j] = @(0);

            for (int k=0; k<n; k++) {

                matC[i][j] = @([matC[i][j] floatValue] + [matA[i][k] floatValue] * [matB[k][j] floatValue]);

            }

        }

    }

    

    return matC;

}

@end