how to DSP-code "signed square root"?

DSP related issues, mathematics, processing and techniques
Post Reply
steph_tsf
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

how to DSP-code "signed square root"?

Post by steph_tsf »

if x positive
then x = sqrt(x)
else x = - (sqrt (-x))
end

I've just completed a 64-tap Widrow-Hoff LMS Machinery. It is written in DSP (not in Green, not in Ruby, not in x86 Assembly). The "textbook" variant is doing fine. I would like to experiment a "signed square root" variant, that's "softening" the error signal using the above mentioned "signed square root" function, and also "softening" the incoming signal, before one is combining them using a multiplication.

Code: Select all

mu2err = mu * 2.0 * err;
a00=leak*(a00+(mu2err * m00));
a01=leak*(a01+(mu2err * m01));
a02=leak*(a02+(mu2err * m02));
a03=leak*(a03+(mu2err * m03));
a04=leak*(a04+(mu2err * m04));

Thus, I need to compute :
a00=leak*(a00+SIGNEDSQUAREROOT(mu2err * m00));
a01=leak*(a01+SIGNEDSQUAREROOT(mu2err * m01));
etc.

intelliger 64 v1.0 leaky.fsm
(2.11 MiB) Downloaded 1393 times

intelliger 64 v1.0 leaky.jpg (650 pix).jpg
intelliger 64 v1.0 leaky.jpg (650 pix).jpg (74.96 KiB) Viewed 27481 times

Any help much appreciated
Have a nice day
User avatar
pshannon
Posts: 144
Joined: Fri Jan 02, 2015 3:08 am

Re: how to DSP-code "signed square root"?

Post by pshannon »

Just taking a jab here. Did you actually check the results of X? When you expect a negative signed result, are you actually getting this? Sometimes if then and variable assignments have given me incorrect results and I created a work around for testing to see if the added steps resolve the issue even though the logic appears 100% correct. I am only assuming your equation is 100% correct and should work. The other Assumption: if x positive true/false works? I did not try your attached .fsm and if I am way off base, my bad. I am only trying to give you ideas.
Below will force signed x.

Try x=sqrt(x*-1.0) * -1.0
and/or
if x<0 then
x = - (sqrt (-x))
else
x = sqrt(x)
end
User avatar
martinvicanek
Posts: 1334
Joined: Sat Jun 22, 2013 8:28 pm

Re: how to DSP-code "signed square root"?

Post by martinvicanek »

In code:

Code: Select all

streamin x;
streamout y;

float abs, sgn        // bitmasks

stage(0){
  abs = 3.2|1.4;      //  abs bitmask 01111111 11111111 11111111 11111111
  sgn = -0;           // sign bitmask 10000000 00000000 00000000 00000000
  }
 
stage(2){
  y = (sgn&x)|sqrt(abs&x);
  }


ASM:

Code: Select all

streamin x;
streamout y;

int abs=2147483647;  //  abs bitmask 01111111 11111111 11111111 11111111
int sgn=-2147483648; // sign bitmask 10000000 00000000 00000000 00000000

movaps xmm0,abs;
andps xmm0,x;
sqrtps xmm0,xmm0;
movaps xmm1,sgn;
andps xmm1,x;
orps xmm1,xmm0;
movaps y,xmm1;

steph_tsf
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

Re: how to DSP-code "signed square root"?

Post by steph_tsf »

pshannon wrote:Try x=sqrt(x*-1.0) * -1.0
Unfortunately, I don't understand your suggestion. In Flowstone DSP Code Component, conditional statements must be implemented using a mask.
For example, the following Flowstone DSP Code: x = x - (x >= 1) & 1.0;
is equivalent to the following C/C++ code: if( x >= 1 ) x = x – 1.0;

The following cumbersome Flowstone DSP code is doing what I am requiring:

Code: Select all

streamin x;
streamout y;
y=sqrt(abs(x))*(((x<0)&-1.0)+(x>0)&1.0);

The corresponding assembly code is:

