Objective-C 中的矩阵乘法

发布于 2025-01-04 02:43:31 字数 5072 浏览 1 评论 0原文

这些是我在项目中进行矩阵计算的一些代码。
它们是两个类方法和一个实例方法,用于创建矩阵并进行矩阵乘法运算。
矩阵乘法的方法效果不好,结果是错误的。

+ (NSMutableArray *)arrayOfWidth:(NSInteger)width andHeight:(NSInteger)height {
    return [[self alloc] initWithWidth:width andHeight:height];
}

- (id)initWithWidth:(NSInteger)width andHeight:(NSInteger)height {
    if((self = [self initWithCapacity:height])) {
        for(int i = 0; i < height; i++) {
            NSMutableArray *inner = [[NSMutableArray alloc] initWithCapacity:width];
            [self addObject:inner];
        }
    }
    return self;
}

+ (NSMutableArray *)matrixA:(NSMutableArray *)matrixA multiplyMatrixB:(NSMutableArray *)matrixB {
    int aRow = [matrixA count];
    int aColumn = [[matrixA objectAtIndex:0] count];
    int bRow = [matrixB count];
    int bColumn = [[matrixB objectAtIndex:0] count];
    NSMutableArray *newArray = [NSMutableArray arrayOfWidth:aRow andHeight:bColumn];

    for (int i = 0; i < aRow; i++) {
        for (int j = 0; j < bColumn; j++) {
            double sum = 0.0;
            for (int k = 0; k < aColumn; k++) {
                NSMutableArray *innerA = [matrixA objectAtIndex:i];
                double numA = [[innerA objectAtIndex:k] doubleValue];
                NSMutableArray * innerB = [matrixB objectAtIndex:k];
                double numB = [[innerB objectAtIndex:j] doubleValue];
                sum += numA * numB; 
            }
            NSNumber *result = [NSNumber numberWithDouble:sum];
            [[newArray objectAtIndex:i] insertObject:result atIndex:j];
        }
    }
    return newArray;
}

代码有问题吗? 我该如何解决它?


    //First, I create a array to hold the numbers
    NSNumber *num11 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num12 = [NSNumber numberWithDouble:1.0];
    NSNumber *num13 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num14 = [NSNumber numberWithDouble:2.0];
    NSNumber *num21 = [NSNumber numberWithDouble:-7.0];
    NSNumber *num22 = [NSNumber numberWithDouble:0.0];
    NSNumber *num23 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num24 = [NSNumber numberWithDouble:-4.0];
    NSNumber *num31 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num32 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num33 = [NSNumber numberWithDouble:0.0];
    NSNumber *num34 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num41 = [NSNumber numberWithDouble:-3.0];
    NSNumber *num42 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num43 = [NSNumber numberWithDouble:0.0];
    NSNumber *num44 = [NSNumber numberWithDouble:-3.0];

    NSMutableArray *temp = [NSMutableArray arrayWithObjects:num11, num12, num13, num14, num21, num22, num23, num24, num31, num32, num33, num34, num41, num42, num43, num44, nil];

    //Second, I create the matrix and get the elements from that array 
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            double c = [[temp objectAtIndex:4*i+j] doubleValue];
            NSNumber *object = [NSNumber numberWithDouble:c];
            [[matrix objectAtIndex:i] insertObject:object atIndex:j];
        }
    }

    //Then, I do the multiplication for matrix and itself
    NSMutableArray *multiMatrix = [NSMutableArray matrixA:matrix multiplyMatrixB:matrix];

    //get all the elements from the multiMatrix
    double m11 = [[[multiMatrix objectAtIndex:0] objectAtIndex:0] doubleValue];
    double m12 = [[[multiMatrix objectAtIndex:0] objectAtIndex:1] doubleValue];
    double m13 = [[[multiMatrix objectAtIndex:0] objectAtIndex:2] doubleValue];
    double m14 = [[[multiMatrix objectAtIndex:0] objectAtIndex:3] doubleValue];

    double m21 = [[[multiMatrix objectAtIndex:1] objectAtIndex:0] doubleValue];
    double m22 = [[[multiMatrix objectAtIndex:1] objectAtIndex:1] doubleValue];
    double m23 = [[[multiMatrix objectAtIndex:1] objectAtIndex:2] doubleValue];
    double m24 = [[[multiMatrix objectAtIndex:1] objectAtIndex:3] doubleValue];

    double m31 = [[[multiMatrix objectAtIndex:2] objectAtIndex:0] doubleValue];
    double m32 = [[[multiMatrix objectAtIndex:2] objectAtIndex:1] doubleValue];
    double m33 = [[[multiMatrix objectAtIndex:2] objectAtIndex:2] doubleValue];
    double m34 = [[[multiMatrix objectAtIndex:2] objectAtIndex:3] doubleValue];

    double m41 = [[[multiMatrix objectAtIndex:3] objectAtIndex:0] doubleValue];
    double m42 = [[[multiMatrix objectAtIndex:3] objectAtIndex:1] doubleValue];
    double m43 = [[[multiMatrix objectAtIndex:3] objectAtIndex:2] doubleValue];
    double m44 = [[[multiMatrix objectAtIndex:3] objectAtIndex:3] doubleValue];

    //Or you can use the NSLog to check the result 
    NSString *lineOne = [NSString stringWithFormat:@"%f, %f, %f, %f", m11, m12, m13, m14];
    NSString *lineTwo= [NSString stringWithFormat:@"%f, %f, %f, %f", m21, m22, m23, m24];
    NSString *lineThree = [NSString stringWithFormat:@"%f, %f, %f, %f", m31, m32, m33, m34];
    NSString *lineFour = [NSString stringWithFormat:@"%f, %f, %f, %f", m41, m42, m43, m44];

