設定ファイルの例

DoxygenFortranソースコードをドキュメント化してみた。その時のDoxyfileのDiffを晒します。

158c158
< JAVADOC_AUTOBRIEF      = NO
---
> JAVADOC_AUTOBRIEF      = YES
354c354
< EXTRACT_ALL            = NO
---
> EXTRACT_ALL            = YES
512c512
< GENERATE_TODOLIST      = YES
---
> GENERATE_TODOLIST      = NO
518c518
< GENERATE_TESTLIST      = YES
---
> GENERATE_TESTLIST      = NO
524c524
< GENERATE_BUGLIST       = YES
---
> GENERATE_BUGLIST       = NO
530c530
< GENERATE_DEPRECATEDLIST= YES
---
> GENERATE_DEPRECATEDLIST= NO
675c675
< FILE_PATTERNS          =
---
> FILE_PATTERNS          = *.f90
681c681
< RECURSIVE              = NO
---
> RECURSIVE              = YES
703c703
< EXCLUDE_PATTERNS       =
---
> EXCLUDE_PATTERNS       = 
793c793
< SOURCE_BROWSER         = NO
---
> SOURCE_BROWSER         = YES
798c798
< INLINE_SOURCES         = NO
---
> INLINE_SOURCES         = YES
816c816
< REFERENCES_RELATION    = NO
---
> REFERENCES_RELATION    = YES
1148c1148
< GENERATE_TREEVIEW      = NO
---
> GENERATE_TREEVIEW      = YES
1289c1289
< GENERATE_LATEX         = YES
---
> GENERATE_LATEX         = NO
1396c1396
< GENERATE_RTF           = NO
---
> GENERATE_RTF           = YES
1417c1417
< RTF_HYPERLINKS         = NO
---
> RTF_HYPERLINKS         = YES
1700c1700
< HAVE_DOT               = NO
---
> HAVE_DOT               = YES
1789c1789
< CALL_GRAPH             = NO
---
> CALL_GRAPH             = YES
1797c1797
< CALLER_GRAPH           = NO
---
> CALLER_GRAPH           = YES
1826c1826
< INTERACTIVE_SVG        = NO
---
> INTERACTIVE_SVG        = YES
1871c1871
< DOT_TRANSPARENT        = NO
---
> DOT_TRANSPARENT        = YES

上からざっと見ていって、必要そうな部分をYESにしただけ。余計なオプションも入ってるかも。

配列構成子の書き方

なじみの薄い配列構成子ですが、うまく使えばコードが綺麗になりそうだったので、サンプルコードを書いてみた。

program main
    implicit none

    integer, pointer :: arr_p(:)
    integer :: arr(3)
    integer, parameter :: n = 3

    allocate(arr_p(n))

    arr_p = (/ 1, 2, 3 /)

    call array_debug_pointer(arr_p, n)

    arr_p(1) = 10
    arr_p(2) = 20
    arr_p(3) = 30

    call array_debug_pointer(arr_p, n)

    arr = (/arr_p(1:2), 3/)

    call array_debug(arr, 3)


    contains
    subroutine array_debug(arr, n)
        integer :: arr(:)
        integer :: n

        integer :: i
        do i = 1, n
            write(*, fmt='(i0, 2x)', advance='no') arr(i)
        end do
        write(*,*)
    end subroutine array_debug

    subroutine array_debug_pointer(arr, n)
        integer, pointer :: arr(:)
        integer :: n

        integer :: i
        do i = 1, n
            write(*, fmt='(i0, 2x)', advance='no') arr(i)
        end do
        write(*,*)
    end subroutine array_debug_pointer

end program main


(/ /)で数値や変数を囲むと配列を一行で直接代入することができるようになります。(/ /)の中には、部分配列を入れたり、数値をそのまま入れたり、ポインタを使用することもできるようです。

出力例

$ ./main
1  2  3  
10  20  30  
10  20  3 

Fortran特有の行列演算の書き方

Fortran90で行列を扱ってみます。配列ではそれぞれの配列要素の演算を簡単な記述で表すことができます。

main.f90

