トップ 追記

日々の流転


2015-07-04 [長年日記]

λ. CTF for ビギナーズ 2015 東京 に参加してきた。

CTF for ビギナーズ 2015 東京 に参加してきた。事前配布された資料を読んで比較的簡単そうという印象だったけれど、実際に講義で手を動かしてみたら良く身につきそうで、想像以上に良かった。

最後のCTF実践には「↻」という名前で参加。 16問中13問を解いて、4600点中3200点で、103人中6位だった。実際にCTFに参加するのもとても面白く、はまってしまう人が多いのも理解できた。講義で扱った範囲だけで楽しめる問題をこれだけ作るのは大変だったのではないかと思うし、運営の人たちには本当に感謝したい。

CTF問題メモ

以下、問題のメモを、解き方を忘れないうちに書いておく。 落ち着いて考えれば全問解けたのではないかと思うと、ちょっと悔しいが、初心者なのでまあ仕方ない。

問題1. 練習問題(まずはここから)(最初にこれを開く)(これを解いてから他の問題をやる) (その他 100)

フラグをsubmitする手順の練習問題。

問題2. Can you login as admin? (Web 100)

ユーザ名とファイル名を指定してログインするシステムで、SQLインジェクションを使ってadminでログインする。 講義でやったとおり「' OR 1=1; --」みたいなのを入れたら通った。

問題3. Find the flag (Web 200)

「Flag is hidden in HTTP traffic.」とあって、HTTPヘッダにフラグが書いてあったのだと思うけれど、詳細は忘れた。

問題4. 1M4G3 V13W3R (Web 300)

画像のアップローダが与えられていて、アップロードされた画像は「view.php?file=076b74f36eee552c.jpg」などのようなURLで参照されていた。 「view.php?file=ファイル名」中のファイル名を適当に書き換えると、どうも「images/ファイル名」からファイルを読んでいるようだったので、「view.php?file=../view.php」と「view.php?file=../index.php」でスクリプトをゲット、スクリプト中のコメントにフラグが書いてあった。

問題5. SQL Injection Level2 (Web 400)

SQLインジェクションの2問目。今度はユーザ名は適切にエスケープされていて、パスワード中にORは使えないそうな。 SQLには不慣れなので、SQLを想像して攻撃するのだと自分には難しいだろうなぁ、と思っていたけれど,適当な文字列をいれてログインを試したところ、実行されたSQLがヒントとして表示され、これなら何とかなるかなと思って考えてみる。

どうも「SELECT username FROM users WHERE username = 'ユーザ名' AND password = 'パスワード';」というようなSQLが実行されているようだったので、これは講義中にやったUNIONのやつだと思って試行錯誤。 不慣れなので何回か試したけれど、最終的にはパスワードに「' UNION SELECT 'admin'; --」的なやつを入れていけた。

後で解説を聞くと、ORは一回だけしか消去していなかったそうで、「OORR」とかしても良かったらしい。 しかし、よくよく考えてみると、パスワードにORという文字列が含まれてはいけないサイトって、サイトとしての根本的な機能に問題がある気が……

問題6. Universal Web Page(笑) (Web 500)

「?lang=en」で英語版、「?lang=ja」で日本語版が表示されるようなサイトが与えられていて、フラグはindex.phpに書かれているそうな。「en」や「ja」の部分を書き換えてみると、その名前のファイルをincludeしているらしいので、「?lang=index.php」としてみたが、どうもphpプログラムの実行エラーになってしまってファイルの中身自体は表示されず。 きっとPHPの変態的な機能を使うと、いけると思ったのだけれど、調べてもよく分からず、行き詰まった。

あとで解説を聞くと、「php://filter/convert.base64-encode/resource=」というのを使えばよかったらしく、事前講習資料ではこの機能についても説明されていたようだ。うぐぐ。 しかし、PHPは一体何を考えてincludeにこんな機能を用意しているのやら。 あと、CTFのために、そうでなければ(自分は)学ばないであろうPHPをあえて、しかもこんなマイナー機能を学ぶのもなぁ、という辺りでちょっとモヤモヤする。