@rooftop,这就是所有代码

These are some code that I carried in my project to do matrix computing.
They are two class methods and one instance method that for create matrices and do the matrix multiplication operation.
The method for matrics multiplication doesn't work well, the result from it is wrong.

+ (NSMutableArray *)arrayOfWidth:(NSInteger)width andHeight:(NSInteger)height {
    return [[self alloc] initWithWidth:width andHeight:height];
}

- (id)initWithWidth:(NSInteger)width andHeight:(NSInteger)height {
    if((self = [self initWithCapacity:height])) {
        for(int i = 0; i < height; i++) {
            NSMutableArray *inner = [[NSMutableArray alloc] initWithCapacity:width];
            [self addObject:inner];
        }
    }
    return self;
}

+ (NSMutableArray *)matrixA:(NSMutableArray *)matrixA multiplyMatrixB:(NSMutableArray *)matrixB {
    int aRow = [matrixA count];
    int aColumn = [[matrixA objectAtIndex:0] count];
    int bRow = [matrixB count];
    int bColumn = [[matrixB objectAtIndex:0] count];
    NSMutableArray *newArray = [NSMutableArray arrayOfWidth:aRow andHeight:bColumn];

    for (int i = 0; i < aRow; i++) {
        for (int j = 0; j < bColumn; j++) {
            double sum = 0.0;
            for (int k = 0; k < aColumn; k++) {
                NSMutableArray *innerA = [matrixA objectAtIndex:i];
                double numA = [[innerA objectAtIndex:k] doubleValue];
                NSMutableArray * innerB = [matrixB objectAtIndex:k];
                double numB = [[innerB objectAtIndex:j] doubleValue];
                sum += numA * numB; 
            }
            NSNumber *result = [NSNumber numberWithDouble:sum];
            [[newArray objectAtIndex:i] insertObject:result atIndex:j];
        }
    }
    return newArray;
}