program main
  integer(kind=8), pointer :: matrix(:,:)
  integer(kind=8), parameter :: nele = 3

  allocate(matrix(nele, nele))

  call set_matrix(matrix, nele)
  call print_matrix(matrix, nele)

  write(*,*) "plus 10"
  matrix = matrix + 10
  call print_matrix(matrix, nele)

  write(*,*) "plus matrix"
  call set_matrix(matrix, nele)
  matrix = matrix + matrix
  call print_matrix(matrix, nele)

  write(*,*) "product matrix"
  call set_matrix(matrix, nele)
  matrix = matrix * matrix
  call print_matrix(matrix, nele)

  write(*,*) "division matrix"
  call set_matrix(matrix, nele)
  matrix = matrix / matrix
  call print_matrix(matrix, nele)

  contains

  subroutine set_matrix(mat, n)
    integer(kind=8), intent(inout) :: mat(:,:)
    integer(kind=8), intent(in) :: n

    integer(kind=8) :: l = 1
  
    !allocate(mat(n:n))
  
    do i=1, n
      do j=1, n
        !write(*, fmt='(I4)', advance='no') l
        mat(i, j) = l
        l = l + 1
      enddo
      !print *
    enddo

    l = 1 !< reset

  end subroutine set_matrix
  
  subroutine print_matrix(mat, n)
    integer(kind=8), intent(in) :: mat(:,:)
    integer(kind=8), intent(in) :: n
    do i=1, n
      do j=1, n
        !print '(I5 )', ele
        !write(*, fmt='(I5 )', advance='no'), ele
        write(*, fmt='(I5 )', advance='no'), mat(i, j)
        !write(*, "I5 ") ele
      enddo
        print *
    enddo 
  end subroutine print_matrix

end program main

10を足す場合は
matrix + 10

行列要素同士を足す場合は
matrix + matrix

行列要素同士の掛け算は
matrix * matrix

行列要素同士の割り算は
matrix / matrix

こんな感じです。

C言語ではちゃんとループしないといけないですね。それをFortranでやろうとすると、

do j = 1, jmax
  do i = 1, imax
    matrix(i, j) = matrix(i, j) + matrix(i, j)
  end do
end do

という感じですかね。ちなみに、2次元配列の走査方法がC言語と違うので注意。

コマンドの存在を確認する方法

コマンドが使えるかどうかを確認するシェルスクリプトを作成しました。

実行すると、こういう出力を返してくれます。

 vi         = True (/bin/vi)
 cmake      = True (/usr/local/cmake/bin/cmake)
 ifconfig   = True (/sbin/ifconfig)
 reboot     = True (/usr/bin/reboot)
 asdf       = False

2つの方法があります。

環境変数PATHを使う方法
一つ目は、環境変数PATHの中を捜す方法。これはシンプルで正統的な方法ですが、aliasでパスを通している場合に見つからないという欠点があります。

commandCheckFromPath.sh

#!/bin/bash

function checkCmd() {
  cmd=$1
  IFS=:
  for d in $PATH; do
    if [ -x $d/$cmd ]; then
      #echo "$d/$cmd"
      echo 0
      exit
    fi
  done
  echo 1
}

function printCmd() {
  cmd=$1
  printf " %-10s = " ${cmd}
  if [ `checkCmd ${cmd}` -eq 0 ]; then
    echo "True (`which ${cmd}`)"
  else
    echo "False"
  fi
}

cmds=(
vi
cmake
ifconfig
reboot
asdf
)

for c in ${cmds[@]}; do
  printCmd $c
done

whichの終了コードを使う方法
二つ目の方法は、whichコマンドの終了コードを確かめる方法。whichコマンドを使うとそのコマンドが使えるかどうかを確認してくれますが、コマンドがなかった場合は終了コードが1になるようです。その仕組みを利用してシェルスクリプト内でコマンドの存在可否を確かめます。

#!/bin/bash
cmds=(
vi
cmake
ifconfig
reboot
asdf
)

for c in ${cmds[@]}; do
  which $c >& /dev/null
  rst=$?
  printf " %-10s = " $c
  if [ ${rst} == 0 ]; then
    path=`which $c`
    echo "True ($path)"
  else
    echo "False"
  fi
done

私の環境ではどちらのコードも同じ結果になりました。

数学の分類名を英語にしてみた

Wikipediaの「学問の一覧」から数学のところを抜き出してきて、それぞれ英訳してみた。調べ方は、リンクをたどって英語表記をコピペするだけ。リンクがない場合は適当にググって補完しました。

数学だけでもこれだけあるのですね。全然聞いたことのない分野もたくさん見つかりました。また今度一つ一つじっくりと勉強していきたいところ。数学を最先端で研究している方は多分もっと他にも新しい理論がたくさんあるんだろうなと思うので、これは代表的な一部分だけなんだろうとは思います。

一覧を見てみると、英語のほうが分かりやすい分類名もあったり、よく知ってる言葉でも英語だと知らない単語になっていたり、新しい発見がいろいろありました。このシリーズ、割と良かったのでまた他の分野でもやってみようかな。

学問の一覧 - Wikipedia