問題7. Insecure Protocol (Network 100)

pcapファイルが与えられているので、Wiresharkで開くとTELNETだったのでFollow TCP Streamすると、パスワードがフラグになっていた。

問題8. Insecure Protocol 2 (Network 200)

pcapファイルが与えられており、Wiresharkで開くとTELNETで、こっちはログイン後にフラグが表示されている感じだけれど、肝心のフラグ部分がマスクされている。 対象のホストにtelnetで繋いでpcapファイル中のユーザ名とパスワードでログインするとフラグが表示された。 なんか、telnetコマンドの使い方でちょっとハマった。

問題9. File Transfer Protocol (Network 300)

pcapファイルが与えられており、Wiresharkで開くとftpの通信らしい。ファイルの一覧を表示後、1.txt, 2.zip, 3.txt というファイルをダウンロードしているようだったので、ftp-data でフィルタリングした後に、Export Select Packet Bytes で適当にファイルとして保存し、書かれていてた内容を連結してフラグをゲット。

問題10. This quiz is a NETWORK challenge (Network 400)

今度はpcapファイルではなくexeファイルが与えられている。 実行してみると謎のメッセージが表示される。 ネットワーク問題なので、どうせWiresharkで通信をキャプチャするんだろう、と思ってキャプチャしてみると、Basic認証付きで表示メッセージのデータを取得した後に、Basic認証無しでflag.txtにアクセスしようとして失敗していた。 なので、最初のBasic認証のデータを(base64デコードした上で)使って、ブラウザからflag.txtにアクセスしたらフラグが読めた。

問題11. Communication (Network 500)

pcapファイルが与えられていて、Wiresharkで開くとHTTPっぽかったので、 File → Export Objects → HTTP したところ、lime240.exe (LimeChat?)、rfc1459.txt (IRCのRFC)、trafficというファイルをダウンロードしていていた。trafficを保存するとこれはzipファイルになっていて、中からtraffic.pcapが出てきた。これをWiresharkで見てみるとIRCの通信っぽい。中に「ctf4b{ }」という文字列があるのは発見したが、この個数分の空白をとりあえずsubmitしても不正解、というところで時間切れ。

lime240.exeを保存した上で、それを使って traffic.pcap の中身に従って、IRCサーバに接続して同じことをしてみれば、マスクされていないフラグが表示されたのかな……多分。

問題12. NOT onion (Binary 100)

exeファイルが与えられていて、fileでgifファイルとわかったので、gifとして開いたらフラグが表示された。 画像ファイルからフラグを書き写すのが一番面倒くさい部分だった。

問題13. 読めますか?(Binary 200)

なんか表示できない変なpngファイルが与えられたので、とりあえずstringsしてctf4bでgrepしたらフラグをゲット。 pngとして表示できなかったのは、無理やりファイルを書きかえてpngとして不正なファイルになっていたためか?

問題15. READ and BURST (Binary 300)

アセンブリの実行結果を問う問題。 計算すれば良い。

問題16. DETECTIVE IDA (Binary 400)

謎のファイルが与えられていて、fileコマンドで判別するとexeファイルで、実行すると Passphrase を問われる。 IDA Pro 上で実行して Set IP で Passpharase の判定結果の分岐を正しい方に変更してみるも、文字化けした結果しか出力されず。 多分、パスフレーズのデータも使って復号化する形になっているのだろうと思い、IDA Pro の画面上のディスアセンブル結果でもパスフレーズっぽい文字列が表示されているのも見つけたが、IDA Pro の使い方がよくわからず、色々やっているうちに時間切れ。 後で解説を聞くと、文字列を照合する際の長さとかに注意して、ちゃんと追えばよかったらしい。

問題17. 5394 (Binary 500)

アセンブリの実行結果を問う問題その2。 ループを含む処理になっていて、手で考えるのが面倒臭かったので、とりあえずRubyに書き換えて実行し、フラグをゲット。

問題14?

あと、問題リストをよく見たら、14番めの問題が欠番になっていたことに気づいた。 ひょっとしてURLを書き換えてアクセスすると、隠し問題があったりしたんだろうか?