Is there something wrong with the code?
And how can I fix it?


    //First, I create a array to hold the numbers
    NSNumber *num11 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num12 = [NSNumber numberWithDouble:1.0];
    NSNumber *num13 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num14 = [NSNumber numberWithDouble:2.0];
    NSNumber *num21 = [NSNumber numberWithDouble:-7.0];
    NSNumber *num22 = [NSNumber numberWithDouble:0.0];
    NSNumber *num23 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num24 = [NSNumber numberWithDouble:-4.0];
    NSNumber *num31 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num32 = [NSNumber numberWithDouble:-1.0];
    NSNumber *num33 = [NSNumber numberWithDouble:0.0];
    NSNumber *num34 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num41 = [NSNumber numberWithDouble:-3.0];
    NSNumber *num42 = [NSNumber numberWithDouble:-2.0];
    NSNumber *num43 = [NSNumber numberWithDouble:0.0];
    NSNumber *num44 = [NSNumber numberWithDouble:-3.0];

    NSMutableArray *temp = [NSMutableArray arrayWithObjects:num11, num12, num13, num14, num21, num22, num23, num24, num31, num32, num33, num34, num41, num42, num43, num44, nil];

    //Second, I create the matrix and get the elements from that array 
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            double c = [[temp objectAtIndex:4*i+j] doubleValue];
            NSNumber *object = [NSNumber numberWithDouble:c];
            [[matrix objectAtIndex:i] insertObject:object atIndex:j];
        }
    }

    //Then, I do the multiplication for matrix and itself
    NSMutableArray *multiMatrix = [NSMutableArray matrixA:matrix multiplyMatrixB:matrix];

    //get all the elements from the multiMatrix
    double m11 = [[[multiMatrix objectAtIndex:0] objectAtIndex:0] doubleValue];
    double m12 = [[[multiMatrix objectAtIndex:0] objectAtIndex:1] doubleValue];
    double m13 = [[[multiMatrix objectAtIndex:0] objectAtIndex:2] doubleValue];
    double m14 = [[[multiMatrix objectAtIndex:0] objectAtIndex:3] doubleValue];

    double m21 = [[[multiMatrix objectAtIndex:1] objectAtIndex:0] doubleValue];
    double m22 = [[[multiMatrix objectAtIndex:1] objectAtIndex:1] doubleValue];
    double m23 = [[[multiMatrix objectAtIndex:1] objectAtIndex:2] doubleValue];
    double m24 = [[[multiMatrix objectAtIndex:1] objectAtIndex:3] doubleValue];

    double m31 = [[[multiMatrix objectAtIndex:2] objectAtIndex:0] doubleValue];
    double m32 = [[[multiMatrix objectAtIndex:2] objectAtIndex:1] doubleValue];
    double m33 = [[[multiMatrix objectAtIndex:2] objectAtIndex:2] doubleValue];
    double m34 = [[[multiMatrix objectAtIndex:2] objectAtIndex:3] doubleValue];

    double m41 = [[[multiMatrix objectAtIndex:3] objectAtIndex:0] doubleValue];
    double m42 = [[[multiMatrix objectAtIndex:3] objectAtIndex:1] doubleValue];
    double m43 = [[[multiMatrix objectAtIndex:3] objectAtIndex:2] doubleValue];
    double m44 = [[[multiMatrix objectAtIndex:3] objectAtIndex:3] doubleValue];

    //Or you can use the NSLog to check the result 
    NSString *lineOne = [NSString stringWithFormat:@"%f, %f, %f, %f", m11, m12, m13, m14];
    NSString *lineTwo= [NSString stringWithFormat:@"%f, %f, %f, %f", m21, m22, m23, m24];
    NSString *lineThree = [NSString stringWithFormat:@"%f, %f, %f, %f", m31, m32, m33, m34];
    NSString *lineFour = [NSString stringWithFormat:@"%f, %f, %f, %f", m41, m42, m43, m44];

@rooftop, that's all the code

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微凉徒眸意 2025-01-11 02:43:31

如果您使用的是 iOS,您可能需要考虑 GLKit

If you're on iOS you might want to consider the matrix routines in GLKit

野の 2025-01-11 02:43:31

如果您熟悉 MATLAB 的向量运算(即使您不熟悉),我建议您查看 加速框架,它是一个针对数字信号处理的优化框架。

两大优势:

  • 他们已经实施了该操作。
  • 这是一种更有效的方法,但显然不适用于小矩阵,请参阅评论以获取更多详细信息。

