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..."
# *************************************************
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)
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)
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)
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)
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)
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)
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)