1D LEE Fast Cosine Tranform to 2D, AI helped

I am doing various Cosine Transforms at present for a stock AMIGA A1200(HD) that only has Python 1.4.0, (a python version of 1.3.0 statically compiled exists in the Python website), so I decided to ask Gemini for help...
A seriously expanded AMIGA has Python 2.0.1 and MicroPython 3.4.0 that will work under AMIGA OS3.0x...
I replied yes to Gemini-2.png...
Now all retro computers to Windows 95 have access to my DCT-II and IDCT-II, DCT-III.
This site is the first to glimpse it. It goes onto AMINET soon.
There is no need for me to carry on text here as I put all the info inside the code:-

# FCT_LEE_1D_2D.py

# The original code was generated by AI, (Gemini), and was supposedly for
# Python 2.0.x, see Gemini-2.png.
# Although I asked for Python (1.3.0), 1.4.0 for the AMIGA it didn't work
# and required a few changes to even work on AMIGA Python 2.0.1.
# NOTE:- The 'print' statement and 'print()' function have never been a real
# major problem at all...
# Around 15 years ago I sorted that lot out and posted them onto AMINET.
# Just copy and paste "Backwards Compatibility" without the quotes into the
# AMINET search bar, top right, and voila, five files that show the
# commonalities with ALL versions of Python, all worked out by myself,
# without resorting to 'sys.stdout.write()' which has its own foibles.
# With a finished version 2.0.1 as a backup I set about the errors on Python
# 1.3.0 for my LINUX test Python 1.3.0......

# There were usual very minor ones, one rare one, the 'list' builtin does
# not exist in Python 1.3.0, we live and learn, and an integer needed
# instead of a float, a thorough cleanup of the code, and added the small
# amount of error checking, the 'Int_Round()' function, etc.

# This is the result; there is no copyright so this is entirely Creative
# Commons CC0 licence:- Public Domain. You do with it as you please.
# Although I take no credit for the initial AI code, I do take credit for
# the extreme, and I mean EXTREME, backwards compatibility.
# The AMIGA Python 2.0.1 results are shown at the bottom of this code, the
# rest are snapshots of AMIGA A1200(HD) and Python 1.4.0, GNU/LINUX MINT
# CINNAMON 22.3 and Python 1.3.0 and 3.12.3, and APPLE OSX 10.15.7 and
# Python 2.7.16 and 3.15.0b3.
#
# Joint authors: Gemini and Barry Walker, 2026.
#
# Reference the Gemini reply pictures:-
# SO YES! A[n] FCT_LEE_1D_2D.py CAN be created to run inside Python 1.3.0 to
# the current, as of 27-07-2026, Python 3.15.0b3 WITHOUT any modification at
# all!
# This is the difference between humans and machines at this current point
# in time! Quick AI code does not necessarily work according to plan, but
# the important parts often help with one's Lateral and Orthogonal Thinking.

# And finally, it's better to have something for a retro-computer that does
# NOT have that facility, TO have it, than TO NOT have it at all!

import sys
import math

# ***************************************************************************

def FCT_LEE_1D_Core(vector, temp, length):
	"""
	Recursive core of Byeong Gi Lee's Fast DCT algorithm.
	Operates on a RADIX-2 length list.
	"""
	if length<=1:
		return()

	# Ensure 'HALF' is an integer.
	HALF=int(length/2)
	for i in range(0, HALF, 1):
		x=vector[i]
		y=vector[length-1-i]
		temp[i]=(x+y)
		# Divide by 2*cos_term as specified by Lee's butterfly step.
		cos_term=(math.cos((i+0.5)*math.pi/float(length)))
		temp[i+HALF]=((x-y)/(cos_term*2.0))

	# Recursively process the lower and upper halves.
	FCT_LEE_1D_Core(temp, vector, HALF)
	# Target the upper HALF buffer region.
	temp_upper=temp[HALF:]
	vector_upper=vector[HALF:]
	FCT_LEE_1D_Core(temp_upper, vector_upper, HALF)
	# Write structural changes back into slice references.
	for i in range(0, HALF, 1):
		temp[HALF+i]=temp_upper[i]
		vector[HALF+i]=vector_upper[i]

	# Re-order the shuffled recursive outputs into standard frequency order.
	for i in range(HALF-1):
		vector[i*2]=temp[i]
		vector[i*2+1]=temp[HALF+i] + temp[HALF+i+1]

	vector[length-2]=temp[HALF-1]
	vector[length-1]=temp[length-1]

# ---------------------------------------------------------------------------

def Ortho_1D_FCT_LEE(vector):
	"""
	Applies Lee's fast algorithm and enforces orthogonal scaling factors.
	"""
	N=len(vector)
	# Create working buffers.
	v_copy=vector[:]
	temp=[0.0]*N

	# Run the fast 1D decomposition.
	FCT_LEE_1D_Core(v_copy, temp, N)

	# Scale outputs to ensure the transform is strictly orthogonal.
	Ortho_Vector=[0.0]*N
	for k in range(0, N, 1):
		if k==0:
			Ortho_Scale=(math.sqrt(1.0/float(N)))
		else:
			Ortho_Scale=(math.sqrt(2.0/float(N)))
		Ortho_Vector[k]=(v_copy[k]*Ortho_Scale)

	return(Ortho_Vector)

# ---------------------------------------------------------------------------