这可能是您正在寻找的函数:

vDSP_mmul:执行两个矩阵的异位乘法;单精度。

void vDSP_mmul (
   float *__vDSP_a,
   vDSP_Stride __vDSP_aStride,
   float *__vDSP_b,
   vDSP_Stride __vDSP_bStride,
   float *__vDSP_c,
   vDSP_Stride __vDSP_cStride,
   vDSP_Length __vDSP_M,
   vDSP_Length __vDSP_N,
   vDSP_Length __vDSP_P
);
Parameters
__vDSP_a
Input matrix A.
__vDSP_aStride
The stride within __vDSP_a. For example if stride is 2, every second element is used.
__vDSP_b
Input matrix B.
__vDSP_bStride
The stride within __vDSP_b. For example if stride is 2, every second element is used.
__vDSP_c
The result matrix.
__vDSP_M
The number of rows in matrix A.
__vDSP_N
The number of columns in matrix B.
__vDSP_P
The number of columns in matrix A and the number of rows in matrix B.
Discussion
This function multiplies an M-by-P matrix (A) by a P-by-N matrix (B) and stores the results in an M-by-N matrix (C).

这将执行以下操作:

另一方面,如果需要自己编写方法,那么这篇文章对您根本没有帮助。

If you are familiar with MATLAB's vector operations (even if you are not), I would recommend you to check the Accelerate Framework, it is an optimized framework for digital signal processing.

Two great advantages:

  • They have that operation already implemented.
  • It's a more efficient way to do it, but apparently not for small matrixes, see the comments for further detail.

This is probably the function you are looking for:

vDSP_mmul: Performs an out-of-place multiplication of two matrices; single precision.

void vDSP_mmul (
   float *__vDSP_a,
   vDSP_Stride __vDSP_aStride,
   float *__vDSP_b,
   vDSP_Stride __vDSP_bStride,
   float *__vDSP_c,
   vDSP_Stride __vDSP_cStride,
   vDSP_Length __vDSP_M,
   vDSP_Length __vDSP_N,
   vDSP_Length __vDSP_P
);
Parameters
__vDSP_a
Input matrix A.
__vDSP_aStride
The stride within __vDSP_a. For example if stride is 2, every second element is used.
__vDSP_b
Input matrix B.
__vDSP_bStride
The stride within __vDSP_b. For example if stride is 2, every second element is used.
__vDSP_c
The result matrix.
__vDSP_M
The number of rows in matrix A.
__vDSP_N
The number of columns in matrix B.
__vDSP_P
The number of columns in matrix A and the number of rows in matrix B.
Discussion
This function multiplies an M-by-P matrix (A) by a P-by-N matrix (B) and stores the results in an M-by-N matrix (C).

This performs the following operation:

On the other side if writing the method yourself is a requirement, this post won't help you at all.

小兔几 2025-01-11 02:43:31

这里主要有两个错误:

  1. 在主程序中,你没有声明matrix。你知道如何解决这个问题。
  2. 当您创建矩阵时,如果您已将矩阵初始化为零,insertingObject 将使矩阵大小为“4x8”,而不是“4x4”。< /p>

    [[矩阵 objectAtIndex:i] insertObject:object atIndex:j];
    
  3. 在矩阵乘法方法中,您还可以将insertObject插入现有矩阵,使其大小为“4x8”而不是“4x4”。

要解决第二个问题,您需要将方法 insertObject:atIndex 替换为 replaceObjectAtIndex:withObject

那应该可以解决问题。

There are mainly two errors here:

  1. In the main program, you did not declare matrix. You know how to fix this problem.
  2. As you create the matrix, if you already initialize the matrix to zeros, insertingObject will make the matrix of size '4x8', and not '4x4'.

    [[matrix objectAtIndex:i] insertObject:object atIndex:j];
    
  3. In your matrix multiplication method, you also insertObject into an existing matrix, making its size '4x8' instead of '4x4'.

To fix this second problem, you need to replace method insertObject:atIndex, with replaceObjectAtIndex:withObject.

That should solve the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文