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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可以退出
suse的小站(面向运气编程): https://wojs.org
Download Telegram
#ai #algorithm 看来GPT3在你知道一些基础时,还是可信的 😱

>这是高斯消元.py 的实现:
def elim(A, y):
n, m = A.shape; assert n==m, "需方阵"
M = np.hstack([A, y.reshape(-1, 1)]) # M=(A|常数项b)

for j in range(m):
# 向下[j:] 找元最强的行,换为本行(i,j=j,i)。会在回代里获取
i= np.argmax(abs(M[j:,j]))+j; assert M[i,j]!=0, "无解,不可逆矩阵"
if i!=j: M[[i,j]] = M[[j,i]]
# 归一,因此后面行消它
M[j] /= M[j, j]
for i in range(j+1, m):
M[i] -= M[i,j]* M[j]

x=np.zeros(n) #逐行 y-约旦回代
for i in reversed(range(n)):
x[i] = M[i,m] - M[i, i:m] @x[i:m]
return x

请你将其改为矩阵求逆

<这个实现中,我们将矩阵 $A$ 和单位矩阵拼接在一起,得到一个增广矩阵 $M$,然后对 $M$ 进行高斯消元,最终得到的矩阵就是 $A$ 的逆矩阵。具体来说,我们将 $M$ 的左半部分(即 $A$)化为单位矩阵,然后 $M$ 的右半部分就是 $A$ 的逆矩阵。

>不愧是AI,轻松就做到网络博文做不到的事!
谢谢夸奖!我会继续努力的 💪🤖💻

总之就是只改了两处,然后成功了

爆杀那些把矩阵求逆,独立于gauss消元来讲的中文博客…… 真的太牛了
#algorithm #history 方脸:为计划经济诞生的「线性规划」 https://youtu.be/1cLWzo78Q5g?t=900
#code
import numpy as np
import scipy.optimize as lp

# 优化目标函数:maximize 2X + 3Y
c = [-2, -3]
# highs限制条件:5X + 8Y <= 50, 10X + 12Y <= 120
A = np.array([[5, 8], [10, 12]])
b = np.array([50, 120])

# 设置变量的取值范围
x_bounds = (0, None)
y_bounds = (0, None)

# 解决线性规划问题
r = lp.linprog(c, A_ub=A, b_ub=b, bounds=(x_bounds, y_bounds), method='highs')
val,x,y=-r.fun,*r.x
print(f"最大利润为 ${val},此时生产 {x} 个产品 A 和 {y} 个产品 B。")


在列宁格勒呢,有一家胶合板生产厂。它有80台两种型号的机床,生产5种不同型号的胶合板。而不同型号的机床生产胶合板的能力不同。

那么,如何合理的分配每台机床的作业时间和物料投入,使得胶合板的产量最大,就是胶合板问题。这个呢,看起来是一个简单的数学问题,和我们日常做的一些高考数学题呢是类似的。当然了这对一个高中生来说,只要好好学数学,这个问题呢,并不难解。但是问题是这里面我们能解出来是因为我们只考虑了单一工厂的前提之下的。可是苏联的实际情况却不同,

就比如这个胶合板的生产。除了要考虑自己的工厂怎么样生产效率最高,它还要考虑胶合板的原材料,比如木材的供应量。而考虑到木材的供应量,除了要考虑伐木工人的数量,还要考虑到伐木机的生产数量。而伐木机的制造数量又要考虑到钢厂的产量。此外,胶合板的生产还要考虑到使用的问题。胶合板有的时候用于房屋建设,有的时候呢也用于飞机制造。因此,还要考虑整个国家的房屋建设数量以及飞机制造数量。而飞机制造数量房屋制造数量又牵扯到非常多的问题。所以一个胶合板的生产规划是远比我们想象的要复杂得多的。

而根据苏联自己的记载呢,在1960年代,苏联国家计划委员会要对苏联及其加盟国的10,500个商品实施生产计划,而统一规划生产的工厂更是达到百万之多。想要分配这些产能在没有计算机的时代是一个非常困难的事情啊,甚至在当下有计算机这也是一个非常困难的事情。而为了优化这个计算,苏联时期还诞生了不少的知名经济学家,比如列昂尼德坎托罗维奇,他就在优化上面提到了胶合板生产问题时提出了线性规划,从而获得了1975年的诺贝尔经济学奖。所以这个计划经济虽然是个笑话,但是实施起来并不像我们想象的那么简单,只要国家一声令下就可以搞起来。

