雨角 发表于 2025-10-19 19:35:00

论DCT和IDCT的重要性,汇编SIMD版第一,此贴第二,就是这么狂 :-)

输入:
输出: [ 3.464 -1.4140.000]
重建:
cos(0.0*π/3)*sqrt(1/N)*1.0 + cos(0.0*π/3)*sqrt(1/N)*2.0 + cos(0.0*π/3)*sqrt(1/N)*3.0 = 3.464
cos(0.5*π/3)*sqrt(2/N)*1.0 + cos(1.5*π/3)*sqrt(2/N)*2.0 + cos(2.5*π/3)*sqrt(2/N)*3.0 = -1.414
cos(1.0*π/3)*sqrt(2/N)*1.0 + cos(3.0*π/3)*sqrt(2/N)*2.0 + cos(5.0*π/3)*sqrt(2/N)*3.0 = 0.000
恭喜,你(基本)明白DCT了!可M为啥是正交矩阵?!
cos(0.0*π/3)*sqrt(1/N)*cos(0.0*π/3)*sqrt(1/N) + cos(0.0*π/3)*sqrt(1/N)*cos(0.0*π/3)*sqrt(1/N) + cos(0.0*π/3)*sqrt(1/N)*cos(0.0*π/3)*sqrt(1/N)
cos(0.0*π/3)*sqrt(1/N)*cos(0.5*π/3)*sqrt(2/N) + cos(0.0*π/3)*sqrt(1/N)*cos(1.5*π/3)*sqrt(2/N) + cos(0.0*π/3)*sqrt(1/N)*cos(2.5*π/3)*sqrt(2/N)
cos(0.0*π/3)*sqrt(1/N)*cos(1.0*π/3)*sqrt(2/N) + cos(0.0*π/3)*sqrt(1/N)*cos(3.0*π/3)*sqrt(2/N) + cos(0.0*π/3)*sqrt(1/N)*cos(5.0*π/3)*sqrt(2/N)
cos(0.5*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N) + cos(1.5*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N) + cos(2.5*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N)
cos(0.5*π/3)*sqrt(2/N)*cos(0.5*π/3)*sqrt(2/N) + cos(1.5*π/3)*sqrt(2/N)*cos(1.5*π/3)*sqrt(2/N) + cos(2.5*π/3)*sqrt(2/N)*cos(2.5*π/3)*sqrt(2/N)
cos(0.5*π/3)*sqrt(2/N)*cos(1.0*π/3)*sqrt(2/N) + cos(1.5*π/3)*sqrt(2/N)*cos(3.0*π/3)*sqrt(2/N) + cos(2.5*π/3)*sqrt(2/N)*cos(5.0*π/3)*sqrt(2/N)
cos(1.0*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N) + cos(3.0*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N) + cos(5.0*π/3)*sqrt(2/N)*cos(0.0*π/3)*sqrt(1/N)
cos(1.0*π/3)*sqrt(2/N)*cos(0.5*π/3)*sqrt(2/N) + cos(3.0*π/3)*sqrt(2/N)*cos(1.5*π/3)*sqrt(2/N) + cos(5.0*π/3)*sqrt(2/N)*cos(2.5*π/3)*sqrt(2/N)
cos(1.0*π/3)*sqrt(2/N)*cos(1.0*π/3)*sqrt(2/N) + cos(3.0*π/3)*sqrt(2/N)*cos(3.0*π/3)*sqrt(2/N) + cos(5.0*π/3)*sqrt(2/N)*cos(5.0*π/3)*sqrt(2/N)
如果用上复数(欧拉公式),就可以用等比数列求和公式了!!
from math import cos, sqrt, pi
import numpy as np

π = pi; N = 3
m = None # DCT矩阵
mt = None # IDCT矩阵,m的转置
mc = None # "C"版本DCT矩阵
ms = None # string版DCT矩阵

ne = lambda a, b: not np.allclose(a, b, atol=1E-6)

def generate_dct_matrices():
global m; global mt; global mc; global ms
m = np.zeros((N, N))
# [*3]*3不对。*3得,再*3复制引用‌而非创建独立副本。修改任意一行会影响所有行;debug 1小时
mc = [ * N for _ in range(N)]
ms = [ * N for _ in range(N)]
for k in range(N):
    for n in range(N):
      mc = m = cos((n + 0.5) * k * pi / N)
      ms = f'cos({(n+0.5)*k}*π/{N})'
