External development: Populating a complex array in C [message #91532] |
Sat, 25 July 2015 11:08  |
dg86
Messages: 118 Registered: September 2012
|
Senior Member |
|
|
Dear Folks,
I'm trying to write a DLL in C that returns a complex array to IDL.
I can create the (temporary) array with no trouble:
char * pd;
IDL_VPTR idl_array;
IDL_MEMINT dim[IDL_MAX_ARRAY_DIM];
dim[0] = 512;
dim[1] = 512;
pd = IDL_MakeTempArray(IDL_TYP_COMPLEX, 2, dim, IDL_ARR_INI_ZERO, &idl_array);
Next, I'd like to populate the idl_array with values, ideally using memcpy for
speed and clarity. Attempts resembling
memcpy(pd, src, 512*512*sizeof(float));
seem not to change the data in idl_array. Does anyone know the right way
to copy floating point data from the C src array to the idl_array?
Alternatively, does anyone know how to convert two IDL_TYPE_FLOAT arrays
into one IDL_TYPE_COMPLEX array along the lines of the COMPLEX(real,imag)
function in IDL?
Many thanks,
David
|
|
|
Re: External development: Populating a complex array in C [message #91533 is a reply to message #91532] |
Sat, 25 July 2015 14:18   |
Heinz Stege
Messages: 189 Registered: January 2003
|
Senior Member |
|
|
Hi David.
On Sat, 25 Jul 2015 11:08:28 -0700 (PDT), David Grier wrote:
> [...]
>
> Next, I'd like to populate the idl_array with values, ideally using memcpy for
> speed and clarity. Attempts resembling
>
> memcpy(pd, src, 512*512*sizeof(float));
>
Just an idea: The size of the complex array is 512*512. A complex
number consists of two floats. So shouldn't you copy
512*512*sizeof(float)*2 bytes?
> seem not to change the data in idl_array. Does anyone know the right way
> to copy floating point data from the C src array to the idl_array?
>
> Alternatively, does anyone know how to convert two IDL_TYPE_FLOAT arrays
> into one IDL_TYPE_COMPLEX array along the lines of the COMPLEX(real,imag)
> function in IDL?
>
Yes, here is an example:
real=findgen(5)
imag=4.-findgen(5)
comp=complex(real,imag)
help,comp
print,comp
IDL prints:
COMP COMPLEX = Array[5]
( 0.000000, 4.00000)( 1.00000, 3.00000)
( 2.00000, 2.00000)( 3.00000, 1.00000)
( 4.00000, 0.000000)
Cheers, Heinz
|
|
|
Re: External development: Populating a complex array in C [message #91534 is a reply to message #91533] |
Sun, 26 July 2015 03:51   |
Heinz Stege
Messages: 189 Registered: January 2003
|
Senior Member |
|
|
On Sat, 25 Jul 2015 23:18:03 +0200, Heinz Stege wrote:
> On Sat, 25 Jul 2015 11:08:28 -0700 (PDT), David Grier wrote:
>
>> Alternatively, does anyone know how to convert two IDL_TYPE_FLOAT arrays
>> into one IDL_TYPE_COMPLEX array along the lines of the COMPLEX(real,imag)
>> function in IDL?
>>
> Yes, here is an example:
> real=findgen(5)
> imag=4.-findgen(5)
> comp=complex(real,imag)
> help,comp
> print,comp
> IDL prints:
> COMP COMPLEX = Array[5]
> ( 0.000000, 4.00000)( 1.00000, 3.00000)
> ( 2.00000, 2.00000)( 3.00000, 1.00000)
> ( 4.00000, 0.000000)
>
This obviously is not what you wanted to ask for. Sorry for not
realizing the meaning of "along the lines of".
You may be interested in the function
IDL_VPTR IDL_CvtComplex(int argc, IDL_VPTR argv[]).
The External Development Guide says, that this function is the direct
implementation of the IDL command COMPLEX.
Cheers, Heinz
|
|
|
Re: External development: Populating a complex array in C [message #91535 is a reply to message #91534] |
Sun, 26 July 2015 04:54  |
dg86
Messages: 118 Registered: September 2012
|
Senior Member |
|
|
On Sunday, July 26, 2015 at 6:51:41 AM UTC-4, Heinz Stege wrote:
> On Sat, 25 Jul 2015 23:18:03 +0200, Heinz Stege wrote:
>
>> On Sat, 25 Jul 2015 11:08:28 -0700 (PDT), David Grier wrote:
>>
>>> Alternatively, does anyone know how to convert two IDL_TYPE_FLOAT arrays
>>> into one IDL_TYPE_COMPLEX array along the lines of the COMPLEX(real,imag)
>>> function in IDL?
>>>
>> Yes, here is an example:
>> real=findgen(5)
>> imag=4.-findgen(5)
>> comp=complex(real,imag)
>> help,comp
>> print,comp
>> IDL prints:
>> COMP COMPLEX = Array[5]
>> ( 0.000000, 4.00000)( 1.00000, 3.00000)
>> ( 2.00000, 2.00000)( 3.00000, 1.00000)
>> ( 4.00000, 0.000000)
>>
> This obviously is not what you wanted to ask for. Sorry for not
> realizing the meaning of "along the lines of".
>
> You may be interested in the function
> IDL_VPTR IDL_CvtComplex(int argc, IDL_VPTR argv[]).
> The External Development Guide says, that this function is the direct
> implementation of the IDL command COMPLEX.
>
> Cheers, Heinz
IDL_CvtComplex() is just what I was looking for. The documentation
for this command is incorrect (wrong function signature) and incomplete
(no examples), but I got it working. Here's a code snippet for my solution:
IDL_MEMINT dim[IDL_MAX_ARRAY_DIM];
IDL_VPTR idl_real, idl_imag, idl_cmp, idl_argv[2];
char *pr, *pi;
dim[0] = width; // width and height are defined elsewhere
dim[1] = height;
pr = IDL_MakeTempArray(IDL_TYP_FLOAT, 2, dim, IDL_ARR_INI_NOP, &idl_real);
pi = IDL_MakeTempArray(IDL_TYP_FLOAT, 2, dim, IDL_ARR_INI_NOP, &idl_imag);
idl_argv[0] = idl_real;
idl_argv[1] = idl_imag;
// Put data into idl_real and idl_imag -- I used cudaMemcpy() for my application
idl_cmp = IDL_CvtComplex(2, idl_argv, NULL);
// Free temporary resources
IDL_Deltmp(idl_real);
IDL_Deltmp(idl_imag);
Many thanks for pointing me in the right direction.
All the best,
David
|
|
|