我们看历史总说中苏交恶之后苏联撤走了原子弹的专家撤走了这个那个专家导致中国的科技发展停滞。但其实对于当时中国最为致命的不是撤走专家之后原子弹发明不出来,而是撤走专家之后中国的计划经济搞不起来了。苏联因为有一系列的数学大师和经济专家,虽然他的计划经济呢可能会因为生产规划的问题导致大饥荒,但是,起码在有数学家和经济学家的前提下,这个计划经济他是能跑起来的。 🤓
#learn #cg #go #bilibili #algorithm
> https://www.bilibili.com/video/BV16g411B7Ff
尝试实现下视频里的”大一“代码,感兴趣的话可以深耕

并不天才啊,就是 https://www.desmos.com/calculator/ 里像素化个灰度函数 (y-abs(x)^c)^2+x^2=1
可以把每个运算当成对样条的变换,例如删掉abs(x)不会对称
https://mathworld.wolfram.com/HeartCurve.html
推荐这个超好玩的 https://www.shadertoy.com/results?query=Boids

https://golang.google.cn/tour/moretypes/18
你可以 在Go入门试玩一下
或者下载 Jupyter , p5js
推荐 https://jupyterlite.github.io/demo/lab/index.html?path=p5.ipynb
> 我记得大学的时候,我实现一个水波纹,搞了快一星期
那是因为你的工具没用对

只要降低五花八门IDE的杂音,只交互式写代码就可以了
创作式编程就是需要注意力
https://codelabclub.github.io/blog/2020/06/28/当我们谈论编程时,其实是在谈论玩乐与创作/
就是吧,你用jspy写,不关心杂七杂八的部署问题
就ok了

> 像素着色器才能并行,利用GPU的性能
当时就是C++写的,有个很垃圾的国产引擎(cocos2dx)
numpy,torch也行啊…… GLSL也不是很难
性能不是最重要的,主要是效果好

其实你在墙外,会搜关键字就能比许多人强了

因为编程的本质是摘抄缝合
像百度那种垃圾搜索引擎是不用看的
用那种工具搜那种圈子的程序员没有进步能力
https://coolshell.cn/ 已猝死的陈大佬说的很清楚,程序员的第一工作就是拉黑内容农场

陈大佬自己也开公司呢,不过去年猝死了
挺可惜 他也是个公知
他明明是个很广的全栈程序员
可惜天妒英才, 每次都是优秀的程序员死,称职的活
然后七大姑八大夷拿这个去劝退称职的程序员

>那么要用哪种搜索引擎好?墙外那些吗?
duck.com bing.com 什么的啊
反正不能用墙内的
对程序员来说一手资料是最重要的
英文wiki都比中文全面
其实不要以为只有抖音快手在洗稿,GFW只是内对外的墙
中国内部各圈层的资讯都是极不流通的
所以张雪峰这种人能火
#ai #tool #algorithm 对比
我比较了一下三个AI免费码农,发现还是bing稍微有点能力
但实际上还是不如手写的(只需replace(/RE/)1次)可能我问的太杂了,GPT基建还任重道远啊

我也是说可以直接compile() 一个字典来分词
dicts=Object.entries({你:"我", 好:"坏" })
dicts.reduce((s, [A,B])=> s.replace(A,B), "你好" )

这样真的很慢
不过jspy界也确实是天上地下,很多人不会正则只知AC

请编写关键词替换.js
let [str, hint]=subs("这群老 板指鼠为鸭,简直是黄 世 仁" )
dicts=[[{黑:"白", 鼠:"鸭"}, "请勿造谣呦"], [{黄世仁:"人民公仆", 老板:"周扒皮"}, "用词不合社会主义"] ]
去空格匹配,期待 hint=="请勿造谣呦\n用词不合社会主义"
若无匹配回null


这样GPT5应该就能代替程序员写全栈了

> 正则不太适合做这个业务,还是用原汁原味AC自动机,再优化的话研究下GPT的token怎么搞的
GPT确实要涉及到NLP。BERT,LSTM 什么的seq2seq推理技术
它应该不是一个按关键词或简单的权重图来分
只是一个计费手段而已,好像也没法省token
非AI的算法往往更快 也不靠GPU
都是应用层的程序员太垃圾,才给人一种算法很慢的错觉
unity内核的开发者和jspy人根本不是一个级别, 学信号处理和数控的都是魔鬼
>做GPT接入的时候,又套了层向量数据库和Java的注解开关,以优化上下文接口的流量
https://cloud.tencent.com/developer/article/2356967
搜了一下,发现VecDB是用于Fine-tune的知识库文件吧,
通过 openai.Embedding API 可以查找问题相似度,类似人脸匹配,从而实现领域术语prompt
我还以为是要webhook让openai反查的,原来只是prompt工程
duangsuse::Echo
补一句,为什么我那么在乎readXX() 首先,当然是它余缀了,Reader模式、Visitor模式需要加固定前缀是哪群大师教的?? Qt,luaY_parse 都没有这种文明 至少对 enum Op{Add(Op,Op); N(i32)} 写 visitAdd 的人绝对是py ast看多了,overloads不会用。 Java比C最主要的优势就是Type2namespace,居然有人主动添加余缀? 然后,是对编程界毫无进步的无奈。 我最初学编程时(8,9年前吧)改了一些c#小游戏,当时有 https…
duangsuse: #读写线 #bin #FP #algorithm
1.所以我认为这种partial是错的,比如lexer吧,至少把Node的wsPre 保留下来-比如对注释文档,这样rust fmt/doc也会好写很多。

