Page 1 of 1

Pseudo random sign flip

Posted: Fri Feb 20, 2015 7:25 am
by wilbert
I needed this for myself. Maybe someone else can use it as well.
What the procedure does is flip the sign of the value on a pseudo random basis.
So it flips, or it doesn't :wink:

Code: Select all

Procedure.i PRSF(value.i); Pseudo random sign flip
  Static RN.l = $72486161
  EnableASM
  mov edx, RN
  !lea eax, [edx + edx]
  !sar edx, 31
  !and edx, 0xc0000401
  !xor edx, eax
  mov RN, edx
  !sar edx, 31
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !movsx rdx, dx
    !mov rax, [p.v_value]
    !xor rax, rdx
    !sub rax, rdx
  CompilerElse
    !mov eax, [p.v_value]
    !xor eax, edx
    !sub eax, edx
  CompilerEndIf
  DisableASM
  ProcedureReturn
EndProcedure
Example

Code: Select all

L.l = 123
For i = 1 To 400
  L = PRSF(L)
  Debug L
Next

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 7:35 am
by StarBootics
Nice but did you know that you can put the example on the same code as your procedure like this :

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  
  L.l = 123
  For i = 1 To 400
    L = PRSF(L)
    Debug L
  Next
  
CompilerEndIf
Best regards
StarBootics

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 11:25 am
by kvitaliy

Code: Select all

Procedure  PRSF(value.i)
  If Random(1,0)
    ProcedureReturn -1 * value
  Else
    ProcedureReturn value
  EndIf
EndProcedure

;Example
L.l = 123
For i = 1 To 400
  L = PRSF(L)
  Debug L
Next

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 11:37 am
by wilbert
@StarBootics,
I have seen it before on the forum but usually don't use it myself.
Thanks for mentioning.

@kvitality,
The procedure was created for a situation where it would be called very often.
Your approach works fine and probably gives better random values but is 4-5 times slower on my computer.

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 12:02 pm
by luis
@kvitality

Who would have thought of that, it's amazing !

But really. Who would have thought of that ? The multiplication is not needed. It's there just to wast CPU cycles I suppose.

Shame on you Wilbert for not thinking about that and writing the code in asm. :wink:

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 12:04 pm
by kvitaliy
wilbert wrote: is 4-5 times slower on my computer.
If speed is important, you're right

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 6:12 pm
by BasicallyPure
Perhaps a macro would be faster than a procedure but not as fast as Wilbert's code of course.

Code: Select all

Macro RandomSign(value)
   value * (-1 + Random(1)<<1)
EndMacro

For n = 1 To 100
   x = RandomSign(n)
   Debug x
   
   Select Sign(x)
      Case  1 : pos.i + 1
      Case -1 : neg.i + 1
   EndSelect
Next n

Debug "positive results = " + pos
Debug "negative results = " + neg

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 6:28 pm
by Little John
BasicallyPure wrote:if the multiplication is not there then how would the procedure return the negative of 'value'.
For instance

Code: Select all

ProcedureReturn -value

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 6:33 pm
by luis
BasicallyPure wrote: I disagree, if the multiplication is not there then how would the procedure return the negative of 'value'.
Reconsider it, quick !

I forgot the obligatory facial expression in this case: :shock:

BTW: even the "else" was not needed.

Re: Pseudo random sign flip

Posted: Fri Feb 20, 2015 6:47 pm
by BasicallyPure
I realized the answer after I posted but didn't complete the edit fast enough. :oops: