# SXMicrocontrollerMathMethod

## Complex number magnitude calculation

### by Nikolai Golovchenko

```;***********************************************
; Complex number magnitude calculation
; using CORDIC algorithm described at
; www.dspguru.com\info\faqs\cordic.htm
;
; Input:
;  ReH:ReL, ImH:ImL - complex number (16 bit signed)
;
; Output:
;  ReH:ReL - magnitude (16 bit unsigned)
;  ImH:ImL - garbage
;
; Temporaries:
;  RekH:RekL - Re multipled by k (k=2^-L, L=0,1,2,...15)
;  Counter - loop counter
;  Temp
;
; Instructions: 147
; Execution time(worst case including return):
;  18+18+15*(8+2+20+5+7.5*10-2)+60 ~= 1700 instruction cycles

; Notes:
;  1) Precision is 0.028%, depends on how exact
;  the division by CORDIC gain is implemented:
;	(0.60725293510314)
;	a) 1/2+1/8-1/64-1/512 -> 0.028%
;	b) 1/2+1/8-1/64-1/512-1/4096 -> 0.012384%
;	c) 1/2+1/8-1/64-1/512-1/4096+1/16384 -> 0.002333%
;  2) Range of input data should be restricted so
;  that M=sqrt(Re*Re+Im*Im) is less than 65536*0.60725293510314~=39760
;  to prevent overflow in magnitude during calculation
;  3) To reduce execution time, the number of loops can be
;  reduced to 8. The angle after rotation the initial
;  vector 8 times is less then 0.22381 deg, which is good
;  enough precision. Besides, the gain at 8 rotations is smaller
;  and closer to the approximated gain, which is used in this code.
;  Reduced execution time will be ~850 cycles!
;
; 6 Aug 2000 by Nikolai Golovchenko
;***********************************************
Magnitude16
;Find absolute value of the vector components
sb	ReH.7		;Re = abs(Re)
jmp	Magnitude16a
not	ReL
not	ReH
inc	ReL
snb	Z
inc	ReH
Magnitude16a
sb	ImH.7		;Im = abs(Im)
jmp	Magnitude16b
not	ImL
not	ImH
inc	ImL
snb	Z
inc	ImH
Magnitude16b
;Test imaginary part for zero and if yes, quit
mov	W, ImL
or	W, ImH
snb	Z
ret	;quit if zero imaginary part
;Perform first iteration
mov	W, ImL		;Imk = Im
mov	ImkL, W
mov	W, ImH
mov	ImkH, W

mov	W, ReL		;Im' = Im - Re
sub	ImL, W
mov	W, ReH
sb	C
movsz	W, ++ReH
sub	ImH, W

mov	W, ImkL		;Re' = Re + Im = Re + Imk
mov	W, ImkH
snb	C
movsz	W, ++ImkH
;Begin loop
mov	W, #1
mov	Counter, W
Magnitude16loop
mov	W, ImL		;Imk = Im
mov	ImkL, W
mov	W, ImH
mov	ImkH, W
mov	W, ReL		;Rek = Re
mov	RekL, W
mov	W, ReH
mov	RekH, W
;scale them (1 to 15 right shifts)
mov	W, Counter	;load counter value to Temp
mov	Temp, W
Magnitude16loop2
clrb	C		;unsigned right shift for Rek
rr	RekH
rr	RekL
mov	W, <<ImkH	;signed right shift for Imk
rr	ImkH
rr	ImkL
decsz	Temp
jmp	Magnitude16loop2
;update current values
mov	W, ImkL
snb	ImH.7		;if Im < 0 add a phase, if Im >= 0 substract a phase
;substract a phase
add	ReL, W		;Re' = Re + Imk
mov	W, ImkH
snb	C
movsz	W, ++ImkH

mov	W, RekL		;Im' = Im - Rek
sub	ImL, W
mov	W, RekH
sb	C
movsz	W, ++RekH
sub	ImH, W

jmp	Magnitude16loopend
snb	C		;correct Imk, because shifts of negative
movsz	W, ++ImkL	;values like (-1 >> 1 = -1) can
dec	ImkH		;accumulate error. With this correction,
inc	ImkH		;shifts of negative values will work like
;shifts of positive values (i.e. round to zero)

sub	ReL, W		;Re' = Re - Imk
mov	W, ImkH
sb	C
movsz	W, ++ImkH
sub	ReH, W

mov	W, RekL		;Im' = Im + Rek
mov	W, RekH
snb	C
movsz	W, ++RekH
Magnitude16loopend
inc	Counter
sb	Counter.4	;repeat untill counter reaches 16
;or uncomment this for better performance
;	sb	Counter.3	;repeat untill counter reaches 8
jmp	Magnitude16loop

;Optional:
;Divide result by 1.64676025786545 (CORDIC gain)
;or multiply by 0.60725293510314 = 1/2+1/8-1/64-1/512 - 0.028%
mov	W, ReH
mov	RekH, W
mov	W, ReL
mov	RekL, W
clrb	C
rr	ReH
rr	ReL
clrb	C
rr	ReH
rr	ReL
clrb	C
rr	ReH
rr	ReL
not	ReL
not	ReH
inc	ReL
snb	Z
inc	ReH
clr	Temp
snb	ReH.7
not	Temp
sub	ReL, W
mov	W, RekH
sb	C
movsz	W, ++RekH
sub	ReH, W
sb	C
dec	Temp
rr	Temp
rr	ReH
rr	ReL
rr	Temp
rr	ReH
rr	ReL
mov	W, <<ReH
rr	ReH
rr	ReL
mov	W, RekL
mov	W, RekH
snb	C
movsz	W, ++RekH
clrb	C
rr	ReH
rr	ReL
clrb	C
rr	ReH
rr	ReL
mov	W, RekL
mov	W, RekH
snb	C
movsz	W, ++RekH
rr	ReH
rr	ReL

;Done!
ret
;***********************************************

```

 file: /Techref/scenix/lib/math/vect/mag-ng_sx.htm, 4KB, , updated: 2004/6/10 14:40, local time: 2018/10/18 16:38, owner: NG--944, TOP NEW HELP FIND:  54.198.15.20:LOG IN

 ©2018 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?Please DO link to this page! Digg it! / MAKE! /  SX Microcontroller Math Method

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
 Did you find what you needed? "No. I'm looking for: " "No. Take me to the search page." "No. Take me to the top so I can drill down by catagory" "No. I'm willing to pay for help, please refer me to a qualified consultant" "No. But I'm interested. me at when this page is expanded."

 PICList 2018 contributors: o List host: MIT, Site host massmind.org, Top posters @20181018 RussellMc, Van Horn, David, Sean Breheny, David C Brown, Isaac M. Bavaresco, Neil, Bob Blick, John Gardner, Harold Hallikainen, Denny Esterline, * Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr.

.