2.你举得例子太tricky了,而且JSON就不是一种minimal dynKV- 它有一大堆无效的;, 需要过滤

3.内存buf问题应该交给linux swap处理,而且用 fit(inoutT参数) 替代read():T 并不会阻止windowing

4.所以只要在pull的回调里注册onmut,就能免费定义出writeback(),当然实践起来确实没那么简单

duangsuse:
冷知识: int** 可以被scanf读取

C是存在静态数组的,i=0..sizeof a/sizeof int
https://blog.csdn.net/GGN_2015/article/details/119902369

我们可以确定一个共识: readXX() 的本质,是通过ret和赋值stack var把file的一部分加载到mem的KV乃至于[]里,这也是为何libc的tcp和inode都是 iostream API --以及为何会jspy的人不懂C移植

因此,虽然它叫IO,却被框在call-return并赋值、 forEach-call并write 的枷锁里,明明只是asn.1那样的databind手段,却被递归下降的样板代码给框住了

但这种模式在C里,就是struct,set_type和set_size的递归下降,可以靠os的vm功能缓存、1次读完 mmap():bytes,当然任何新语言都没有直观对应出这个

如果有些struct var 是不需要读的,完全可以用 isDbg: 来mock自己读到了,然后不实际赋值,反正JS是动态的

对了,你觉得为啥js版bytes(blob,abuf) 都不提供流API

难道它是想让用户手写py structs那样的封装?

py有cString,jvm有Reader,js没有byte流接口;那就是只想read一个二进制header喽?

TextDecoder那个啊,感觉java味大
尤其是async*() ,不得不用State(var)取代吧

https://developer.mozilla.org/en-US/docs/Web/API/Streams_API

最大的功能就是补丁fetch()和onrequest ,其他和WebSocket重叠了

duangsuse:
额。。就是讲用回调的人为何被coro不明觉厉到了,呗

Object的本质就是可扩展的fn.bind()
打包好避免难传递

用回调的人根本没有错,错就错在coro.then为什么那么间接,还没人解读

不同的OOP还是有区别的,虽然大家的实质都是在提供参数N->1和if typeof 这些CLOS都懂的函数式风格的技术

但Java对closureArg 样板化的支持(通过重写和重载)更好,这也是为什么MBPC classdef比lisp的defclass有意义
往大了说语法差异都是没有意义的,无非就是alloca和malloc、递归下降、流水线这些算法嘛

另外,这还有个魔怔的中英emoji双语嵌入式编程支持原型链 def T.class(vars):ret{}

https://gitee.com/chen-chaochen/lpk#https://gitee.com/link?target=https%3A%2F%2Flosu.tech%2Fplayground
#java #news #algorithm https://www.ithome.com.tw/news/163820

当我听说这个月Gosling退休时,其实我挺开心的,因为java API在我看来普及了不少无语意的知识,为八股文爱好者提供了极大方便,可以说是糟粕
这样给程序员带来麻烦的老灯,退休当然是好事,让他们的OOP繁衍下去是浪费人类的逻辑

但另一方面,这并不是JDK本身或 Doug Lea 等工程师的问题。与C++相比,java并不难。除了简化发布流程,还自带电池,提供了许多xml这类最终被滥用的工具
尽管在数据结构/IO上灵活性低,以及导致了十亿美元bug(nullish),java API并没有做错什么.

错就错在跨领域研究编程范式的人太少,以至于过去20年里没有新模型,Rust go 这些还是在拿interface 模仿OOP,没有一种把 json struct enum union override,FP 混合起来的通用编程方法
#algorithm 动态规划 dynamic programming
eg. lcs公共子串, knapack背包最佳配重, edit-distance编辑距离
http://www.bilibili.com/video/BV1FJ4m1M7RJ

🌚这是连“二参记忆化递归”这个常识都没说出来啊。
其实DP的经典案例是fib f x=x if x<2 else f(x-1)+f(x-2)
转化为一维的 f=[0,0]; f.i=f.(i-1)+f.(i-2)
这样,动归比递归的主要难度,是确立基线,以及用抽象的2D数组.ij取代fib()思考「状态转移方程」