def Transpose_MATRIX(matrix):
	"""Transposes a RADIX-2, NxN 2D list array structural format."""
	N=len(matrix)
	Transposed=[]
	for c in range(0, N, 1):
		row_build=[]
		for r in range(0, N, 1):
			row_build.append(matrix[r][c])
		Transposed.append(row_build)
	return(Transposed)

# ---------------------------------------------------------------------------

def Ortho_2D_FCT_LEE(matrix):
	"""
	Computes an orthogonal 2D FCT via 1D row transformations 
	and matrix transpositions using Lee's fast approach.
	"""
	# Transform each row independently.
	row_transformed=[]
	for row in matrix:
		row_transformed.append(Ortho_1D_FCT_LEE(row))

	# Transpose columns to rows.
	Transposed_1=Transpose_MATRIX(row_transformed)

	# Transform the columns, (now acting as rows).
	col_transformed=[]
	for col_row in Transposed_1:
		col_transformed.append(Ortho_1D_FCT_LEE(col_row))

	# Transpose back to original orientation mapping.
	return(Transpose_MATRIX(col_transformed))

# ***************************************************************************

def Int_Round(result, N):
	"""Rounds all floating point values and converts to integers."""
	for row in result:
		for i in range(0, N, 1):
			row[i]=int(round(row[i]))

# *********************************** MAIN **********************************
# ***** Input matrix size MUST ALWAYS be RADIX-2, for Lee's algorithm. ******
#    In this example an 8x8 matrix as used in ordinary JPEG compression.
Sample_MATRIX=[
	[52,  55,  61,  66,  70,  61,  64,  73],
	[63,  59,  55,  90,  109, 85,  69,  72],
	[62,  59,  68,  113, 144, 104, 66,  73],
	[63,  58,  71,  122, 154, 106, 70,  69],
	[67,  61,  68,  104, 126, 88,  68,  70],
	[79,  65,  60,  70,  77,  68,  58,  75],
	[85,  71,  64,  59,  55,  61,  65,  83],
	[87,  79,  69,  68,  65,  76,  78,  94]
]

M=len(Sample_MATRIX[0])
N=len(Sample_MATRIX)

# A small amount of error checking.
if M!=N: sys.exit(3)
if M&(M-1)!=0:
	print("Power of 2 ERROR!")
	print("Exiting with a return code of 1!")
	sys.exit(1)
if N&(N-1)!=0:
	print("Power of 2 ERROR!")
	print("Exiting with a return code of 2!")
	sys.exit(2)

result=Ortho_2D_FCT_LEE(Sample_MATRIX)

print(Sample_MATRIX)
print("")
print(result)
print("")
Int_Round(result, N)
print(result)

sys.exit()

# ***************************************************************************
# A Highly expanded AMIGA A1200(HD), Python 2.0.1. The photo is Python 1.4.0.
# ---------------------------------------------------------------------------
# [[52, 55, 61, 66, 70, 61, 64, 73], [63, 59, 55, 90, 109, 85, 69, 72],
# [62, 59, 68, 113, 144, 104, 66, 73], [63, 58, 71, 122, 154, 106, 70, 69],
# [67, 61, 68, 104, 126, 88, 68, 70], [79, 65, 60, 70, 77, 68, 58, 75],
# [85, 71, 64, 59, 55, 61, 65, 83], [87, 79, 69, 68, 65, 76, 78, 94]]
#
# [[608.625, -30.185717276809, -61.197061950296, 27.239322496005, 56.125,
# -20.095173772335, -2.3876470952936, 0.46181544244841], [4.4655237014137,
# -21.85743933226, -60.758038116534, 10.253636818418, 13.145110120476,
# -7.0874180078452, -8.5354367129695, 4.8768884966804], [-46.834484742312,
# 7.3705973534267, 77.129387578756, -24.561982249733, -28.911688429321,
# 9.9335209527751, 5.4168154723945, -5.6489508621375], [-48.534966665531,
# 12.068360940019, 34.099767172715, -14.759411080802, -10.24060680175,
# 6.295967438373, 1.8311650530957, 1.9459365148648], [12.125,
# -6.5534499288921, -13.196120970972, -3.9514277279078, -1.875,
# 1.7452844510267, -2.7872282503369, 3.1352823039768], [-7.734743677599,
# 2.9054613828906, 2.3797957648756, -5.9393139358655, -2.3777967067326,
# 0.94139159614139, 4.3037133436227, 1.8486910259091], [-1.0306740134973,
# 0.18306744355202, 0.41681547239451, -2.4155613745354, -0.87779391994229,
# -3.0193065522845, 4.1206124212445, -0.66194845393858], [-0.16537560203668,
# 0.14160712244184, -1.0715363895103, -4.1929120780447, -1.1703140920062,
# -0.097761079337537, 0.50126939164459, 1.6754588169204]]
#
# [[609, -30, -61, 27, 56, -20, -2, 0], [4, -22, -61, 10, 13, -7, -9, 5],
# [-47, 7, 77, -25, -29, 10, 5, -6], [-49, 12, 34, -15, -10, 6, 2, 2],
# [12, -7, -13, -4, -2, 2, -3, 3], [-8, 3, 2, -6, -2, 1, 4, 2],
# [-1, 0, 0, -2, -1, -3, 4, -1], [0, 0, -1, -4, -1, 0, 1, 2]]
# ***************************************************************************

See images...

2 Likes