Multiply a complex scalar and a real array

259 views
Skip to first unread message

Eric

unread,
Jun 22, 2015, 2:15:21 PM6/22/15
to arrayfi...@googlegroups.com
I'm trying to figure out how to multiply a complex scalar by an array.  Here's a simplified version of the code, borrowing from the helloworld example.

        // Select a device and display arrayfire info
        int device = argc > 1 ? atoi(argv[1]) : 0;
        af::setDevice(device);
        af::info();

        printf("Create an array equal to -2*pi*i\n");
        float temp[] = { 0, 1 };
        array i(1, 1, (cfloat *)temp);
        array miTwoPi = -2.0f*af::Pi * i;
        af_print(miTwoPi);

        printf("Create a 5-by-3 matrix of random floats on the GPU\n");
        array A = randu(5,3, f32);
        af_print(A);

        printf("Multiply A by the imaginary constant\n");
        array A_mult = miTwoPi * complex(A);
        af_print(A_mult);


The variable miTwoPi seems to be created correctly as does the variable A.  However, when I try to multiply the two with the * operator I get:

ArrayFire Exception(203): Invalid input size
In c:\workspace\af_installer\arrayfire\src\api\cpp\array.cpp:888


Any thoughts as to what is happening?  I've tried this with and without the explicit complex() call around A when multiplying by miTwoPi.  My goal is to calculate a complex array of the form exp(-i*2*pi*theta), where theta is an array of real values.

Thanks,
Eric Shields

Eric

unread,
Jun 22, 2015, 2:17:49 PM6/22/15
to arrayfi...@googlegroups.com
One more thing:  I did try using af::complex(A) to make sure that the correct complex() function was being called. My only includes are arrayfire.h, cstdio, and cstdlib.

-Eric

Shehzan Mohammed

unread,
Jun 22, 2015, 2:22:35 PM6/22/15
to arrayfi...@googlegroups.com, eric.a....@gmail.com
The behavior you are seeing is correct.
When you do a * operation between 2 arrays, it is an element wise operation. Hence the sizes of both arrays need to be equal. In your code, A is 5x3 and miTwoPi is 1x1. Hence the failure.

You can do one of the following:
* Create a constant array of size of A with temp as value.
* Tile miTwoPi to the the same size as A.
* Use temp as the scalar multiplies (like how you are doing when creating miTwoPi).
* Use gfor.

- Shehzan

Eric

unread,
Jun 22, 2015, 2:37:54 PM6/22/15
to arrayfi...@googlegroups.com, eric.a....@gmail.com
Shehzan,

Thanks!  Just for completeness and in case anybody else stumbles on this.  Here's what solved my problem:

                printf("Create an array equal to -2*pi*i\n");

        float temp[] = { 0, 1 };
        array i(1, 1, (cfloat *)temp);
        array miTwoPi = -2.0f*af::Pi * i;
        array miTwoPiArray = tile(miTwoPi, 5, 3);
        af_print(miTwoPiArray);


        printf("Create a 5-by-3 matrix of random floats on the GPU\n");
        array A = randu(5,3, f32);
        af_print(A);

        printf("Multiply A by -2*i*pi\n");
        array A_mult = miTwoPiArray * af::complex(A);
        af_print(A_mult);


Thanks again,
Eric

Pavan Yalamanchili

unread,
Jun 22, 2015, 2:43:46 PM6/22/15
to Eric, arrayfi...@googlegroups.com
Hi Eric,

While this code works, the best way to do this is to do one of the following

1) Easiest way:

af::cfloat i = af::cfloat(0, 1);
array A_mult = -2.0 * af::Pi * i * A;

2) Another way:

array i = af::constant(af::cfloat(0, 1), A.dims());
array A_mult = -2.0 * af::Pi * i * A;

Both of these do not allocate temporary memory for "i". The tile method creates temporary memory that is not needed.

--
You received this message because you are subscribed to the Google Groups "ArrayFire Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to arrayfire-use...@googlegroups.com.
To post to this group, send email to arrayfi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/arrayfire-users/01f43da6-32af-4238-9d69-81a866d233a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Eric

unread,
Jun 22, 2015, 3:05:02 PM6/22/15
to arrayfi...@googlegroups.com, eric.a....@gmail.com
Pavan,

Thanks for the suggestions.  In the "Easiest way" I thought I needed to use the following:

array A_mult = -2.0 * af::Pi * (i * A);

Without the parentheses I received an error message in Visual Studio on the * operator between af::Pi and i.  It said it matched more than one * operator.  However, when I used the above, A_mult was a real array equal to zero everywhere.  If I use

array A_mult = -2.0 * af::Pi * (i * complex(A));

I get the correct answer.  The second method works as is, interestingly.  There was no need to call the complex() function in that case.

Thanks again,
Eric
Reply all
Reply to author
Forward
0 new messages