Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

problem on multiplying a matrix and a vector with vecLib framework of Mac OS X 10.7

I just have started using vecLib framework to make a program doing intensive matrix-vector multiplications on Mac OS X 10.7. I made a simple program like this; multiply the matrix a with the vector x and add the result on the vector y.

#include <vecLib/vectorOps.h>
#include <stdio.h>

float a[8][4] =     // the matrix to be multiplied
{
    {1.0f, 0.0f, 0.0f, 0.0f},
    {0.0f, 1.0f, 0.0f, 0.0f},
    {1.0f, 1.0f, 0.0f, 0.0f},
    {0.0f, 0.0f, 1.0f, 1.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 1.0f, 1.0f, 0.0f},
    {0.0f, 0.0f, 0.0f, 1.0f},
};

float x[4] = {1.0f, 2.0f, 4.0f, 8.0f};  // the vector to be multiplied
float y[8] = {0.f, 0.f, 0.f, 0.f,       // the result vector
              0.f, 0.f, 0.f, 0.f};


int main() {
    int i;
    vSgemv('n', 8, 4, 1.0f, (const vFloat *)a, (const vFloat *)x, 1.0f, (vFloat *)y);

    for (i = 0; i < 8; i++) {
        printf("%.4f\n", y[i]);
    }

    return 0;
}

I compiled and ran the program on the console

gcc -framework vecLib -o test test.c && ./test

But the result was like this; the operation did not happen and the result vector was still empty.

0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000

Am I missing some initialization to run the matrix and vector functions in the vecLib framework?

like image 896
araste Avatar asked Jul 31 '11 02:07

araste


1 Answers

First off, the actual bug is very simple, but you would have had no way to know; you're passing 'n' for the first argument, but you actually need to pass 'N' (despite what's written in the header). With that fix, your code works.

Now, that said, you're doing a couple more subtle things "wrong"(ish).

First, please don't use vecLib. It was replaced by the Accelerate.framework (in 10.4!). vecLib.framework has only been kept around for legacy support. Any new development should link against Accelerate instead.

Second, please don't use the v* functions defined in vectorOps.h. They too have been replaced, with the industry-standard BLAS functions defined in cblas.h. Since they're standard, there is lots of public documentation on how to use them, and they're backed by much faster implementations as well; the vectorOps functions are maintained only for legacy support. cblas.h also supports many more operations and data types. If that all wasn't enough, if you decide to port your code to iOS, you will find that the vectorOps functions are not available at all. Use the cblas.h functions.

Re-writing your example as suggested:

#include <Accelerate/Accelerate.h>
#include <stdio.h>

float a[8][4] =     // the matrix to be multiplied
{
    {1.0f, 0.0f, 0.0f, 0.0f},
    {0.0f, 1.0f, 0.0f, 0.0f},
    {1.0f, 1.0f, 0.0f, 0.0f},
    {0.0f, 0.0f, 1.0f, 1.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 0.0f, 1.0f, 0.0f},
    {1.0f, 1.0f, 1.0f, 0.0f},
    {0.0f, 0.0f, 0.0f, 1.0f},
};

float x[4] = {1.0f, 2.0f, 4.0f, 8.0f};  // the vector to be multiplied
float y[8] = {0.f, 0.f, 0.f, 0.f,       // the result vector
    0.f, 0.f, 0.f, 0.f};


int main() {
    int i;
    cblas_sgemv(CblasRowMajor, CblasNoTrans, 8, 4, 1.0f, (float*)a, 4, x, 1, 1.0f, y, 1);

    for (i = 0; i < 8; i++) {
        printf("%.4f\n", y[i]);
    }

    return 0;
}

and running it gives:

scanon$ gcc test.c -framework Accelerate -o test
scanon$ ./test
1.0000
2.0000
3.0000
12.0000
5.0000
5.0000
7.0000
8.0000
like image 50
Stephen Canon Avatar answered Oct 27 '22 17:10

Stephen Canon