m *= sqrt(1/N)
for n in range(N):
    mc *= sqrt(1/N)
    ms += f'*sqrt(1/N)'
m *= sqrt(2/N)
for k in range(1,N):
    for n in range(N):
      mc *= sqrt(2/N)
      ms += f'*sqrt(2/N)'
mt = m.T
if ne(m, mc): raise ValueError()

# x是一维数组,shape=(3,),np将其视为‌列向量‌(3,1)
# 3x3 x 3x1 = 3x1 再摆平
dct= lambda x: np.dot(m,x)
idct = lambda y: np.dot(mt, y)
# So, dct和idct其实是一个函数

np.set_printoptions(
suppress=True,# 禁用科学计数法
precision=3,    # 保留3位小数
floatmode='fixed'# 固定小数位数
)

generate_dct_matrices()

x = np.array(); print("输入:", x)
y = dct(x); print("输出:", y)
r = idct(y); print("重建:", r)
ee = np.eye(m.shape)
if ne(np.matmul(m, mt), ee): raise ValueError()
print()

y2 = * N
for i in range(N):
for j in range(N): y2 += mc * x
if ne(y, y2): raise ValueError()

y2 = * N
for i in range(N):
s = ''
for j in range(N): s += f'{ms}*{x} + '
s = s[:-3]
y2 = eval(s)
print(f'{} {s} = {y2:.3f}')
if ne(y, y2): raise ValueError()
print('')

print('恭喜,你(基本)明白DCT了!可M为啥是正交矩阵?!')

a = ms; b = np.array(ms).T; e = [ * N for _ in range(N)]
for i in range(N):
for j in range(N):
    s = ''
    for k in range(N): s += f'{a}*{b} + '
    s = s[:-3]
    print(f'[{i},{j}] {s}')
    e = eval(s)
if ne(e, ee): raise ValueError()
print()

print('如果用上复数(欧拉公式),就可以用等比数列求和公式了!!') 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

褐洌 发表于 2025-11-3 11:18:22

谢谢分享,辛苦了

泠邸 发表于 2025-11-7 10:32:27

鼓励转贴优秀软件安全工具和文档!

谭皎洁 发表于 2025-12-16 08:30:08

懂技术并乐意极积无私分享的人越来越少。珍惜

诞楮 发表于 2026-1-2 13:36:50

喜欢鼓捣这些软件,现在用得少,谢谢分享!

愆蟠唉 发表于 2026-1-15 10:08:32

yyds。多谢分享

摹熹 发表于 2026-1-17 10:38:25

喜欢鼓捣这些软件,现在用得少,谢谢分享!

距佰溘 发表于 2026-1-18 17:18:29

喜欢鼓捣这些软件,现在用得少,谢谢分享!

闵雇 发表于 2026-1-18 23:54:22

这个好,看起来很实用

驼娑 发表于 2026-1-23 03:36:21

谢谢分享,辛苦了

姘轻拎 发表于 2026-1-26 11:51:04

感谢分享,学习下。

岳娅纯 发表于 2026-1-27 08:42:56

用心讨论,共获提升!

乳杂丫 发表于 2026-1-28 01:45:52

感谢分享,下载保存了,貌似很强大

靳夏萱 发表于 2026-1-29 11:57:31

喜欢鼓捣这些软件,现在用得少,谢谢分享!

蒲善思 发表于 2026-1-30 06:36:20

感谢分享,学习下。

蓬庄静 发表于 2026-2-1 04:24:59

谢谢分享,辛苦了

僻嘶 发表于 2026-2-3 04:05:19

这个好,看起来很实用

姚望舒 发表于 2026-2-5 06:19:39

过来提前占个楼

毁抨句 发表于 2026-2-6 04:37:55

感谢分享

侧胥咽 发表于 2026-2-7 23:25:02

感谢分享
页: [1] 2
查看完整版本: 论DCT和IDCT的重要性,汇编SIMD版第一,此贴第二,就是这么狂 :-)