関連リンク

Tags: security

2014-04-30 [長年日記]

λ. IOモナドでヒープ割り当てを強制される件

Haskellでプログラムを書いていて、数年以上ずっと悩んでいる点として、

sumI :: UArray Int Int -> Int -> Int -> Int -> Int
sumI a i end ret
  | i <= end  = sumI a (i+1) end (ret + (a ! i))
  | otherwise = ret

みたいな関数だと、UArray Int Int -> Int# -> Int# -> Int# -> Int# という型のワーカ関数が生成されるので、結果を即消費するような場合にはヒープ割り当てが発生しないのに対して、

sumM :: IOUArray Int Int -> Int -> Int -> Int -> IO Int
sumM a i end !ret
  | i <= end = do
      x <- readArray a i
      sumM a (i+1) end (ret+x)
  | otherwise =
      return ret

みたいな関数だと、IOUArray Int Int -> Int# -> Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #) という型のワーカ関数ではなく、IOUArray Int Int -> Int# -> Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int #) という型のワーカーしか生成されず、Intが必ずヒープ割り当てされてしまう。

通常は大して問題にならないのだけど、凄まじい回数呼ばれる関数だと、それが積もり積もってプログラム全体のメモリ割り当ての数割を占めてしまったりして、そういう場合にはGCプレッシャーも馬鹿にならないので、出来ることなら1バイトたりともヒープ割り当てしたくないのである。 望む worker-wrapper transformation 結果を手で書いてしまえば良いのだけれど、GHC拡張に依存したコードを直書きするのも気が引けることもあって……

Tags: haskell
本日のツッコミ(全2件) [ツッコミを入れる]

