DFT using pure ksh ONLY!


 
Thread Tools Search this Thread
Operating Systems OS X (Apple) DFT using pure ksh ONLY!
# 1  
Old 10-29-2018
DFT using pure ksh ONLY!

DFT using pure ksh ONLY!

Well ksh[93] now has its own DFT without the aid of AWK. The SINE, COSINE and SQRT functions are in the code directly and NOT sourced.
This is stand alone and requires nothing but ksh[93] itself. Who would have even thought that this was possible until very recently?
Thanks to Corona688 for his major improvements of my original naive working maths functions.
Code:
#!/bin/ksh
# KSH Version: 'Version AJM 93u+ 2012-08-01'
# From both ${.sh.version} and ${KSH_VERSION}.
#
# OSX 10.13.6, default bash terminal running ksh.
# Darwin Barrys-MacBook-Pro.local 17.7.0 Darwin Kernel Version 17.7.0:
# Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64
#
# Licence is CC0, Public Domain.
#
# Thanks to Corona688 for his maths expertise inside the maths functions
# translating my original naive coding.
#
# This is pure ksh93 shell code only.

# The only constant required to 17 decimal places.
PI=3.14159265358979323

# Degrees to radians.
TORADIANS=$(( PI/180.0 ))
# Radians to degrees.
TODEGREES=$(( 180.0/PI ))

# NTH ROOT of a positive floating point number.
# Called as:
# NthRoot NUMBER NTHROOT [PRECISION]
# ALL POSITIVE VALUES.
# NUMBER and NTHROOT can be floating point, optional PRECISION is an integer from 1 to 16.
NthRoot()
{
	# Make these local.
	typeset NUMBER var
	typeset NTHROOT var
	typeset PRECISION var

	NUMBER="$1"
	NTHROOT="$2"
	PRECISION="$3"

	if [ "$PRECISION" = "" ] || [ $PRECISION -lt 1 ]
	then
		# My school log table(s) accuracy. ;o)
		PRECISION=4
	fi

	printf "%.${PRECISION}f\n" "$(( NUMBER**(1.0/NTHROOT) ))"
}

# SQUARE ROOT of a positive floating point number.
# Called as:
# Sqrt NUMBER [PRECISION]
# ALL POSITIVE VALUES.
# NUMBER can be floating point, optional PRECISION is an integer from 1 to 16.
Sqrt()
{
	# Make these local.
	typeset NUMBER var
	typeset NTHROOT var
	typeset PRECISION var

	NUMBER="$1"
	NTHROOT=2.0
	PRECISION="$2"

	NthRoot $NUMBER $NTHROOT $PRECISION
}

# SINE(angle) in degrees.
# Called as:
# Sin some_angle
# Courtesy of Corona688 translated and improved considerably from shell code I wrote.
Sin()
{
	# Make these local.
	typeset ANGLE var
	typeset SIN var

	# ANGLE used instead of RADIANS for consistency in accuracy.
	ANGLE="$1"
	SIN=0.0

	# Compensate for angles less the 0.0 degrees.
	while (( ANGLE<0.0 ))
	do
		(( ANGLE+=360.0 ))
	done

	# Ditto for angles greater than 360.0 degrees.
	while (( ANGLE>=360.0 ))
	do
		(( ANGLE-=360.0 ))
	done

	# Correct for the four quadrants.
	(( ANGLE>270.0 )) && (( ANGLE-=360 ))
	(( ANGLE>180.0 )) && ANGLE=$(( -(ANGLE-180) ))
	(( ANGLE>90.0 )) && ANGLE=$(( 180-ANGLE ))

	# Now convert to RADIANS.
	(( ANGLE*=TORADIANS ))

	# This loop is to calculate this Taylor series:
	# RADIAN-((RADIAN**3)/6.0)+((RADIAN**5)/120.0)-((RADIAN**7)/5040.0)+((RADIAN**9)/362880.0)-((RADIAN**11)/39916800.0)+((RADIAN**13)/6227020800.0) ... etc.
	# Factorial part 'F'.
	F=1
	for (( N=1; N<=13; ))
	do
		(( SIN+=(ANGLE**N)/F ))
		(( F*=++N ))
		(( F*=-(++N) ))
	done

	# Precision returned to 8 Decimal places.
	printf "%.8f\n" "$SIN"
}

