2023-08-22 14:39:29 +00:00
|
|
|
|
#programming-language #research
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 08:56:00 +00:00
|
|
|
|
## 先行例
|
2023-08-24 11:45:03 +00:00
|
|
|
|
|
|
|
|
|
[[Faust]]
|
2023-08-22 14:39:29 +00:00
|
|
|
|
|
|
|
|
|
|
2023-08-24 11:45:03 +00:00
|
|
|
|
[[The w-calculus a synchronous framework for the verified modelling of digital signal processing algorithms]]
|
2023-08-22 14:39:29 +00:00
|
|
|
|
|
2023-08-24 11:45:03 +00:00
|
|
|
|
## 基礎知識
|
|
|
|
|
|
2023-08-24 12:45:03 +00:00
|
|
|
|
[[Coqの勉強]]
|
2023-08-26 09:27:50 +00:00
|
|
|
|
|
|
|
|
|
|
2023-08-28 13:32:09 +00:00
|
|
|
|
## [[mimium]]と[[多段階計算]]
|
2023-08-26 09:27:50 +00:00
|
|
|
|
|
2023-08-27 17:22:00 +00:00
|
|
|
|
こういうのが計算できなかった(要するにfixpointの中で`self`を使うと必要な`self`のサイズを確定できない)
|
2023-08-26 09:27:50 +00:00
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
fn filterbank(N,input,lowestfreq, margin,Q,filter){
|
|
|
|
|
if(N>0){
|
|
|
|
|
return filter(input,lowestfreq+N*margin,Q)
|
|
|
|
|
+ filterbank(N-1,input, lowestfreq,margin,Q,filter)
|
|
|
|
|
}else{
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
仮に多段階計算だとしてちょっと型を明示してみる
|
|
|
|
|
まあ〜書きづらいよな
|
|
|
|
|
|
|
|
|
|
```rust
|
2023-08-27 17:22:00 +00:00
|
|
|
|
fn gen_filterbank(N:int,lowestfreq:float, margin:float,Q:float,filter:(float,float,float)->float)-> <(float,float,float)->float> {
|
2023-08-26 09:27:50 +00:00
|
|
|
|
// level:0
|
|
|
|
|
if(N>0){
|
|
|
|
|
< //level:1
|
|
|
|
|
|x| {
|
|
|
|
|
filter(x,~(lowestfreq+N*margin),~(Q))
|
|
|
|
|
+ ~( //level:0
|
|
|
|
|
gen_filterbank(N-1,x, lowestfreq,margin,Q,filter)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
<|x|{0}>
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-27 17:22:00 +00:00
|
|
|
|
fn filterbank(input:float, N:int,lowestfreq:float, margin:float,Q:float,filter:(float,float,float)->float)-> float{
|
2023-08-26 09:27:50 +00:00
|
|
|
|
~(gen_filterbank(N,lowestfreq,margin,filter))(input)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
filter同士の足し算を`+`の`infix`でやりたいよねえ
|
|
|
|
|
let多相じゃないよなあこれは
|
|
|
|
|
|
2023-08-27 17:22:00 +00:00
|
|
|
|
ていうかこれそもそも普通に高階関数じゃダメなんだろうか?
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
fn gen_filterbank(N,lowestfreq, margin,Q,filter)->(float->float){
|
|
|
|
|
|input|{
|
|
|
|
|
if(N>0){
|
|
|
|
|
return filter(input,lowestfreq+N*margin,Q)
|
|
|
|
|
+ gen_filterbank(N-1,lowestfreq,margin,Q,filter)(input)
|
|
|
|
|
}else{
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
いやーこれでもif文が展開されるのは実行時だから意味ないのか
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
あー、つまり
|
|
|
|
|
|
|
|
|
|
- ステージ0ではfixpointが使えてfeedが使えない
|
|
|
|
|
- ステージ1ではfeedが使えてfixpointが使えない
|
|
|
|
|
|
|
|
|
|
みたいな定義ができればいいんじゃなかろうか(というか、fixpointが使えるステージとfeedが使えるステージが交互に繰り返し出てくる、とかになればいけるのか?)
|
|
|
|
|
|
|
|
|
|
ステージ0でfixpointを使ったものを評価しきってステージ1に行く時には再帰は有限回の計算に展開されていることになる・・・のでは?
|
|
|
|
|
|
|
|
|
|
これ、同じように
|
|
|
|
|
|
|
|
|
|
- ステージ0でn個の要素数のものとして評価されたリストはステージ1からn要素のタプルとして見える
|
|
|
|
|
|
2023-08-28 03:48:08 +00:00
|
|
|
|
という前から考えていたこととも繋がるのでは?(というか、これが[[Kronos]]でやっている高階ラムダ計算というか、System F$\omega$なのか?)
|
2023-08-27 17:22:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-27 17:28:39 +00:00
|
|
|
|
問題はそれをユーザーに意識させずに書かせる方法かあ、結局Faustはそれができているからこそ強いわけで(いや、[Faustのパターンマッチ](https://ccrma.stanford.edu/~jos/aspf/Pattern_Matching_FAUST.html)は意味論破壊してHygienicとはいえマクロになってるから結局2段階なのか)
|
2023-08-27 17:22:00 +00:00
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
fn lowpass(input,fb){
|
|
|
|
|
(1-fb)*input + fb*self
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2023-08-28 03:48:08 +00:00
|
|
|
|
### Faustとかと比べたときのメリット
|
|
|
|
|
|
|
|
|
|
マクロ部分の生成段階も含めてCやC++のコードとして生成できるのなら、juceの`prepareToPlay`のような関数内でのDSPグラフのパラメトリックな変形(フィルターの次数を変えるとか)が実現できるかも(そこまでのことが求められてるかというと微妙な気もするが・・・)
|
|
|
|
|
|
|
|
|
|
というか果たしてそんなことはできるのだろうか
|
|
|
|
|
|
|
|
|
|
あとは、Faustのエラーメッセージで入出力の数が合わないとかのエラーはマクロ展開後に発生するので、マクロを多用するほどエラーが読みづらくなる問題があるが、それは多分多段階計算の方が読みやすくなる・・・はず
|