ψ mkotha [ご存知かもしれませんがJoachim Breitnerさんがこの問題に取り組んでますね https://ghc.ha..]

ψ さかい [おお。知らなかったです。ありがとうございます!]


2013-12-31 [長年日記]

λ. 2013年振り返り

2014年を迎えるにあたって、2013年を簡単に振り返ってみる。

月毎の主なイベント

1月
Coursera での学習を開始。昨年末に買ったNexus7で初めてのAndroid経験&初代iPadから乗り換え。
2月
スキーで転けて靭帯損傷。
3月
『型システム入門 プログラミング言語と型の理論』出版と出版記念トークイベントMax-SAT Evaluation 2013 に参加。
4月
特になし
5月
Haskellで計算機代数勉強会を開催。Google Code Jam 2013 は去年に引き続いて今年も体調的に微妙で微妙。
6月
某自社の株主総会見てきた。
7月
スカイツリー昇った。ICSE'13勉強会でT芝チームとして発表。 奥歯抜歯Coursera MeetUp Tokyo に参加。
8月
ICFP Contest 2013 に例によって Team Sampou で参加。引越しと一人暮らし開始。SPLC2013の併設ワークショップFMSPLE 2013で発表。
9月
ウサギと同居開始。
10月
結婚(といっても婚姻届を出しただけで、結婚式はまだ)
11月
電機連合第34回技術者フォーラムに参加。2013川崎国際多摩川マラソンに参加。
12月
川崎グランシティモール実証実験開始

Coursera

前から少し気になっていたCourseraを1月に試してみて、最終的に以下の9コースを履修。

  1. Computing for Data Analysis by Roger D. Peng @ Johns Hopkins University
  2. Data Analysis by Jeff Leek @ Johns Hopkins University
  3. Linear and Discrete Optimization by Friedrich Eisenbrand @ École Polytechnique Fédérale de Lausanne
  4. Machine Learning by Andrew Ng @ Stanford University
  5. Developing Innovative Ideas for New Companies: The First Step in Entrepreneurship by James V. Green @ University of Maryland, College Park
  6. Model Thinking by Scott E. Page @ University of Michigan
  7. Maps and the Geospatial Revolution by Anthony C. Robinson @ The Pennsylvania State University
  8. Introduction to Computational Finance and Financial Econometrics by Eric Zivot @ University of Washington
  9. Introduction to Recommender Systems by Joseph A Konstan and Michael D Ekstrand @ University of Minnesota

自分のスキルのポートフォリオに追加したいと考えたものを中心に、それなりに戦略的に学習してみたつもり。上手くいった部分もあればそうでない部分もあるけれど。自分はデータ分析や統計に関しては大学1年のときに、ほぼ必修の位置づけだった「データ分析」の授業を途中で飽きて切ってしまってから、ほとんど学習しないままになってしまっていたので、その辺りを補完できたのは良かった。

そして、7月にCoursera MeetUp Tokyoに参加したところ、その縁で、メディアで取り上げらることになったのは、なかなか貴重な体験だった。

新しいプログラミング言語、環境

「毎年少なくとも一つの言語を学習する」という話があるけれど、今年は Coursera のコースで割と色々な言語を学べた。 Computing for Data AnalysisData AnalysisIntroduction to Recommender Systems では R を、Linear and Discrete Optimization ではPython (とSymPy)を、Machine Learningでは MATLAB/Octave に触れることができた。その後、そのうちのRとPythonは仕事でもそれなりに使うようになったので、結構役立っている。

それから、言語というほどではないけれど、Model Thinking では NetLogo に、Maps and the Geospatial Revolution では ArcGIS Online に触った。 あと、Introduction to Recommender Systems で使った LensKit は、アノテーションなどを活用したJavaの今風なDIを使ってて、ちょっとおぉと思ったりなんかもした。

『型システム入門 プログラミング言語と型の理論』出版

Benjamin C. Pierce の Types and Programming Languages (TAPL) の訳書『型システム入門 プログラミング言語と型の理論』を出版。前回のAlloy本こと『抽象によるソフトウェア設計−Alloyではじめる形式手法』が終わり、2011年9月からTAPL翻訳が本格始動したのだけれど、それから1年半ほどかかって、ついに出版にこぎ着いたのがこの3月で、非常に感慨深かった。また、共訳者、監訳者、編集者、レビュワー、皆素晴らしい人達ばかりで一緒に仕事をできて光栄だった。出版記念トークイベントという珍しい体験もしてしまったし。

靭帯損傷

2月にスキーで転けて靭帯損傷。内側側副靭帯損傷の2度で、MRIを初体験したり、しばらくギプス(正確にはギプスシーネ)と松葉杖で不便な生活をしたり、さらに結構な間リハビリをしたりとか。 ギブスしてると、立ってても座っててもバランスが悪くて、体中凝って仕方なかったのが辛かった。 後、しばらくギプスとサポーターをしてるだけで、関節って本当に曲がらなくなるんだなぁ。リハビリしてだんだん動くようになって、人間の関節や筋肉って本当によくできてるなぁと思った。 大変な体験だったけれど、周囲からは非常によくしてくれたし、結構学ぶことのあった体験だったと思う。

ランニング

ランニングは500kmの目標を立てていたけど、途中怪我で数ヶ月走れなかったこともあって、320kmほどに留まった。でも、我ながらよく続いたなぁと思うし、自分を誉めてあげたい。 また、大会に参加するという目標は2013川崎国際多摩川マラソンに参加するという形で達成。 目標がハーフマラソンだったのに対して8kmになってしまったので、ハーフマラソンを走るのは2014年の目標に持ち越し。

あと、昨年末にちゃんとしたランニングシューズを買ったけれど、今年は心拍計 Wahoo Blue HR とか、活動量計 Misfit Shine とか、ランニング用のスポーツタイツのCW-Xとか色々と買ってしまった。

お仕事

Courseraで学んだデータ分析・機械学習系の知識を活かして、これまでとちょっと違った方面の仕事に挑戦してみた1年で、川崎グランシティモール実証実験 なんかにも関われて、まだまだこれからだけれど、面白い仕事ができた。

その他にはFMSPLEで発表したりとか。

計算機代数

代数的実数や量化子除去に関して勉強したり簡単な実装をしたりしていたので、思いきって Haskellで計算機代数勉強会という勉強会をゴールデンウィークに開催。結構マニアックなトピックにも関わらず参加者20人以上も集まり、なかなか楽しかった。 その後も、Berlekamp-Zassenhaus アルゴリズムを理解して実装したりとちょっとは進めた。あと、これまでなんとなくしか理解できていなかった sugar flavor とか syzygy とかについて、計算機代数勉強会での@mr_konnさんの発表で理解できて、自分でも実装してみようと思っていたけれど、これは実装しないままになってしまったなぁ……

Max-SAT Evaluation 2013

昨年は Pseudo Boolean Competition 2012 に参加したが、今年は開催されなかったので、代わりに Max-SAT Evaluation 2013 に参加。 今回は自分のtoysatに加えて、GLPKSCIP に簡単なフロントエンドを付けたもので参加。

自作のtoysatの方は、昨年の Pseudo-Boolean Competition 2012 ではそれなりに健闘した(と思ってる)けれど、今回はあまり振るわなかったねぇ。 まあ、色々とやりたいことはあったけれど、結局、目的関数値の線形探索ベースの単純なアルゴリズムのやつで投稿してしまったからなぁ……

SCIPの方は、SCIP本体のバグが見つかって、SCIP開発者に報告・修正してもらったものを再投稿させてもらったりと、意外と大変だったけれど、その甲斐もあって Partial Max-SAT 部門の Crafted ベンチマークで2位に入賞して嬉しかった。(別にフロントエンドを書いただけの自分がすごい訳ではないのだけれど)

英語

英語は今年はあんまり頑張れなかった。 Courseraでは英語を使って学習してはいたし、日本開催の国際会議SPLC2013の併設ワークショップFMSPLE 2013で発表はしたものの、海外には一回も行かなかったし。それに、レアジョブも後半は殆どやらなくなってしまったしなぁ。2014年はその辺りもっと頑張りたいところ。

関連エントリ


2013-12-03 [長年日記]

λ. 自動微分でロジスティック回帰

自動微分を使って線形回帰をしてみる」と「nonlinear-optimizationパッケージで遊ぶ」で線形回帰をして遊んでみたので、次は予定通り自動微分でロジスティック回帰を試してみることに。 例として何を使おうか悩んでいたのだけれど、たまたま ロジスティック回帰で分類を試す - Negative/Positive Thinking (2013-11-29) という記事を(@chezouさんのtweetで)見かけたので、これと同じデータで試してみることにした。

使用するデータ

というわけで、使用するデータはこれ。

コード

実装にはnonlinear-optimizationパッケージを、自動微分を行うadパッケージと組み合わせて便利に使うための、拙作のnonlinear-optimization-adパッケージを使用。

コスト関数としては Courseraの Machine Learning のコースで扱った形の、正則化なしのコスト関数と、L2正則化を行うコスト関数の場合の両方を試す。

import Control.Monad
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Numeric.Optimization.Algorithms.HagerZhang05.AD as CG
import Text.Printf

main :: IO ()
main = do
  trainingData <- liftM parse $ readFile "a9a"
  testData     <- liftM parse $ readFile "a9a.t"

  let features :: Set String
      features = Set.unions [Map.keysSet fs | (_, fs) <- trainingData]

      cost, costReg :: RealFloat a => Map String a -> a
      cost theta    = sum [ if y then - log p else - log (1 - p)
                          | (y,x) <- trainingData, let p = h theta (fmap realToFrac x) ]
                      / fromIntegral (length trainingData)
      costReg theta = cost theta + (lambda / (2 * fromIntegral (length trainingData))) * sum [x**2 | (feat,x) <- Map.toList theta, feat/=""]

      params = CG.defaultParameters
               { CG.printFinal  = True
               , CG.printParams = True
               , CG.verbose     = CG.Verbose
               , CG.maxItersFac = 50 / fromIntegral (1 + Set.size features)
               }
      grad_tol = 0.00001
      theta0 = Map.fromAscList [(feat,0) | feat <- Set.toAscList (Set.insert "" features)]

  (theta1, _result1, _stat1) <- CG.optimize params grad_tol theta0 cost
  (theta2, _result2, _stat2) <- CG.optimize params grad_tol theta0 costReg

  forM_ [("without regularization", theta1), ("with regularization", theta2)] $ \(s, theta) -> do
    printf "[%s]\n" s
    forM_ [("training set", trainingData), ("test set", testData)] $ \(name, samples) -> do
      let correct  = filter (\(y,x) -> predict theta x == y) samples
          accuracy :: Double
          accuracy = fromIntegral (length correct) / fromIntegral (length samples)
      printf "  %s accuracy: %d/%d = %f %%\n" name (length correct) (length samples) (100*accuracy)

-- regularization parameter
lambda :: Num a => a
lambda = 1

-- hypothesis
h :: RealFloat a => Map String a -> (Map String a -> a)
h theta x = sigmoid $ sum [(theta Map.! feat) * val | (feat, val) <- ("", 1) : Map.toList x]

predict :: Map String Double -> (Map String Double -> Bool)
predict theta x = h theta x > 0.5

sigmoid :: RealFloat a => a -> a
sigmoid x = 1 / (1 + exp (-x))

parse :: String -> [(Bool, Map String Double)]
parse = map f . lines
  where
    f l = (readInt w > 0, Map.fromList [(name, read val) | s <- ws, let (name,_:val) = break (':'==) s])
      where
        (w:ws) = words l
        readInt :: String -> Int
        readInt ('+':s) = read s
        readInt s = read s

ちょっと試してみたところなかなか収束しなかったので、参照したブログと同じくイテレーション回数50回で打ち切ることに。これは、nonlinear-optimizationパッケージのoptimize関数は、イテレーション回数の指定がパラメータ数に対する倍率になっていて、ちょっと面倒だった。

結果

結果は以下のとおりで、参照したブログの数字ともほぼ一緒だし、まあこんなものだろう。

[without regularization]
  training set accuracy: 27644/32561 = 84.89911243512176 %
  test set accuracy: 13846/16281 = 85.04391622136232 %
[with regularization]
  training set accuracy: 27648/32561 = 84.91139707011456 %
  test set accuracy: 13850/16281 = 85.06848473680978 %

2013-11-28 [長年日記]

λ. nonlinear-optimizationパッケージで遊ぶ

自動微分を使って線形回帰をしてみる」の続きで、最急降下法を自分で書いてみるかと思ったのだけれど、そういえばHackageにnonlinear-optimizationパッケージというのがあったのを思い出した。以前から、一回試してみたいと思っていたパッケージだったので、せっかくなのでこれを試してみる。 試してみるバージョンは現時点での最新版の0.3.7で、Hager and Zhang *1 のアルゴリズムを同著者らが実装したCG_DESCENTライブラリのバインディングが提供されている。

nonlinear-optimizationパッケージのAPIはadパッケージのgradientDescent関数に比べるとちょっと面倒臭いAPIだけれど、前回のコードを書き換えてみたのが以下のコード。 nonlinear-optimizationパッケージは自動微分とかはしないので、勾配を計算する関数を明示的に渡す必要があり、adパッケージのgrad関数で自動微分した結果の関数を渡すようにしてある。

module Main where

import Control.Monad
import qualified Data.Vector as V
import Numeric.AD
import qualified Numeric.Optimization.Algorithms.HagerZhang05 as CG
import Text.Printf
import qualified Text.CSV as CSV

main :: IO ()
main = do
  Right csv <- CSV.parseCSVFromFile "galton.csv"
  let samples :: [(Double, Double)]
      samples = [(read parent, read child) | [child,parent] <- tail csv]      
      -- hypothesis
      h theta x = (theta V.! 0) + (theta V.! 1) * x
      -- cost function
      cost theta = mse [(realToFrac x, realToFrac y) | (x,y) <- samples] (h theta)
  (theta, result, stat) <-
    CG.optimize
      CG.defaultParameters{ CG.printFinal = True, CG.printParams = True, CG.verbose = CG.Verbose }
      0.0000001                  -- grad_tol
      (V.fromList [0::Double,0]) -- Initial guess
      (CG.VFunction cost)        -- Function to be minimized.
      (CG.VGradient (grad cost)) -- Gradient of the function.
      Nothing                    -- (Optional) Combined function computing both the function and its gradient.
  print theta

-- mean squared error
mse :: Fractional y => [(x,y)] -> (x -> y) -> y
mse samples h = sum [(h x - y)^(2::Int) | (x,y) <- samples] / fromIntegral (length samples)

で、これを実行してみると……

PARAMETERS:

Wolfe line search parameter ..................... delta: 1.000000e-01
Wolfe line search parameter ..................... sigma: 9.000000e-01
decay factor for bracketing interval ............ gamma: 6.600000e-01
growth factor for bracket interval ................ rho: 5.000000e+00
growth factor for bracket interval after nan .. nan_rho: 1.300000e+00
truncation factor for cg beta ..................... eta: 1.000000e-02
perturbation parameter for function value ......... eps: 1.000000e-06
factor for computing average cost .............. Qdecay: 7.000000e-01
relative change in cost to stop quadstep ... QuadCufOff: 1.000000e-12
factor multiplying gradient in stop condition . StopFac: 0.000000e+00
cost change factor, approx Wolfe transition . AWolfeFac: 1.000000e-03
restart cg every restart_fac*n iterations . restart_fac: 1.000000e+00
stop when cost change <= feps*|f| ................. eps: 1.000000e-06
starting guess parameter in first iteration ...... psi0: 1.000000e-02
starting step in first iteration if nonzero ...... step: 0.000000e+00
factor multiply starting guess in quad step ...... psi1: 1.000000e-01
initial guess factor for general iteration ....... psi2: 2.000000e+00
max iterations is n*maxit_fac ............... maxit_fac: 1.797693e+308
max expansions in line search ................. nexpand: 50
max secant iterations in line search .......... nsecant: 50
print level (0 = none, 2 = maximum) ........ PrintLevel: 1
Logical parameters:
    Error estimate for function value is eps
    Use quadratic interpolation step
    Print final cost and statistics
    Print the parameter structure
    Wolfe line search ... switching to approximate Wolfe
    Stopping condition uses initial grad tolerance
    Do not check for decay of cost, debugger is off
iter:     0 f =   4.642373e+03 gnorm =   9.306125e+03 AWolfe =  0
QuadOK:  1 initial a:   1.070618e-04 f0:   4.642373e+03 dphi:  -8.662251e+07
Wolfe line search

iter:     1 f =   5.391563e+00 gnorm =   3.269753e-02 AWolfe =  0
QuadOK:  1 initial a:   1.632104e+01 f0:   5.391563e+00 dphi:  -1.069411e-03
Wolfe line search
RESTART CG

iter:     2 f =   5.387312e+00 gnorm =   1.558689e+01 AWolfe =  1
QuadOK:  0 initial a:   3.264209e+01 f0:   5.387312e+00 dphi:  -2.430188e+02
Approximate Wolfe line search

iter:     3 f =   5.374303e+00 gnorm =   3.196800e-02 AWolfe =  1
QuadOK:  1 initial a:   3.559386e+00 f0:   5.374303e+00 dphi:  -1.022238e-03
Approximate Wolfe line search
RESTART CG

iter:     4 f =   5.288871e+00 gnorm =   2.808049e-02 AWolfe =  1
QuadOK:  1 initial a:   2.376426e+01 f0:   5.288871e+00 dphi:  -7.887345e-04
Approximate Wolfe line search

iter:     5 f =   5.279499e+00 gnorm =   1.301306e+01 AWolfe =  1
QuadOK:  0 initial a:   4.752853e+01 f0:   5.279499e+00 dphi:  -1.693871e+02
Approximate Wolfe line search
RESTART CG

Termination status: 0
Convergence tolerance for gradient satisfied
maximum norm for gradient:  5.513258e-09
function value:             5.000294e+00

cg  iterations:                   6
function evaluations:            15
gradient evaluations:            11
===================================

fromList [23.941530180694265,0.6462905819889333]

今度は一瞬で収束した! やった!

*1  Hager, W. W. and Zhang, H. A new conjugate gradient method with guaranteed descent and an efficient line search. Society of Industrial and Applied Mathematics Journal on Optimization, 16 (2005), 170-192.