数学基礎論 Foundations of mathematics
集合論 Set theory
数理論理学 Mathematical logic
再帰理論 Recursion theory
モデル理論 Model theory
証明論 Proof theory
圏論 Category theory
トポス Topos
数論 Number theory
代数的整数論 Algebraic number theory
類体論 Class field theory
解析的整数論 Analytic number theory
数論幾何学 Geometric number theory
代数学 Algebra
線形代数 Linear algebra
多重線形代数 Multilinear algebra
行列論 Matrix
普遍代数学 Universal algebra
抽象代数学 Abstract algebra
群論 Group theory
環論 Ring theory
体論 Field theory
可換環 Commutative ring theory
束論 Lattice
表現論 Representation
解析学 Mathematical analysis
微分積分学 Calculus
ベクトル解析 Vector calculus
関数解析学 Functional analysis
作用素環論 Theory of operator algebras
実解析 Real analysis
測度論 Measure
常微分方程式 Ordinary differential equation
偏微分方程式 Partial differential equation
複素解析 Complex analysis
超準解析 Nonstandard analysis
調和解析 Harmonic analysis
変分法 Calculus of variations
幾何学 Geometry
位相幾何学 Topology
微分位相幾何学 Differential topology
代数幾何学 Algebraic geometry
微分幾何学 Differential geometry
リーマン幾何学 Riemannian geometry
リー群 Lie group
シンプレクティック幾何学 Symplectic geometry
ユークリッド幾何学 Euclidean geometry
ユークリッド幾何学 non-Euclidean geometry
双曲幾何学 Hyperbolic geometry
楕円幾何学 Elliptic geometry
球面幾何学 Spherical geometry
アフィン幾何学 Affine geometry
非可換幾何学 Noncommutative geometry
射影幾何学 Projective geometry
計算幾何学 Computational geometry
多様体 Manifold
離散数学 Discrete mathematics
組み合わせ数学 Combinatorics
符号理論 Coding theory
グラフ理論 Graph theory
ゲーム理論 Game theory
理論計算機科学 Theoretical computer science
計算理論 Theory of computation
計算可能性理論 Computability theory
計算複雑性理論 Computational complexity theory
確率論 Probability theory
エルゴード理論 Ergodic theory
確率過程 Stochastic process
応用数学 Applied mathematics
統計学 Statistic
多変量解析 Multivariate statistics
人口統計学 Demography
数値解析 Numerical Analysis
最適化問題 Optimization problem
オペレーションズ・リサーチ Operations research
線形計画問題 Linear programming problem
カオス理論 Chaos theory
フラクタル Fractale
数理物理学 Mathematical physics
場の量子論 Quantum Field Theory
統計力学 Statistical mechanics
情報理論 Information theory
暗号理論 Cryptography

Wikipediaの「数学」のところのすぐ下に「計算機科学」の分野が…。こっちから先に調べるべきだったか。

portコマンドのリストを更新する

久しぶりにMac portsを使おうとすると、こんなWarningが出ていることに気づきました。

Warning: port definitions are more than two weeks old, consider using selfupdate

ということで、言われている通りport selfupdateを実行して、さらにport upgrade outdatedを実施しました。

bash-3.2$ sudo port selfupdate
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.1.3 installed,
MacPorts base version 2.1.3 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

The ports tree has been updated. To upgrade your installed ports, you should run
  port upgrade outdated

port upgrade outdatedは新しいバージョンが出ているアプリケーション全てを一括でアップグレードするという意味らしいです。yumだとyum updateをすると自動的にリポジトリのリストが更新されるのですが、portでは個別のコマンドになっているようです。

portコマンドでno destroot foundエラー。

前のcmakeのインストールに関連して。
MacのportコマンドでなぜかOpenSSLが更新できずにしばらく詰まってしまったので、その原因と解決方法。

bash-3.2$ sudo port install openssl
Password:
--->  Computing dependencies for openssl
--->  Installing openssl @1.0.1e_1
Error: org.macports.install for port openssl returned: no destroot found at: /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_openssl/openssl/work/destroot
Please see the log file for port openssl for details:
    /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_openssl/openssl/main.log
To report a bug, follow the instructions in the guide:
    http://guide.macports.org/#project.tickets
Error: Processing of port openssl failed

何度やっても失敗する。原因がよく分からなかったが、cleanして再度installするとすんなり入った。どうやらインストールの際に生成される中間ファイルが壊れていたらしい。

bash-3.2$ sudo port clean openssl
--->  Cleaning openssl
bash-3.2$ sudo port install openssl
--->  Computing dependencies for openssl
--->  Fetching archive for openssl
--->  Attempting to fetch openssl-1.0.1e_1.darwin_11.x86_64.tbz2 from http://jog.id.packages.macports.org/macports/packages/openssl
--->  Attempting to fetch openssl-1.0.1e_1.darwin_11.x86_64.tbz2.rmd160 from http://jog.id.packages.macports.org/macports/packages/openssl
--->  Installing openssl @1.0.1e_1
--->  Deactivating openssl @1.0.1c_0
--->  Cleaning openssl
--->  Activating openssl @1.0.1e_1
--->  Cleaning openssl
--->  Updating database of binaries: 100.0%
--->  Scanning binaries for linking errors: 100.0%
--->  No broken files found.