| | 有一次, 我媽媽在電話中問我, 現在國內工作的人都一直在學習, 你們在美國, 應該更需要學習, 怎麼只聽見你在打橋牌, 從來沒聽見你在學東西. 老太太說的是對的, 估計老人家已經憋好久了.我說物理中有近代物理和經典物理, 前者可說是日新月異, 真是三天不學習, 趕不上劉少奇. 即使你不搞研究, 只在大學裡教書, 不學新東西也很難混日子. 至於那些前沿學科, 電腦, 工程, 醫學, 生物等, 就更不用說了. 但這經典物理, 卻是很少再有新東西了.至於金融行業, 我也把它分為現代金融和經典金融. 你兒子運氣好, 做的正是經典金融. 工作十幾年, 確實一直在吃老本. 在可以預見的將來, 吃到退休應無大問題. 但新東西多少還是學了一些, 在較高的層次上, 有C++, VBA, Oracle 等等. 這些是我原來完全不懂的. 前一篇《不厭其”煩”》也是一例,但屬於較低層次, 說出來是懂的, 但自己就是沒想到 . 我以前的研究是做嚴格解的, 相對而言, 數值計算不是我的強項, 所以進公司後學的新東西, 計算方面占很大比例.這篇是另一個例子, 就是用分段線性函數 (Piecewise Linear Function) 來近似模型中的曲線. 儘管程序看上去繁多了, 但CPU節約很多, 建立模型也比以前容易得多, 好控制, 修改也方便. 如果曲線變化較大, 就多用幾段, 反之就少用幾段. 每段的起始點和斜率由回歸或經驗決定.這樣儘管模型的一階導數不再連續, 但可以很方便地使曲線更接近實際數據. 我最開始看到的一段關於分段線性函數的程序, 看上去很簡潔, 實際上極不合理. 假定函數小於某值(X1)是個常數, 大於某值(XN)是最後兩點的線性延伸. 那程序是這樣的. 凡涉及程序, 我只寫邏輯, 不牽涉具體語言. 這邏輯對C, Fortran, SAS, Pasco, … 應該都適用. Y = Y1 K = 1 if X > XK and X < XN then Y = YK + (YK+1 – YK) (X – XK) / (XK+1 – XK) K = K + 1 end 這段程序的循環中, 真正有用的計算只有一次, 既最後一次. 如果運氣好, 這無用循環只走了一兩次, 如果運氣不好就要走遍N-1 次了. 我重寫如下. if X < X1 then Y = Y1 else if X > XN-1 then Y = YN-1 + (YN – YN-1) (X – XN-1) / (XN – XN-1) else do i = 1 to N – 2 if Xi < X <= Xi+1 then Y = Yi + (Yi+1 – Yi) (X – Xi) / (Xi+1 – Xi) end 我測試了 N = 8 的 1,000,000 個隨機數, 新舊程序的時間比大約是 4:5. 我還注意到, 這(Yi+1 – Yi) / (Xi+1 – Xi) 實際上是個常數, 其中還有一次昂貴的除法. 所以這程序還可進一步優化. 在整個計算之前, 我們先算一下這 N – 1 個常數. Zi = (Yi+1 – Yi) / (Xi+1 – Xi), i = 1, 2, 3, …, N – 1 然後前面這優化過的程序就可寫成 if X < X1 then Y = Y1 else if X > XN-1 then Y = ZN-1 (X – XN-1) else do i = 1 to N – 2 if Xi < X <= Xi+1 then Y = Yi + Zi (X – Xi) end 原來的程序中, 除了占時極少的判別語句及左邊邊界的賦值語句, 每次要 5 次加法(加減乘 CPU 相同), 1 次除法, 共 7.3 次加法. 現在只用 3 次加法. 初始計算的 CPU 是可以忽略的. 和最初的”簡潔”程序相比, CPU 只有 33%. 如今, 計算機硬盤越來越大, 速度越來越快, 大家聽到的都是 Hard disk is cheap. 但在我們公司, 數據文件動輒40-50G, 同事們很快發現, 我做的優化確實有重大實際意義, 節約的時間可對模型進行更多的測試和改進. 尤其當項目很緊急時, 這些優化的意義就不是CPU能夠衡量了. 對大部分工業界的朋友, 這篇中的雕蟲小技並無太大實際意義. |