# COSINE(angle) in degrees.
# Called as:
# Cos some_angle
Cos()
{
	# Make this local.
	typeset COS var

	COS=$(( "$1" + 90.0 ))
	# Call the 'Sin()' function.
	Sin $COS
}

dft()
{
	# Check for equal length real and imaginary arrays, and minimum number of elements of 1.
	if [ ${#REAL_ARRAY[@]} -ne ${#IMAG_ARRAY[@]} ] || [ ${#REAL_ARRAY[@]} -le 1 ] || [ ${#IMAG_ARRAY[@]} -le 1 ]
	then
		echo "ERROR 1:"
		echo "Number of elements, both real and imaginary, must be the same."
		exit 1
	fi
	# Check for powers of 2.
	N=${#REAL_ARRAY[@]}
	if [ $(( N&(N-1) )) -ne 0 ]
	then
		echo "ERROR 2:"
		echo "Padding or cropping is required to the nearest power of 2 elements."
		exit 2
	fi
	REAL=()
	IMAG=()
	# For each element into REAL() and IMAG() arrays...
	for ((K=0; K<=N-1; K++))
	do
		SUMREAL=0.0
		SUMIMAG=0.0
		# For each element from REAL_ARRAY() and IMAG_ARRAY() arrays...
		for ((T=0; T<=N-1; T++))
		do
			ANGLE=$(( (2.0*PI*T*K)/N ))
			DEGREES=$(( ANGLE*TODEGREES ))
			COS_ANGLE=$( Cos DEGREES )
			SIN_ANGLE=$( Sin DEGREES )
			SUMREAL=$(( SUMREAL+${REAL_ARRAY[T]}*COS_ANGLE+${IMAG_ARRAY[T]}*SIN_ANGLE ))
			SUMIMAG=$(( SUMIMAG-${REAL_ARRAY[T]}*SIN_ANGLE+${IMAG_ARRAY[T]}*COS_ANGLE ))
		done
		REAL[$K]=$SUMREAL
		IMAG[$K]=$SUMIMAG
	done
}

# This is good enough for this DEMO.
abs_complex()
{
	SQUARE=$(( (${REAL[COUNT]}**2)+(${IMAG[COUNT]}**2) ))
	ABS=$( Sqrt $SQUARE 8 )
}

# ALL floating point values must be from zero to positive.
#
# 16 samples of single cycle square wave.
#
# REAL_ARRAY=( 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
# IMAG_ARRAY=( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
#
# 8.00000 5.12583 0.00000 1.79995 0.00000 1.20269 0.00000 1.01959
# 0.00000 1.01959 0.00000 1.20269 0.00000 1.79995 0.00000 5.12583

# This has midway '0.5' value padding at the end to bring to the power of 2.
# Note: SIX 1.0s, SIX 0.0s, ONE extra 1.0 and finally the THREE 0.5s padding!
#
REAL_ARRAY=( 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.5 0.5 0.5 )
IMAG_ARRAY=( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
#
# 8.50000 4.11842 1.77882 0.24688 1.80278 0.49665 0.57947 1.31567
# 0.50000 1.31567 0.57947 0.49665 1.80278 0.24688 1.77882 4.11842

# Standard test values.
#
# REAL_ARRAY=( 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 )
# IMAG_ARRAY=( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
#
# 4.00000 2.61313 0.00000 1.08239 0.00000 1.08239 0.00000 2.61313

# This assumes some needed variables are global!
dft

# *************************************************
# This lot can be discarded...
echo ""
echo "Real values:		Imaginary Values:"
for n in $( seq 0 1 $(( ${#REAL[@]}-1 )) )
do
	printf "%.6f		%.6f\n" "${REAL[${n}]}" "${IMAG[${n}]}"
done
echo ""
echo "Absolute values of _complex_ numbers:"

for COUNT in $( seq 0 1 $(( ${#REAL[@]}-1 )) )
do
	abs_complex
	printf "%.5f " "$ABS"
done
echo ""
echo ""
echo "Done..."
# *************************************************

Results using OSX 10.13.6, default bash terminal.
Code:
Last login: Mon Oct 29 12:52:09 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> ./DFT_ksh

Real values:		Imaginary Values:
8.500000		0.000000
3.637821		-1.930714
-1.707107		-0.500000
0.051425		-0.241468
1.500000		-1.000000
-0.172746		0.465639
-0.292893		0.500000
0.483499		-1.223608
0.500000		0.000000
0.483499		1.223608
-0.292893		-0.500000
-0.172746		-0.465639
1.500000		1.000000
0.051425		0.241468
-1.707107		0.500000
3.637821		1.930714

Absolute values of _complex_ numbers:
8.50000 4.11842 1.77882 0.24688 1.80278 0.49665 0.57947 1.31567 0.50000 1.31567 0.57947 0.49665 1.80278 0.24688 1.77882 4.11842 

Done...
AMIGA:amiga~/Desktop/Code/Shell> _

As an addendum the maths _library_ on another thread will have functions added to it separately from this, TAN, SEC, etc... etc...

Bazza...
This User Gave Thanks to wisecracker For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

7 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

A Stanza File Parser in Pure ksh

As it was ultimately Don Craguns idea that saved the whole project i can as well give something back to the community. This is my stanza file parser, which was written only using ksh without any external programs. The stanza structure There is some inconsistency as to what exactly is meant by... (0 Replies)
Discussion started by: bakunin
0 Replies

2. Programming

Pure C function pointer on printing vowels twice

Have difficulty to understand this pure C code to only print vowels twice from input string. Questions are commented at the end of each place. #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <limits.h> /* *Demonstrate the use of dispatch tables */ /*Print a char... (11 Replies)
Discussion started by: yifangt
11 Replies

3. Shell Programming and Scripting

Pure POSIX shell scripting...

Hi all... This is more of a concensus question than help... As many of you know I am experimenting with the limitations of Pure POSIX shell scripting. Q: Is the directory /bin considered part of the Pure POSIX shell or must I stick entirely with the builtins only? The reason is I... (2 Replies)
Discussion started by: wisecracker
2 Replies

4. Debian

Pure-ftpd, passive mode, tls

Hello everyone, Could you please help me with settings of pure-ftpd. Here is my actual solution: I have got linux (debian 7.1 wheezy ), where I run pure-ftpd, created virtual users, folder for ftp. I also install openssl, create private certificate for tls. All seems good. ... (3 Replies)
Discussion started by: sedlis
3 Replies

5. SuSE

ubuntu to pure debian

ok, im going to start off by saying i am a newbee so some of the stuff i say may not be right. but anyways, right now i am using ubuntu hardy for my main distrobution. i love it and all, but the main reason i switched to linux (besides drm and the blue screen i see on my comp about ten times a... (13 Replies)
Discussion started by: Texasone
13 Replies

6. Programming

Pure Virtual Function in C++

Dear All, Here I want to know why we put =0 in case of pure virtual function, why not =1, =2 or any thing else Please send me answer any one as soon as possible. (1 Reply)
Discussion started by: krishna_sicsr
1 Replies

7. UNIX for Dummies Questions & Answers

Where can i get pure unix?

Hi guys, I do know how tu use linux (actully slack), i do know that linux was made from unix. Where can i get the unix? is that possible? Does it have any driver? Help me plz! (2 Replies)
Discussion started by: Bstyle
2 Replies
Login or Register to Ask a Question