duangsuse::Echo
711 subscribers
4.24K photos
127 videos
583 files
6.44K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
#plt 呃,这几天眼睛有点疼,那个网页重构也接近尾声了(目的就是交个PR),马上把雄狮扭眼的”热度蹭完“,我就能开始二进制pybind了 ……但是到2月我就必须开始制作一个H5动画礼物,以现在这个效率…… (而且之前说的 Java 入门又鸽子了,尽管对话框和离线javac的问题解决,其他内容还是需费精力 说真的我没一次蹭上国内热度,因为每次都是我趁机学了些”没用的“(比如彩字符画、粒子动画、MBR程序、C指针和数组啦),然后数据不好看 😂 这次也是一样,我用shift重映射圆心距l=1~len 环上像…
对正常人的理解,做编程语言是要能运行的,也有配套代码高亮规则/REPL/网站示例 之类的最低工具集,当然REPL的功能(Tab,历史,高亮)都类似,ANSI终端上 bash 用的 GNU readline 和 node repl{eval,log-writer,completer} 都可以拿来测试

如果说语言是要执行或变成数据(Makefile),
leX-Yacc 的X-Y根本无关这个目的(这个Y根本不是解,因为BNF,PEG本身就是很弱的DSL”领域专有“语言),学下来最后发现自己什么都不会做,一个简单的”数据定义语言“也得费很大功夫
不懂行的人都觉得 school 厉害,其实它各种层面上只教过时的东西,好好想想,如果人家能跟业界平分秋色,为啥不来分一杯羹呢?这又不是传统科学

真正懂编程语言的人不会随意设计(或拓展预处理)语言或类似的东西(隐式注入值,大宏,.),除非这个问题已经到常规写法不能解决的程度(例如 Java 的 null问题和 Builder.this 链),像内联XML和JSON 文法这样的东西,是给常量加糖(混淆语言的数据定义和功能步骤),偶尔用用还乐呵,当个宝就会有人让你知道啥叫行为艺术(配置文件全内联js里,因为默认值垃圾!),所以 #Kotlin 里只有 listOf,mapOf 而无 []{} 数据,老爱复制粘贴的人到这也就顿悟了——原来 Map 是由 Pair<K,V> 组成的..
就像你老重复写一个动词,为许多同类HTTP接口操作专门弄堆fun,不代表你理解框架,只能显得很傻,所以 Kotlin 可以给 fun/A.(T)->R 指定 this (扩展函数)

