確率論的整数化、Gitまとめ、複雑ネットワーク生成 (2020/04/28)


メモ

Wolfram Alpha

たまに仕事ででてくる謎の計算を丸投げしている alpha さんですが、微分方程式も mathematica 語で入力すると普通に解いてくれるのを最近発見しました。

解くのに時間かかるやつはダメみたいです。カネ払えばいけるかも。

確率論的な整数化

1.5なら半々の確率で1になったり2になったりするし 1.8 なら8割がた2になる。という整数化があったら便利じゃないですか。つまり、ある実数があったとき、それを整数値をとる確率変数に変換でき、その確率変数の期待値が元の実数になっているという処理です。

class Numeric
  def to_pi
    if self > 0
      (i = self.to_i) + (if rand < (self - i); 1; else; 0;end)
    else
      (i = self.to_i) - (if rand < (i - self); 1; else; 0;end)
    end
  end
end

はい。できました。まぁちょっとどうかという書き方ですが。ではさっそくテストしてみましょう

irb(main):1521:0> PI
3.141592653589793
irb(main):1522:0> Array.new(100000){PI.to_pi}.ave
3.14159
irb(main):1526:0> Array.new(10){PI.to_pi}
[4, 4, 3, 4, 3, 3, 3, 4, 3, 3]

このとおり、円周率なら3時々4というわけです。メソッド名の to_pi は probablistic integer ぐらいの感じです。

これの用途ですが、たとえば長い目で見たら 3.14159... 回ループすることになる、みたいなのが必要な時があるでしょう。 これを使うと簡単に作れますね。

PI.to_pi.times{hoge}

でいっちょあがりです。確率論は非常に強力なのでこれを使えば整数で簡単に任意の実数を表現できるわけです。

ぎっつ

バージョン管理システムわりと面倒というか謎というか理解できない仕組みを多数持っていたところがあったが、 git はわりとよくできているというかこういうものが必要であってかつ具体的に課題を解決することで人々の役に立っているという実感があったので、それを忘れないうちにまとめておきたい。

想定しているのは次の状況である。

ABふたりが同じプロダクツについて作業している。時々開発が分岐して新規機能のテストなどが行われ、うまくいったらメインに統合するのだが、二人でやっているので、うっかりするとAが出した枝は開発に手間取ったりバージョン管理をしくじったせいで古い版からの分岐となってしまい、今さら統合しようとすると異常に大変だったりする、というような状況。

どこかにおおもとのバージョン情報管理場所があり、そこから working copy をとってきて作業をする。おわったら管理所に書き戻す。書き戻さない限りは、手元でいくらでもバージョンをいったり来たりテストしたりすることができる。よさげなものを管理所に書き戻したら、他の人がそれを参照できる。gitは、まぁそういうシステムである。

ということで、初めはおおもとのリポジトリを作らねばならない。空のディレクトリで

git init --bare

これで何もないディレクトリがバージョン管理対象となった。この空のディレクトリを手元にとってくる。

git clone /some/where

それに今作ってるものを全部登録する。まず普通のファイル操作コマンド(cpとか)でフォルダにものをならべたら、

git add .

などとやって

git commit -a -m "starting"

すると手元のワーキングコピーが充実する。しかるのちにこれをおおもとのレポジトリに書き戻す。

git push origin master

masterは何もしないときに最初にできるブランチ(作業系列あるいはそれについたなまえ)です。

何か変更をくわえるときは、それにふさわしい名前の作業系列を作成します

git checkout -b newbranch

作業してcommitしてpushすると先方にも newbranch ができます。

ここでmasterの作業が著しく進み、こっちの newbranch が new でもなんでもなくなってしまう場合があります。

git checkout master; git pull

一旦、本家の最新の内容を手元にとってきます。newbranch に切り替えます

git checkout newbranch

そして

git rebase master 

とやると newbranch が最新版ベースになります。 たまに齟齬が発生します。齟齬が発生したファイルを開いて解消して commit します。ここでやらかしても newbranch がおかしくなるだけです。安心してください。newbranch の用事が終わったら master に書き戻します

git checkout master; git merge newbranch 

論文もこんな感じで書いています。論文なんか自分しか書いてないのになんでこんなことやってるかというと端末が二つあったり昨日と今日だと、もはや個人の同一性は怪しいし到底そんなものに科学の基盤を置くことはできないという事です。わりと簡単に差分を参照できるので非常に良いです。

オーサリング環境

長年使ったpsgmlモードが動かなくなり、直し方も完全に解らないため長年放置していたわけですが、 このほど学位論文も提出して若干心の余裕ができたのでnxmlモードというものに移行しました。やってみりゃどうってことなくて わりと簡単でした。適宜permalinkを生成するコードとかimage linkを生成するコードをpsgmlの上に自作していたわけですが、 そこは今回フルスクラッチにしました。といってもどうってことなくて、なんたらmarkup languageって結局のところは S式じゃないすか。作ったツリーをevalすると何たらmarkup languageになりゃいいわけですよ。

image link を手軽に生成するのは案外大変で、回転方向をexifデータから取り出して方向を揃えた上でサイズを揃える、という処理があるわけですが、いろんなデータが来ても間違いなく動く必要があります。ただ、まえ作ってたやつがシェルコードの実行とその結果の取得、 文字列を連想リストにする、などに適宜分割されていてそれらは一切いじる必要がなかったのでけっこうすぐに移行できてしまいました。

Complex Network Generating Model and its Implementation

In this section I will describe a complex network generating model which produces (theoretically) any size of network with arbitrary power-law degree distribution.

The model is basicly that of Price's, a simple preferential attachment. Price's model describes a process of growing of network as a successive steps of adding each node. Added node obtaines a link to the existing node, which is chosen based on the probability proportional to the number of links of the existing node.

It means older node tends to have more links and if the node has more links, it is more likely to obtain additional link, which is commonly referred to as "preferential attachment".

For precise discussion of how power-law distribution is realized from preferential attachment based on master equation can be found in Section 13.1 of Mark Newman's "Networks", second edition.

The code listed below generates a network specified by

  def Ngraph.prefa(size: 100000, power: 2.0, mindeg: 1.0)
    deglb=mindeg.to_pi
    nodes = (0..deglb).to_a
    links=nodes.combination(2)

    (size-nodes.length).times{|i|
      anode=i+2
      nodes.push(anode)
      vee=nil
      mindeg.to_pi.times{vee=links.sample.sample ; links.push([vee, anode].shuffle)}

      alt = (mindeg*(2-power)/2/(power-1)).to_pi

      if alt > 0
        alt.times{
          vo=links.sample.sample
          links.push([vee, vo].shuffle) if anode != vo
        }
      else
        (-alt).times{links.delete_at(rand(links.length))}
      end
    }

    pfn=Ngraph.new
    pfn.vertex=nodes
    pfn.edge=links
    pfn
  end

The default values for vertices population, power-law distribution's power value and minimum degree are ten thousand, 2.0 (in terms of probability density, it is 3.0) and 1.0.


記事リストへ