Code: Select all

streamin x;streamout y;float smIntVarTemp=0.0;
float smIntVarZero=0;
float F0=0;
float FM1=-1;
float F1=1;
movaps xmm0,x;
movaps smIntVarTemp,xmm0;
cmpps xmm0,smIntVarZero,6;
andps xmm0,smIntVarTemp;
addps xmm0,xmm0;
subps xmm0,smIntVarTemp;
sqrtps xmm0,xmm0;
movaps xmm1,x;
cmpps xmm1,F0,1;
movaps xmm2,xmm1;
andps xmm2,FM1;
movaps xmm3,x;
cmpps xmm3,F0,6;
movaps xmm4,xmm3;
andps xmm4,F1;
addps xmm2,xmm4;
mulps xmm0,xmm2;
//Assignment> sLeft=xmm0
movaps y,xmm0;

Looks like a joke
Is there a more efficient approach, still in Flowstone DSP Code Component?
Any help much appreciated
Last edited by steph_tsf on Thu Mar 19, 2020 7:22 pm, edited 1 time in total.
steph_tsf
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

Re: how to DSP-code "signed square root"?

Post by steph_tsf »

Martin, I didn't notice your kind reply dated Wed Mar 18, 2020 9:40 pm.
Looks brilliant.

Code: Select all

a00=leak*(a00+(mu2err * m00));
a01=leak*(a01+(mu2err * m01));
a02=leak*(a02+(mu2err * m02));
etc.

can thus become in stage (2):

Code: Select all

x=mu2err*m00;
a00=leak*(a00+((sgn&x)|sqrt(abs&x)));
x=mu2err*m01;
a01=leak*(a01+((sgn&x)|sqrt(abs&x)));
x=mu2err*m02;
a02=leak*(a02+((sgn&x)|sqrt(abs&x)));
etc.

Is it possible to also pipe-line the various mu2err*m00, mu2err*m01, etc. calculations, for regaining a "single line" layout?
User avatar
pshannon
Posts: 144
Joined: Fri Jan 02, 2015 3:08 am

Re: how to DSP-code "signed square root"?

Post by pshannon »

When I responded it was to quickly and I thought it was a logic issue you were having or the signed x was not working correctly. I was leaning towards a bug in FS at first. I still know C & ASM, but I have not worked with the DSP code side yet. Sorry for the confusion.
steph_tsf
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

Re: how to DSP-code "signed square root"?

Post by steph_tsf »

pshannon wrote:I have not worked with the DSP code side yet.
Me to. This is the first time I am digging into Flowstone DSP Code Component, deeper than computing y = a * x + b.

Attached, is a working implementation of Martin Vicanek solution:
signed square root.fsm
(8.18 KiB) Downloaded 1421 times

http://www.dsprobotics.com/Files/V3/User%20Guide.pdf chapter 9 page 240 doesn't list:
- the "vertical bar" operator,
- the "abs" (absolute value) function,
- the "square root" (sqrt) function.
Question: Is there a supported operators list somewhere?
Question: Is there a supported functions list somewhere?

Upon reading page 242, I realized that one can declare and access indexed arrays.
Question: is this really supported, and reliable, because on Flowstone 3.0.4, this appears to be not supported.
Question: can somebody please publish a circular buffer management example, whose length is 64?

Upon reading page 243, I realized that memin() creates a Mem type connector on the component so that one can pass in data from outside.
Question: is this really supported, and reliable, because on Flowstone 3.0.4, this appears to be not supported.
Question: can somebody please publish a memin() example?
Question: is there a memout()?

Upon reading page 243, I realized one can program loops.
Question: Is it allowed to rely on a loop counter, that's a variable instead of a constant?

Considering the lack of "normal" conditional statements in DSP coding, what Google search keyword do I need to specify for locating the utility that's converting a "if (condition) then (true branch) else (false branch) end" code sequence into a DSP code sequence?

Any help, much appreciated
Have a nice day
Post Reply