This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
My customer would like to confirm the spec of _complex_conjugate_mpysp intinsics function for C66x core.
Please take a look at www.ti.com/.../spru187v.pdf
The following is a prototype for _complex_conjugate_mpysp.
double _complex_conjugate_mpysp (double src1, double src2);
I believe the data type of arguments and return value should be __float2_t, rather than double. Correct, right ?
Also, which argument should be regarded as 'conjugate' ? I could not find any documentations about this.
Best Regards,
Naoki Kawada
Naoki Kawada said:I believe the data type of arguments and return value should be __float2_t, rather than double. Correct, right ?
That's correct. SDSCM00045110 is filed in the SDOWP system to get this changed. It was not marked as externally visible. I changed it. In a few hours, you will be able to see it at the SDOWP link below in my signature. Since __float2_t is typedef'd to double, this change has no effect on compiled code. It only avoids the confusion you experienced here.
Naoki Kawada said:Also, which argument should be regarded as 'conjugate' ? I could not find any documentations about this.
I suggest you code a small example which uses the intrinsic, and see the code the compiler generates for it. Use the build option --src_interlist to have the compiler keep the .asm file, and add comments which make it easier to understand the output. Then look up the instructions used in the C66x CPU manual.
Another way to understand this ... Install the C66x DSPLIB library and read the source code which use the _complex_conjugate_mpysp intrinsic. These files in the library use the intrinsic ...
./packages/ti/dsplib/src/DSPF_sp_cholesky_cmplx/c66/DSPF_sp_cholesky_cmplx.c ./packages/ti/dsplib/src/DSPF_sp_qrd_cmplx/c66/DSPF_sp_qrd_cmplx.c ./packages/ti/dsplib/src/DSPF_sp_svd_cmplx/c66/DSPF_sp_svd_cmplx.c
Thanks and regards,
-George
Hello George,
Thanks for your help.
I coded small example with _complex_mpysp and _complex_conjugate_mpysp.
Here is a sample code for complex multiply by using _complex_mpysp and feeding arguments are 'conjugate' each other.
a_cplx = _ftof2(5.0f, 2.0f);//5+2i b_cplx = _ftof2(5.0f, -2.0f);//5-2i result = _complex_mpysp(a_cplx,b_cplx); y_real = _hif2(result);//real part y_img = _lof2(result);//img part
This formula results in y_real = 29.0 and y_img = 0.0. This is correct behavior, right ?
Next, here is a sample code for 'conjugate' complex multiply by using _complex_conjugate_mpysp and feeding values are 'conjugate' each other.
a_cplx = _ftof2(5.0f, 2.0f);//5+2i b_cplx = _ftof2(5.0f, -2.0f);//5-2i result = _complex_conjugate_mpysp(a_cplx,b_cplx); y_conjugate_real = _hif2(result);//real part y_conjugate_img = _lof2(result);//img part
My assumption was the result of y_conjugate_real = 29.0 and y_conjugate_img = 0.0.
But in fact, this formula leads to the result of y_conjugate_real = 21.0 and y_conjugate_img = -20.0.
I confirmed the actual assembly code for _complex_conjugate_mpysp by using --src_interlist and I found CMPSP and DSUBSP was being used.
These assembly code looks working with the following scheme:
(a + bi)(c+di) = (ac+bd) + (ad-bc)i
Because I feed a=5.0, b=2.0, c=5.0, d=-2.0, the above formula results in 21.0 - 20.0i. So, the formula itself looks correct.
What I don't really understand is the usage of _complex_conjugate_mpysp. In other words, what value should be given to a_cplx and b_cplx to use _complex_conjugate_mpysp ? Can you answer to this ?
FYI, If I tried the following values as arguments for _complex_conjugate_mpysp, I got the same result with _complex_mpysp.
a_cplx = _ftof2(5.0f, 2.0f);//5+2i b_cplx = _ftof2(5.0f, 2.0f);//5+2i ==> regarded as 5-2i ??? result = _complex_conjugate_mpysp(a_cplx,b_cplx); y_conjugate_real = _hif2(result);//real part y_conjugate_img = _lof2(result);//img part
Now y_conjugate_real = 29.0 and y_conjugate_img = 0.0.
Best Regards,
Naoki Kawada
I lack the expertise to help you. Perhaps this thread will shed some light. I'll ask for help from one expert. However, he is out this week, and possibly next week too.
Thanks and regards,
-George
You should seriously consider writing your code with native C99 complex types. Although the TI C compiler doesn't completely support C99, recent versions of this compiler fully support complex types:
#include <complex.h> a_cplx = 5 + 2 * I; b_cplx = 5 - 2 * I; result = a_cplx * conjf(b_cplx); y_conjugate_real = crealf(result); y_conjugate_img = cimagf(result);
In regards to your question, I studied how the compiler uses _complex_conjugate_mpysp, and the compiler is treating it as _complex_conjugate_mpysp(a,b) == _complex_mpysp(conj(a), b)); however, I don't know whether that's right or wrong. We'll probably need to wait for the expert.
_complex_conjugate_mpysp(x,y) is x * conj(y).
That is, given
result := _complex_conjugate_mpysp(x,y)
then
real(result) := real(x)*real(y) + real(x)*imag(y)
imag(result) := imag(x)*real(y) - real(x)*imag(y)
It's the same as a normal complex multiply (_complex_mpysp) but with the imaginary part of y negated.
I think this matches what you are seeing.
-Alan
Hello Alan and rrlagic,
Thanks for your interest !
rrlagic, I read some threads you posted. Thanks for your remark.
> real(result) := real(x)*real(y) + real(x)*imag(y)
> imag(result) := imag(x)*real(y) - real(x)*imag(y)
I think this is not correct. I summarized the formulas for both complex_mypsp and complex_conjugate_mpysp as below:
1) complex_mypsp
result = complex_mypsp (x, y), where, x=a+bi and y=c+di
result(real) := ac-bd
result(img) := ad+bc
2) complex_conjugate_mpysp
result = complex_conjugate_mpysp (x,y). where, x=a+bi and y=c+di
result(real) := ac+bd
result(img) := ad-bc
Also, I confirmed the result of complex_mypsp and complex_conjugate_mpysp by feeding some values to 'a' to 'd', and it looks _complex_conjugate_mpysp(a,b) == _complex_mpysp(a, conj(b))); is incorrect. And as rrlagic suggested, _complex_conjugate_mpysp(a,b) == _complex_mpysp(conj(a), b)); looks correct.
Can you confirm my understanding is correct ?
Best Regards,
Naoki Kawada
Yes, it's _complex_conjugate_mpysp(a,b) == _complex_mpysp(conj(a), b));
The _complex_mpysp() operation (without conjugate) is CMPYSP followed by DADDSP.
suppose:
A5:A4 == (a,b)
A7:A6 == (c,d)
CMPYSP A5:A4, A7:A6, A3:A2:A1:A0 gives
(A3:A2:A1:A0) == (ac,ad,-bd, bc)
DADD A3:A2, A1,A0, A9:A8 gives
A9:A8 == (ac-bd, ad+bc) which is (a+bi) * (c+di)
The _complex_conjugate_mpysp() is CMPYSP followed by DSUBSP.
DSUB A3:A2, A1,A0, A9:A8 gives
A9:A8 == (ac+bd, ad-bc), which is (a-bi) * (c+di) == conj(a+bi) * (c+di)
-Alan