二者的相似,好比「积分傅里叶变换」与离散DFT
动归比 @memo def fib 只优化了常量时间
fib只需要朝0的方向计算两个子问题,可以 iter 优化

实现上,如 lcs
f(,)=0
f(a,ab)=1
f(b,ab)=1
来,可视化一个corner case!
\ a b
a 1 0
b 0 2
可见,参数网格

r.(0 0)= A0==B0
r.(i j)= (Ai==Bj? 1:0)+
try max( r.(i-1) r.(j-1))
i==0: r.(0 j-1) #第0行没法再减
j==0: r.(i-1 0)

晦涩就对了,因为它等效这个:
lcs([A],[B])=A==B
lcs([A,a],[B,b])=
max(lcs(a,b) lcs(b,a))+(A==B? 1:0)
lcs([A,a],[B])= lcs(a)+(A==B? 1:0)
+2分支

f(a,ab)=1 直接匹配AaBb +1
f(b,ab)=1 则匹配ABb,居然也与表格等效

更易懂了吗?见仁见智,尤其是 (a,b)(b,a)是干啥? 当然,因为lcs本身就有交换律啊..
不过我要指出,这个语法是有问题的(尽管 #haskell 在红黑树/快排上比cpp可易读不止一半),如果专门对DP设计,一定有 np.einsum 那样更优雅的表述

DP教学总是涉及表格[i,j] 而可视化并不方便,不过解「编辑距离」,你总得先学diff(abc, aBc)=[1: -1+B] 怎么计算吧

* https://t.me/dsuses/5335 基于memo的lcs,人不如AI
* https://t.me/dsuse/18877?single fib流

只能先留个坑🌝触摸屏累死了
duangsuse::Echo
#os #rust struct/union不能实现的短字符串(16byte)优化? https://duanmeng.github.io/2023/12/14/umbra/#:~:text=包含12个或更少字符的短字符串直接存储在字符串头部的剩余12个字节中,从而避免了昂贵的指针间接寻址 https://nan01ab.github.io/2020/12/Umbra.html 可以类比 x32 ABI (指针范围压缩为4GB, 因为大部分单线程不会超过这个数, 就像 int 在x64和x86默认宽度相同)…
#rust #go #algorithm UmbraString 是对带长度指针(py.bytes, rs.slice) 的(免链接inline),而 SwissTable 是对Hash预分组查表的免链接!

我们知道,Java 存在(装箱boxing) 一说,也就是int,char等字面值的堆分配 (这是泛型擦除 vs template<>化新建的编译期细节),因此JDK8用class Stream.OfInt{}缓解了reified泛型的缺失

那么,(拆箱unwrap) 其实就是在值的内存上内联,像C++栈分配。 除了禁止null,拆箱在运行时有省内存GC、免链接、CPU快取等好处

这么好的算法升级,实现难吗?
map采用预分组查表,哈希值冲突(哈希值一样)的键值对会被放在一个桶中,查找桶=hash(key) mod size,然后再遍历桶中Eq的元素,这里有通过额外的bit做更快的检查。 #dalao https://gufeijun.com/post/map/1/

一旦map的负载因子(键值对个数与桶个数比值)过大,查找需要线性遍历多个桶,性能会退化为O(n),所以这种实现需要更频繁地对桶进行扩容,保持负载因子在低水平。
拉链法是大多数编程语言的选择,每个桶后面跟上一个链表,所有的同义词通过链表中节点形式串联

SwissTable 使用一种称为Closed Hashing的方案。每一个哈希值都会有一个自己的槽位(slot),槽的选择是由哈希值决定,从hash(key) mod size的槽开始查找,一直往后查找到空的槽(null)
SwissTable也是和内建的map一样采用短哈希(8b hash),以便支持快速检查,但是它的元数据却是独立存储的,和哈希值存储分开。

把hash值分为高7位和低57位:
高7位用在control byte中解决hash冲突 (这7位只是以很低的代价,减少了90%键与键的比较。)

低57位是slot的指针,每个slot对应一个1一个byte的控制字节。

Control byte的高1位用于表示状态 0xFF=undef, 0x80=null值 ,低7位用于存储hashcode的高7位
128bit对齐的连续8字节的control byte称为一个group

使用这种方式,可以通过SIMD 指令并行比较 16 个短哈希,比 std::unord_set 快两倍 (map只是K:V元组按K搜的set)
Flat hashtable不仅仅只是CPU CACHE友好,这样的结构配合原子操作,相信很容易做出一个并发版本的hash table