• Forums
• Posts
Latest Posts
Active Posts
Recently Visited
Search Results
• Page Extras
• Forum Themes
• AVR Freaks

### Hot!How to implemet fractcomplex multiply operation

Author
Maple
PIC-fan
• Total Posts : 44
• Reward points : 0
• Joined: 2016/03/06 21:42:36
• Location: China
• Status: offline
0

# How to implemet fractcomplex multiply operation

Hello everyone! I wonder if anyone knows some "fast" fractcomplex-type multiplication routine.
I am using the belowing one, but I think it is not so optimized. Does anyone can share his idea on this...Thx!
`void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ){ _Q15 q1, q2;  q1 = _Q15mpy(pX->real, pY->real); q2 = _Q15mpy(pX->imag, pY->imag); pZ->real = _Q15sub(q1, q2); q1 = _Q15mpy(pX->imag, pY->real); q2 = _Q15mpy(pX->real, pY->imag); pZ->imag = _Q15add(q1, q2);}`

du00000001
Just Some Member
• Total Posts : 3974
• Reward points : 0
• Joined: 2016/05/03 13:52:42
• Location: Germany
• Status: online
Re: How to implemet fractcomplex multiply operation 2020/10/18 16:31:35 (permalink)
0
You "think it is not so optimized"?
Why? Bacause it doesn't fit into your concept?
Do you have any idea about the math behind that?

PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
Maple
PIC-fan
• Total Posts : 44
• Reward points : 0
• Joined: 2016/03/06 21:42:36
• Location: China
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/18 20:02:05 (permalink)
0
du00000001
You "think it is not so optimized"?
Why? Bacause it doesn't fit into your concept?
Do you have any idea about the math behind that?

Yes, I think I may know sth. about it.
It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.
I read "16-Bit MCU and DSC Programmer’s Reference Manual" in chapter 4.15, there is a statement says :
"In addition, four of the ten DSP  MAC  instructions are also capable of performing an operation with
one  accumulator,  while  storing  out  the  rounded  contents  of  the  alternate  accumulator.  This
feature  is  called  accumulator  Write-Back  (WB)  and  it  provides  flexibility  for  the  software
developer. For instance, the Accumulator WB may be used to run two algorithms concurrently,
or efficiently process complex numbers, among other things. I thought maybe my routine could use this advantage somehow, but I dont know how to implememt it and that the reason I posted this thread.

BTW there is no _Q15mpy in <libq.h>, I wrote it by myself. the source code is belowing:
_Q15 _Q15mpy(_Q15 x, _Q15 y)
{
volatile register int RegACC asm("A");
RegACC = __builtin_clr();
RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0);
return (__builtin_sac(RegACC, 0));
}

`FractCmplx_Mpy`
1and0
Access is Denied
• Total Posts : 11320
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/18 22:09:07 (permalink)
+1 (1)
grchy
It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.

How optimized do you want? Your calling function within function is not going to help, neither will the Write-Back.

Anyway, I think you overthinking this. Give this a try:
`void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ){    volatile register int result asm("A");         result = __builtin_mpy(pX->real, pY->real, NULL, NULL, 0, NULL, NULL, 0);     result = __builtin_msc(result, pX->imag, pY->imag, NULL, NULL, 0, NULL, NULL, 0, 0, 0);     pZ->real = __builtin_sacr(result, 0);        result = __builtin_mpy(pX->real, pY->imag, NULL, NULL, 0, NULL, NULL, 0);     result = __builtin_mac(result, pX->imag, pY->real, NULL, NULL, 0, NULL, NULL, 0, 0, 0);     pZ->imag = __builtin_sacr(result, 0);}`

which should take about ~30 instruction cycles.

Maple
PIC-fan
• Total Posts : 44
• Reward points : 0
• Joined: 2016/03/06 21:42:36
• Location: China
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/19 05:55:37 (permalink)
0
1and0
grchy
It is my  routine "FractCmplx" which I think "not so optimized", not the _Q15xxx build-in functions.

How optimized do you want? Your calling function within function is not going to help, neither will the Write-Back.

Anyway, I think you overthinking this. Give this a try:
`void FractCmplx_Mpy(fractcomplex* pX, fractcomplex* pY, fractcomplex* pZ){    volatile register int result asm("A");         result = __builtin_mpy(pX->real, pY->real, NULL, NULL, 0, NULL, NULL, 0);     result = __builtin_msc(result, pX->imag, pY->imag, NULL, NULL, 0, NULL, NULL, 0, 0, 0);     pZ->real = __builtin_sacr(result, 0);        result = __builtin_mpy(pX->real, pY->imag, NULL, NULL, 0, NULL, NULL, 0);     result = __builtin_mac(result, pX->imag, pY->real, NULL, NULL, 0, NULL, NULL, 0, 0, 0);     pZ->imag = __builtin_sacr(result, 0);}`

which should take about ~30 instruction cycles.

Thx, 1and0! your way is better!
but one question, is that correct without clear "accumulator"(40 bits long) before executing multiplication ?
1and0
Access is Denied
• Total Posts : 11320
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/19 06:05:11 (permalink)
0
grchy
Thx, 1and0! your way is better!

You're welcome.

but one question, is that correct without clear "accumulator"(40 bits long) before executing multiplication ?

The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y).
Maple
PIC-fan
• Total Posts : 44
• Reward points : 0
• Joined: 2016/03/06 21:42:36
• Location: China
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/19 06:29:16 (permalink)
0
Thx again 1and0! :)
Maybe I didn't make my point clear, in my "_Q15mpy" routine:
_Q15 _Q15mpy(_Q15 x, _Q15 y)
{
volatile register int RegACC asm("A");
RegACC = __builtin_clr();  //line 1
RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0); //line 2
return (__builtin_sac(RegACC, 0));
}

there is line 1 to clear the accumulator first, since accumulator is 40bit and x, y are both 16bit. if there is no line 1, maybe the result would go wrong?
Actually, I didn't get your reply "The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y)." so much... sorry
1and0
Access is Denied
• Total Posts : 11320
• Reward points : 0
• Joined: 2007/05/06 12:03:20
• Location: Harry's Gray Matter
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/19 06:55:12 (permalink)
+1 (1)
grchy
Maybe I didn't make my point clear, in my "_Q15mpy" routine:
_Q15 _Q15mpy(_Q15 x, _Q15 y)
{
volatile register int RegACC asm("A");
RegACC = __builtin_clr();  //line 1
RegACC = __builtin_mpy(x, y, NULL, NULL, 0, NULL, NULL, 0); //line 2
return (__builtin_sac(RegACC, 0));
}

there is line 1 to clear the accumulator first, since accumulator is 40bit and x, y are both 16bit. if there is no line 1, maybe the result would go wrong?
Actually, I didn't get your reply "The result of the MPY is placed in the accumulator; i.e. Acc = real(X) * real(Y)." so much... sorry

There is NO need to clear the accumulator first, because the result of the multiplication is placed into the entire accumulator; that is, Acc = x * y.  16-bit x multiplies 16-bit y gives a product of 32-bit which is then sign-extended to 40 bits and put inside the accumulator. Hope this is clear. ;)
Maple
PIC-fan
• Total Posts : 44
• Reward points : 0
• Joined: 2016/03/06 21:42:36
• Location: China
• Status: offline
Re: How to implemet fractcomplex multiply operation 2020/10/19 07:01:12 (permalink)
0
Aye, Aye! Master, pretty clear this time! thank you sooooo much! :)