为什么懂语言结构的处理,反而要(在实验外)规避真正做它? 因为我们明白,若非语言真的优化了一个系统性问题,它只是制造麻烦。知道 for(decl;cond;tail) 很厉害,自由变形AST都能做许多,但也只是玩具——如果我能在编写时避免含糊,就没有后续问题。
如果新语言命名语序和别人相同,那要它干嘛? 否则,就让用户重复学习(例如”汉化“关键词和stdlib),而又不写转译器(Kotlin做得很好),是很头疼的。(没错,我能感到用户的头疼😅

因为我们知道语言也有开销和收益,它不是最终问题,所以不随便创建它。如果你真的把「语言」当成问题,或顺带框架概念去讨论些简单的算法,就会把简单搞复杂、难调试。

>摘要:
举个例子,S表达式就能表示HTML🙃。有人想过拿JSON保存这个吧,但是因为含大量children:[]被怼,但S表达式 (div.wtf (id xx) (a (href xx title 上级)) 就能表示HTML-DOM。
现在不少人就把它的影子当新DSL呢!我们是不是该说这是「历史倒流」呢🌝

毕竟大家开始学编程时都是按直觉的, int n; new ListSeter(){ void f(List a){a[0]=n;} } 里new了的Type实质是函数(SAM单方法接口),而SAM实质又是包含n和算式的数据(闭包),for(i0;i<;i++)for(i in 0..N) 这样都没想过吧。 框架定义,我就用,这是外国 Java 在 Kotlin 出现后如此被动的原因。 😅

你把东西写长,不会让它更”生产“或”可配置“ ”易懂“;写短,不会”更快“或”有内涵“,语义不多不少,它就在那。我觉得这是仍没见过汇编的程序员该有的认识。不知道为什么,重视语义的人很少,仿佛世界上只有语法和”JSON,YAML“这些名字,而操作它们的库API也都是孤立的,并不存在一个”概念“把所有的一切语法和表象连起来。
duangsuse::Echo
我太阳,才发现这个别人能发博文的东西,我竟然连标题和名字都没起,试运行成功贴上就pass了…… 这不是在线教SICP(程序的构造和解释)吗🤪 #lisp #fp #zhihu #statement 放到以前我绝对搞大新闻一样,就像之前仿造(但也没成功)Lice 时专门建了项目画了logo,然后文档拼缀别人的,最后模板代码写完不会了 🙈 但说起来,元编程最后也不过是编程。你了解编程语言,很好,但语言只是载体,美丽的、各种各样的应用才是我们的最终目的。 你能写编译器,很好,但也不过是完成了文本模式和树遍历,加上一些理论。…
尽管王某这篇不够简洁,作为同道的我觉得,这囊括住了上面冰封喜欢一大堆术语的 HOAS ,许多人讲过一切关于解释器的理论,而且没有遮遮掩掩、没有复古命名,与目前我对程序解释的基础认知完全吻合 #plt #ce #recommend
他写这一篇就够了。其他东西没必要再讲了,已经胜过许多人分享捕风捉影的东西了。 全网那么多自称知识的社区,就R大和王垠的多分享最干货,其他的大佬,都仍迷惑在语法和名词上。 我开始了解程序语言理论这三年,所获得的也不过如此嘛。

唯一的缺点是不够明确,只有Racket的版本, Lexical Scope 当年我问冰封他没回答,但看这篇我也没看懂,就只知道不能 getA=(a)=>()=>a 了。其实这些在编译原理都有更直接的解释(函数指针+upvalues外层量)
毕竟当时就是嵌套表都只知道 Map<K,List<V>> 或其翻过来这样"虚表"式查找,不知道eval(e,d) 本身就是ds:List栈.. 更不知道名字!=UUID ,=arg$1 这回事;说白了就是编译原理不是显学,看半天揉杂太多语言特性和C,Lisp之类博文语言的麻烦

如果说王某招生的愿打愿挨(在语言理论人看来就)是在躺着圈钱,那么”学院派“大佬的知乎就是站着昂着脸受拜 ,如果想开培训班过好生活是割韭菜,作为既有能力又看不惯的人,不该反思下这种现象为何存在?
虽然我不会干这种事(未来还是打算做后端),但如果博客做到此科普名气水准,我想做点轻松的职业也不该受到道德苛责吧

偶像崇拜不应该是单向的,尝试接受和质疑大佬的布道也很重要
如果一个人给人不接受质疑的感觉,那么他只是暗示自己有这个资格而已
duangsuse::Echo
#plt 呃,这几天眼睛有点疼,那个网页重构也接近尾声了(目的就是交个PR),马上把雄狮扭眼的”热度蹭完“,我就能开始二进制pybind了 ……但是到2月我就必须开始制作一个H5动画礼物,以现在这个效率…… (而且之前说的 Java 入门又鸽子了,尽管对话框和离线javac的问题解决,其他内容还是需费精力 说真的我没一次蹭上国内热度,因为每次都是我趁机学了些”没用的“(比如彩字符画、粒子动画、MBR程序、C指针和数组啦),然后数据不好看 😂 这次也是一样,我用shift重映射圆心距l=1~len 环上像…
谈谈命名问题。圆座标系(POLar)上,角度和距离一般称 theta-rho , angle/arc-radius 即a-r,这是物理采用较少的几个希腊字
我的物理命名法则用 rl:rotation-length 表示这个,因为编程上a理应代表数组..而一些人也会用r标记角度a记面积 真混乱

对同一个像素图,可用直角(xy)和圆座标(rl)自00点等效描述其上每点位置(座标系的意义就是编码位置),这样就容易进行变换,例如圆翘曲和拧转
->rl=(atan2(x,y), sqrt(xx+yy))
<-rl=(lsinr,lcosr)

画半径=3圆就可用点迭代式(参数方程) lsinr,lcosr (r=0~2pi, l=3) ,这等同于在pol系生成一堆点再映射到xy系。当然位图上不好确认dr=rStep ,所以可用 length(p-p0)<l, r=atan2(yx) 处理圆内点。这个yx是配合 (lcosr,lsinr) 顺序的,具体为啥正弦反在余(co-)弦后我不清楚(补: 因为数学把 正右作0点, sin,cos 的00是正上

比如,笛卡尔心 rho=1-sin(theta) .极座标式 r=a*(1-(sint)) 直座标式 (asint,acost)-(.5sin(2t),.5cos(2t)) t=0~2pi

#define pol(f) float r=atan(p.y,p.x),l=length(p);f;p = l * vec2(cos(r), sin(r));
void mainImage(out vec4 bg, vec2 P){
vec2 p = P.xy/iResolution.xy - .5;
p-=.1;pol(float d=(1.-sin(r))/3.9 -l) bg = vec4(1.,step(d,.001) ,1.,1.);
//pol(l=l*l*1.5)bg=texture(iChannel0, p + .5);
}

为啥笛卡尔能画出心呢?在 funcplot.com 画 1-sinx (即-sinx+1)和 x=2pi 和y=1,对照 r=1-sint 你就能找到答案. 注意数学pol系是从正右逆时针算弧度..天哪 难怪 r=1-cost 是向左的

附带物理命名法表/补上次的:
Array B-paired Config Distance Element Func/File-path Graph
h w y x/item i j-i内i n m-n内n Key/比率 Value Length
Object Predicate条件 Question真假 Rotation弧度 Str/stream Text/template模板
u-二进制 z-深度

记忆法:26字母背一遍,把符号配对就行了: hwyx (h)ijnm (ij)kvl (uvwxy)z,你会发现 for(y in 0..<h)for(x i 0..<w) 正好和 y=i, x=j 对应
duangsuse::Echo
谈谈命名问题。圆座标系(POLar)上,角度和距离一般称 theta-rho , angle/arc-radius 即a-r,这是物理采用较少的几个希腊字 我的物理命名法则用 rl:rotation-length 表示这个,因为编程上a理应代表数组..而一些人也会用r标记角度a记面积 真混乱 对同一个像素图,可用直角(xy)和圆座标(rl)自00点等效描述其上每点位置(座标系的意义就是编码位置),这样就容易进行变换,例如圆翘曲和拧转 ->rl=(atan2(x,y), sqrt(xx+yy)) <-rl=(lsinr…
#math 我补张图。注意t=0,r=1 是从正右逆时针,看绿线以下的区域和”心“的上半。 如果把 1-sint 改成 min(it,1) 会咋样?

然后物理的向量(有r和l 的量)计算(许多JS小游戏里玩家跑跳/重力 都有用,尽管一些人封装的不好 )也是出色的圆座标系简化。它利用了角度无关位置(某点+ 角度*距离 是OK)的事实,在GL里vec2(x,y) length,atan,normalize=it/len 就是向量
duangsuse::Echo
#math 我补张图。注意t=0,r=1 是从正右逆时针,看绿线以下的区域和”心“的上半。 如果把 1-sint 改成 min(it,1) 会咋样? 然后物理的向量(有r和l 的量)计算(许多JS小游戏里玩家跑跳/重力 都有用,尽管一些人封装的不好 )也是出色的圆座标系简化。它利用了角度无关位置(某点+ 角度*距离 是OK)的事实,在GL里vec2(x,y) length,atan,normalize=it/len 就是向量
#statement #dev #math 你觉得我会说”编程到尽头是数学“吗?错。 实际上浮点编程、列表(即矩阵)处理让数学真正走入了现实世界,而流控和步骤算法尽管对有许多hack的图形学没意义,对小游戏却是必须的,比如数学就算不了最短路径和五子棋AI (我不觉得图论是数学,如果真是那样万物皆『数学』,没啥意义了)

编程和数学对一个”非== “的应用都是需要的 ,只有公式而缺乏位置什么也干不了,并没有谁的尽头是谁的说法。
倒不如说获得了编程的数学从无聊的算式推导和缺意义的符号跳出来,变得与现实接轨且更易读有结构了,这对数学而言是种提升,就像精确的思想配合通俗的语言,比中文词性都分不清要好。

如果说数学是抽象的,编程比数学抽象得更严谨更广泛,你可以拿苹果、香蕉这样具体的东西套进 List和Set ,而不是局限于数学表示法不擅长的 {x|x是学生} ,一切求值等号和变形都可执行。 数学函数定义域/值域 就是单参函数参/返值的类型 ,比如 abs:整数->正数|0

仅有数值计算的语言是不完整的,所以编程设计了一套套工具系统,抽象、准确快速、可扩展工程,让单次的纸面变成无数设备上无数地方无数次的调用,不局限于数学或逻辑
这可不是件小事,更不是单靠数学训练就能完工的。

编程可以结合线性代数组的矩阵来配平化学式,也可以结合微积分来做(dot.好像是卷积:十字积之和 吧)神经网络自动调参,它意味着真实语言,思想只有用人能懂的语言说出来才有效果。 编程除了”应用“也能表达思想,只是数学语言写起来特例更多 方便人类变形而已,思想终有一天要成熟。你能说思想和语言哪个重要吗?必须合作才能成事,没有主次。
【2021个人作品合集-Demo reel-哔哩哔哩】 https://b23.tv/T0inTYO
#recommend #cg #bilibili 人和人之间的差距大于人和猴子间的差距…… 🤪
这人2019入门的,两个月人物建模贴图着色就ok,2020就做reel了
php:敏杰语言(确信🌚👍 我整个人都敏捷起来了,使用Jawa和Go
都是些JP玩家讨论 asyncio和netty,orm啥哪个好,还有 C#, Go+ DDD.. 魔怔概念

#Ruby 这里有个2D数组编序的..
def spiral_print m
return '' if m.size == 0
m.map(&:shift).join + spiral_print(m.reverse.transpose)
end
妈耶,这mT真的是2D数组..
spiral_print([
['a','b','c','d'],
['e','f','g','h'],
['i','j','k','l']
])
# -> 'aeijklhdcbfg'

噢螺旋向内啊..能看出先是左侧消1,然后末,然后右、始。所以 while m; puts a.map{shift};a.reverse.transpose! ,果然必须转置90度
duangsuse::Echo
【2021个人作品合集-Demo reel-哔哩哔哩】 https://b23.tv/T0inTYO #recommend #cg #bilibili 人和人之间的差距大于人和猴子间的差距…… 🤪 这人2019入门的,两个月人物建模贴图着色就ok,2020就做reel了
【《有一种美叫数学2》| 用方程表达世界的本质,用代码描绘数学的光彩。-哔哩哔哩】 https://b23.tv/cDXyDUU
#math 推荐一个超级牛的 Matlab 数学可视化作者,虵🐸的校友

运动模拟、椭圆反射、各种3D图形、虚数Koch分形、A* JPS 、集合覆盖问题、傅里叶、梯度下降、卷积图形识别可视化、泰勒展开、微积分逼近,许多种算法,反正是数学的有很多🐱
实在是太 #dalao 了这个,也在做公众号但是就不一样,很nice

A:你说这个文本入场动画咋做的队列啊,两边同时往中间靠?
B:学队列动画学魔怔了!这就是中点切后左右letter-spacing啊
A:你说楼上那个建模大佬是怎么画雪山Mesh的啊,每次选中几点往y+拉?不得很生硬?
B:首先,高程图(bump texture)可以手绘y高度,然后NURBS曲面选几点拉高就是平滑的。 生锈铁锅的光泽/吸收也可以用特殊材质混合着色器
A:不过3D单帧一些本质上是物理效果的部分不知道是手绘还是咋弄呢
B:所以这年头捏人和动画速率很赚钱啊
duangsuse::Echo
https://zhuanlan.zhihu.com/p/34064655 #zhihu #fp 这是个物理爱好者18年的 CPS 解释器实现文 这个代码质量.. 其实我是讨厌看lisp 系的,非常讨厌嵌套括号,而且这个人似乎在代码里插debug print ,以C的方法写Racket .. ,那我就把要点挑出来看看 函数式除了伪递归也可做尾调用优化,当 f=()=>g(), g=()=>1 时g可return 到f.retAddr ,类似函数内联。CPS也是尾调用 显然return/即 callstk.pop()…
#PLT #Kotlin 作为编程语言爱好者的我怎么能「只知其一不知其二」呢? 😤x
我对VM/struct,GC(空闲链表标记清除) 都有了解,可就是不懂栈->寄存器 和 Kotlin CPS 不靠 #JS Generator awaiter 怎么实现 async 调用等待

1. 并不是最大栈高度=寄存器数,1+2*3 按结果看有2个,但其实1就够了
思考 x+2*3 ,其实只要1寄存器,但 x+2*a.n ,因为数字和obj 冲突需要两个,那么 a.n.inc 这样的计算链其实也只要一个寄存器!是关于类型的吗? 尽管Dalvik 寄存器有类型
思考 (1*2)+(3*4) ——是因为运算优先级吗?其实是临时位置! 如果 1*2*3 , (2)*3 的位置就可复用,但 *+* 里先算的俩就需2寄存器,+ 在其一上计算
x+(2*a.n) ,首先 a.n 然后 2* 在其上计算,最后+x ... 其实就是一个SSA问题。 但把+-*/. 变节点并不难,就是分配不知咋写..
后计算的尽量复用先算结果的位置,栈->寄存器指令
break/continue 们串成链表,while 结束回填
if jmp-B a jmp-C else b c 记录俩位置,else 回填 jB, end 回填 jC 。递归下降法兼容 if else if 嵌套

2. Kotlin协程和ES6都是基于变量闭包+状态机化,但 JVM 没有 awaiter(IO loop,负责帮忙等待yield的任务并resume 其func*,因此嵌套等待 yield 就行了)
在状态对象上ES6是 Generator{then,throw},Kotlin 是 Continuation{context,resume/WithException} ,分别在this、末参数
在Lua里是基于 lua_State(虚拟机)单步执行权,就有点像pthread了。 但不管Kt,Py,ES6,Lua 的 await/async 都是基于协程实现。 我觉得 CPS 化的最优雅 😊 新学到

StateMachine 是自动生成基于context的cont.resume实现。 在 suspend? fun 内调用休眠函数自会生成其 Cont 实现,把自己的cont注册给它就行

类似ES6(yield),函暂停的位置肯定有 suspend fun 调用,CPS变换给它加自身cont 参数(这是自动回调吗.. 好吧也算),挂起回调度器Dispatcher ,与 __awaiter 不同的是f把 f1.then(cont=f) 指派好了(ES6就不行,因为你要返回调度队列让它找机会的,不能私自叫then 。但Kt 就支持调用时手动指定何时真Cont)

状态机化就是 swith case 0:f(); st++ return; case 1: 这样的
实现上如果内部 suspend call 此次未挂起,自身也直接继续而不会返回调度
这么说:
runBlocking{
GlobalScope.async{delay}.await
async{delay}//reset timer
}

本来只期望await的暂停,结果全暂停了,因为 runBlocking 会等待所有内部suspend fun

其实就有3断续函数,作用域(基于Scope继承)在它内的 async{} 就等待,外的就得显式 await

https://zhuanlan.zhihu.com/p/156030219
duangsuse::Echo
#PLT #Kotlin 作为编程语言爱好者的我怎么能「只知其一不知其二」呢? 😤x 我对VM/struct,GC(空闲链表标记清除) 都有了解,可就是不懂栈->寄存器 和 Kotlin CPS 不靠 #JS Generator awaiter 怎么实现 async 调用等待 1. 并不是最大栈高度=寄存器数,1+2*3 按结果看有2个,但其实1就够了 思考 x+2*3 ,其实只要1寄存器,但 x+2*a.n ,因为数字和obj 冲突需要两个,那么 a.n.inc 这样的计算链其实也只要一个寄存器!是关于类型的吗?…
Kotlin的方法就是完全自底向上构造 suspend fun 的返回值,调用后立刻返回等 Dispatcher 去cont 那些最底下的 delay 等操作,全OK顶层自然就 return val 了
JS的方法还需要一个 awaiter 去一层层剥开 function* yield 的 Promise 去next(promVal),不像 Kotlin 直接不支持返回值,全交给 cont 参数决定恢复到哪继续了
这样实现 delay setTimeout(f,dt) 只需要把 f=cont.resume 就行了,new Promise((res,rej)=> 都没必要。创建完依赖图后task开始调度,每个 coroutine 直接挂起回调度器,因为把值回馈到哪调用时就决定了,而不是 __awaiter 来负责告诉它们值交给谁

理论上是Kt更优雅,其实数据量上差不多(调用者:父级状态机都要挂起等待),只是JS 用了太多待参对象(Promise 就是等待then队列的),而 Kotlin 的 setTimeout 最后拿到可序列化可执行的 Continuation 供调度
CPS真的妙啊,一般靠调用栈保留上级,但遇到Task就要阻塞栈,占掉1线程,CPS(回调)调用即指定了跳回位置,从栈上撤下来也能再恢复,suspend fun 里调用 suspend fun 就是暂断执行,保存位置等待下级叫自己再继续, Sequence(0){yield(it+1)}.filter{it<10}.toList() 的yield不就是让 filter 决定是否next吗
单靠休眠状态机只能单向转移执行权(协程),CPS回调参就是休眠函数最好的调用约定,比 yield new Promise 广泛,因为浏览器的调度队列才全局可访问,一般得有 fetch.then( this.resume ) 注册(这不还是断续函数自己设回调


其实 ES6,Py 的 func* 和 Lua coroutine Ruby Fiber 都是标准的上下级协程(别再提Go了! 尽拿烂概念营销),而 Kotlin 的状态机+CPS 是不止 yield 1动词的协程;类似于 FP 和 OOP 的关系,后者是不纯的前者

for(x of xs)yield xyield* xs 是否一样?for-of 拿1项交1值,yield* 允许调用方处理值写到哪,好像只是自己能少挂起
但考虑 AsyncGenerator 和 Generator 没有 Array.map 啥的问题,只有「回交」到序列缓冲区是不行的,允许在任何调用里中断更便于编译期优化
(其实ES6 主要提供[...gen(5)]z=gen();z.next().value 的迭代器接口,它还是不支持yield*由调用方负责的,因此 async gen 得再包一层 await aslist..
(说到底 suspend fun 而非yield 是 Kotlin 为完整而非仅回调地解决async“别算我,等完成我算你” 类问题引入的方案,也只能说Kt高瞻远瞩,其他语言有 yield 后开始繁杂了,而Kt保持一站式方案
Forwarded from 螺莉莉的黑板报
哦吼,图标博物馆
Forwarded from Solidot
腾讯视频修改搏击俱乐部的结局

2022-01-24 19:55

国内流视频网站删减影视剧的做法由来已久,但直接修改原版视频的结局做法可能是闻所未闻的。据社交媒体用户报告,腾讯视频被发现修改了《搏击俱乐部》的结局。原版《搏击俱乐部》时长 2 小时 19 分钟, 腾讯版本为 2 小时 7 分钟,除了有 12 分钟内容删减外,腾讯给了原版加入了一个非常和谐的结局:原版中两位男女主角手拉着手站在大楼顶层看着一栋又一栋高楼大厦爆炸倾颓;腾讯版本给了一段英文文字去讲述圆满大结局。
duangsuse::Echo
#statement #dev #math 你觉得我会说”编程到尽头是数学“吗?错。 实际上浮点编程、列表(即矩阵)处理让数学真正走入了现实世界,而流控和步骤算法尽管对有许多hack的图形学没意义,对小游戏却是必须的,比如数学就算不了最短路径和五子棋AI (我不觉得图论是数学,如果真是那样万物皆『数学』,没啥意义了) 编程和数学对一个”非== “的应用都是需要的 ,只有公式而缺乏位置什么也干不了,并没有谁的尽头是谁的说法。 倒不如说获得了编程的数学从无聊的算式推导和缺意义的符号跳出来,变得与现实接轨且…
#math 上面 ai.Xecades.xyz 的数字识别用了卷积网络:(另外 #life 我恢复了。明天交了页面就又继续修补JS最简解释器了,添加更多数据类型、解构、?句和表达式宏、中缀式

其中有一句 ab点积(移动做内点积就是卷积):
let c = MatZeros(a.row, b.col),i,j,k;
for (i = 0; i < a.row; i++)
for (j = 0; j < b.col; j++)
for (k = 0; k < a.col; k++)
c.data[i][j] += a.data[i][k] * b.data[k][j];

它将a横b纵 一个十字叠起来了,核b的大小决定参考旁边的k像素。比如全是透明积也透明

但作为原理的『卷积』1像素=N像素积和是做了,卷的又是哪里,为和要横纵翻转才能用?
2D位图可表现为函数 f(x,y) 卷积核g较小些。卷f,g=Sum[xy] f(x,y)*g(w-x,h-y) 。wh=g.dim 。导数暂不涉及

表达式完全可以预翻转g位图。为何是中心翻转而非矩阵^T,为何是「卷」要从1D信号处理:f(t)*g(1-t) 来
开始为过滤f(t)的噪音,对它进行加权平均:t小的信号才衰减,固靠近当前t 更不平均,于是 f1(t)= f(t)*avg*(1-t) 。即 g=w*(1-t) ,随t下降序列。再Sum[t]f1(t)就是卷积
把f,f1 对照下?会发现 t=0 时g(1)f(0) ,t=1 g(0)f(1) ,连线gf就是反着的,所有位置都反

如果把 g(-t +1~k) ,它的avg*g随t上升, f(1)g(1) 就正确且可滑移k了。
x+y=n 即 y=n-x = -x+n (\形图像) n上升时像卷帘拉起,故名卷积

丢俩骰子,点数和=6 有3种数对:13;22;31 ,卷积就是 Sum[i=1~3]f(i)g(4-i) 。这是对3的切分

卷积核b应用于位图 a 产生大小相等(左上角补了0)的过滤图像, Sum[ij]b(h-i,w-j)*a(i,j) ,实践直接拿dot积就行
b=[1/9]*9 width 3 会模糊图像
b=[-1]*9 width 3 中心=9 会锐化

A: 说起来,那些手机电量20%直接跳5%,还有QQ升级的 20% 直接跳100% 是怎么弄啊
B: 编程一点就是 v>5? v+15 : v ,相当于 x,0~5; 15+x,5~100 的两条线 。数学点用 ease-in 贝兹线,它在0平滑 1正常。纵翻 (1-y)*100。 QQ的就不必1-
duangsuse::Echo
#math 上面 ai.Xecades.xyz 的数字识别用了卷积网络:(另外 #life 我恢复了。明天交了页面就又继续修补JS最简解释器了,添加更多数据类型、解构、?句和表达式宏、中缀式 其中有一句 ab点积(移动做内点积就是卷积): let c = MatZeros(a.row, b.col),i,j,k; for (i = 0; i < a.row; i++) for (j = 0; j < b.col; j++) for (k = 0; k < a.col; k++) c.data[i][j]…
呃,我觉得这位和顶楼的工程式讲法比较好:
在输入信号的每个位置,叠加一个单位响应,就得到了输出信号。
卷积的重要的物理意义是:一个函数(如:单位响应)在另一个函数(如:输入信号)上的加权叠加。
^”书上先反褶再平移,把输入信号当作一个整体(去翻转平移相乘积分),一次算出一个时间点的响应值;而楼主把信号拆开,一次算出一个信号在所有时间的响应值,再把各个信号相加。两者本质上是相同的。

顶楼:
令f(t=1) 衰减是种卷积,如t=1敲锣,锣面震幅随 tNow-1 衰减。接下来 1.2 ,1.4s 也有同样的敲锣。将它们叠起来就成了系统的输出
无论多么复杂的输入信号,我们都可以将其分解为一个个连续的冲激信号

用符号'*'表示卷积,关系式:输入*系统=输出。上面的图2在t=0.4s时的数值,是由图1中蓝、红、绿分别对应的3个单位冲激响应相加得来,
蓝、红、绿3个信号进入系统的时间分别为:t=0s,t=0.2s,t=0.4s,仔细观察,在图1中3个冲激信号对应系统响应的值分别为
系统响应在t=0.4s,t=0.2s,t=0s的值,对应的时间顺序刚好相反(因为.4s时0s 的还没消失),所以要翻转

😅不过有件好事:在计算机图形学 #cg 上 Sobel 边缘检测和各种锐化/平滑 都是无关方向的,如果只是 dot 乘积(各位之和) 其实就是普通列表处理;需要处理声音和图像不需要理解信号处理 #sp 学的术语概念

我想起了滑动平均拨弦声
https://tinyrave.com/tracks/67/remix
#js #code audio
kPluck = 470.0 ,
a = Array(44100 / kPluck >>0).fill(0);//FIFO frequency
a.forEach((x,i)=>a[i] = Math.random() * 2 - 1)//white noise
cyc=(a,i)=>i%a.length,
runAvg=f=>T=>{
let i=cyc(a,T*SAMPLE_RATE>>0); return a[i] = f(a[i], a[cyc(a,i+1)])
}

buildSample=runAvg((a,b)=>(a+b)/2)

当然音质差也可:
kPluck = 470.0 ,
a = Array(44100 / kPluck >>0).fill(0);
a.forEach((x,i)=>a[i] = Math.random() * 2 - 1)

buildSample=T=>{//没平均相邻
let i=T*SAMPLE_RATE %a.length >>0; return a[i] = a[i]/1.01
}

卷积核就是权重,#AI 学习的正好是权重,把权叠到每片像素,所以图片分类器能学习出核的特征,对识别项求和后判断归类
在每个xy 叠加卷积核,就得到输出颜色/灰度 等信号

应用于位图参考 https://zhuanlan.zhihu.com/p/76606892
shadertoy.com/new #GLSL #code
#define v1 float
v1 lumAt(vec2 p){
return dot(vec3(.2126, .7152, .0722),//亮度
texture(iChannel0, p.xy / iResolution.xy).rgb);
}

void mainImage(out vec4 bg, vec2 P){
vec4 c = texture(iChannel0, P / iResolution.xy);
v1 gx,gy, d = sin(iTime * 5.0)*0.5 + 1.5; // kernel offset

// Sobel Kernel
//x
// -1 -2 -1
// 0 0 0
// 1 2 1
//y
// -1 0 -1
// -2 0 -2
// -1 0 -1
#define k(x,y,P,a) v1(a)*lumAt(P+vec2(v1(x)*d,v1(y)*d))
gx=k(-1,-1, P,1) + k( 0,-1, P,2)
+k( 1,-1, P,1) + k(-1, 1, P,-1)
+k( 0, 1, P,-2) + k( 1, 1, P,-1);
gy=k(-1,-1, P,1) + k(-1, 0, P,2)
+k(-1, 1, P,1) + k( 1,-1, P,-1)
+k( 1, 0, P,-2) + k( 1, 1, P,-1);

v1 g = gx*gx + gy*gy;// denoise in the video
v1 g2 = g * (sin(iTime) / 2.0 + 0.5);
bg = c+ vec4(0.0, g, g2, 1.0);
}

lum滤镜 . 这次让我学会了位图擦拭渐变外 的边缘和模糊 以及边角画扭曲 💭视频粒子特效可能需要
我这里还有个中心模糊的:
#GLSL #code https://www.shadertoy.com/view/4ts3Ws
float amount = 5.9;

vec3 shadow(vec2 P){
return texture( iChannel0, .5*(sin(1.)+P) ).rgb;
}

void mainImage( out vec4 bg, vec2 P){
vec2 pC = -1.0 + 2.0 * P.xy / iResolution.xy, p = pC;
vec2 dCopy = (iMouse.xy/iResolution.xy - pC ) / amount;

vec3 g = vec3( 0.0 );
for(int i = 0; i < int( amount ); i++ ){
vec3 c = shadow(p);
g += smoothstep( 0.0, 1.0, c);
p += dCopy;
}

bg = vec4(g/ amount, 1.0 );
}