為科學計算而生的Julia——基於Manjaro Linux的安裝與入門

技術背景

Julia是一門為科學計算而生的程式語言,其著重強調了開源、生態與性能。從開源角度來說,相比於Matlab就要友好很多,用戶可以免費使用,而且MIT協議應該是最寬鬆的開源協議之一(截圖來自於參考鏈接3):

而生態則是對標的C/C++語言,我們都知道python是一門生態非常強大的程式語言,各種輪子很大程度上減少了學習成本和工作量,而julia的目標也是如此。最後在性能上是對標的python,我們都知道python作為一門解釋性語言,在性能上有較大的犧牲。除非我們使用c++或者fortran去構造動態鏈接庫,然後通過python上層語言來封裝,這樣才能在性能上有所保障,但是工作量又被放大了。Julia的優勢就在於可以達到接近於C語言的性能,同時又能像python一樣易於編寫,兼顧了性能與開發周期,對科學計算非常的友好。

官網簡介

科學計算對性能一直有著最高的需求,但目前各領域的專家卻大量使用較慢的動態語言來開展他們的日常工作。 偏愛動態語言有很多很好的理由,因此我們不會捨棄動態的特性。 幸運的是,現代程式語言設計與編譯器技術可以大大消除性能折衷(trade-off),並提供有足夠生產力的單一環境進行原型設計,而且能高效地部署性能密集型應用程式。 Julia 語言在這其中扮演了這樣一個角色:它是一門靈活的動態語言,適合用於科學計算和數值計算,並且性能可與傳統的靜態類型語言媲美。

由於 Julia 的編譯器和其它語言比如 Python 或 R 的解釋器有所不同,一開始你可能發現 Julia 的性能並不是很突出。 如果你覺得速度有點慢,我們強烈建議在嘗試其他功能前,先讀一讀文檔中的提高性能的竅門。 在理解了 Julia 的運作方式後,寫出和 C 一樣快的程式碼對你而言就是小菜一碟。

Julia 擁有可選類型標註和多重派發這兩個特性,同時還擁有很棒的性能。 這些都得歸功於使用 LLVM 實現的類型推導和即時編譯(JIT)技術。Julia 是一門支援過程式、函數式和面向對象的多範式語言。 它像 R、MATLAB 和 Python 一樣簡單,在高級數值計算方面有豐富的表現力,並且支援通用編程。 為了實現這個目標,Julia 以數學程式語言(mathematical programming languages)為基礎,同時也參考了不少流行的動態語言,例如 Lisp、Perl、Python、Lua、和 Ruby。

Julia 與傳統動態語言最重要的區別是:

  • 核心語言很小:標準庫是用 Julia 自身寫的,包括整數運算這樣的基礎運算
  • 豐富的基礎類型:既可用於定義和描述對象,也可用於做可選的類型標註
  • 通過多重派發,可以根據類型的不同,來調用同名函數的不同實現
  • 為不同的參數類型,自動生成高效、專用的程式碼
  • 接近 C 語言的性能

儘管人們有時會說動態語言是「無類型的」,但實際上絕對不是這樣的:每一個對象都有一個類型,無論它是基礎的類型(primitive)還是用戶自定義的類型。 大多數的動態語言都缺乏類型聲明,這意味著程式設計師無法告訴編譯器值的類型,也就無法顯式地討論類型。 另一方面,在靜態語言中,往往必須標註對象的類型。但類型只在編譯期才存在,而無法在運行時進行操作和表達。 而在 Julia 中,類型本身是運行時的對象,並可用於向編譯器傳達資訊。

類型系統和多重派發是 Julia 語言最主要的特徵,但一般不需要顯式地手動標註或使用:函數通過函數名稱和不同類型參數的組合進行定義,在調用時會派發到最接近(most specific)的定義上去。這樣的編程模型非常適合數學化的編程,尤其是在傳統的面向對象派發中,一些函數的第一個變數理論上並不「擁有」這樣一個操作時。 在 Julia 中運算符只是函數的一個特殊標記——例如,為用戶定義的新類型添加加法運算,你只要為 + 函數定義一個新的方法就可以了。 已有的程式碼就可以無縫接入這個新的類型。

Julia 在設計之初就非常看重性能,再加上它的動態類型推導(可以被可選的類型標註增強),使得 Julia 的計算性能超過了其它的動態語言,甚至能夠與靜態編譯語言競爭。對於大型數值問題,速度一直都是,也一直會是一個重要的關注點:在過去的幾十年里,需要處理的數據量很容易與摩爾定律保持同步。

Julia 的目標是創建一個前所未有的集易用、強大、高效於一體的語言。除此之外,Julia 還擁有以下優勢:

  • 採用 MIT 許可證:免費又開源
  • 用戶自定義類型的速度與兼容性和內建類型一樣好
  • 無需特意編寫向量化的程式碼:非向量化的程式碼就很快
  • 為並行計算和分散式計算設計
  • 輕量級的「綠色」執行緒:協程
  • 低調又牛逼的類型系統
  • 優雅、可擴展的類型轉換和類型提升
  • 對 Unicode 的有效支援,包括但不限於 UTF-8
  • 直接調用 C 函數,無需封裝或調用特別的 API
  • 像 Shell 一樣強大的管理其他進程的能力
  • 像 Lisp 一樣的宏和其他元編程工具

在Manjaro Linux上安裝Julia

如果我們直接搜索Julia在Manjaro Linux下的安裝方法,很有可能搜到一個類似於參考鏈接4中所提供的方案。這個方案是從官網下載一個可執行文件,然後將該文件存放到系統路徑下。雖然這也不失為一個比較通用的方法,但是我個人更傾向於從系統的源裡面去尋找資源,而Manjaro Linux其實是有julia的資源的,只是會有一些依賴需要我們去獨立安裝。我們先嘗試一下直接安裝julia:

[dechin-root 2021-softwares]# pacman -S julia
正在解析依賴關係...
正在查找軟體包衝突...
警告:正在從目標清單中刪除 'blas' ,因為它和 'openblas' 衝突

軟體包 (11) cblas-3.9.0-3  lapack-3.9.0-3  libutf8proc-2.6.1-1  llvm10-libs-10.0.1-4
            mbedtls-2.25.0-1  metis-5.1.0.p10-1  openblas-0.3.13-2  openlibm-0.7.5-1
            suitesparse-5.9.0-1  tbb-2020.3-1  julia-2:1.5.4-1

下載大小:   51.24 MiB
全部安裝大小:  272.10 MiB

:: 進行安裝嗎? [Y/n] Y
:: 正在獲取軟體包......
 cblas-3.9.0-3-x86_64        33.9 KiB  4.73 MiB/s 00:00 [#############################] 100%
 metis-5.1.0.p10-1-x86_64   166.6 KiB  2.71 MiB/s 00:00 [#############################] 100%
 lapack-3.9.0-3-x86_64        2.3 MiB  9.36 MiB/s 00:00 [#############################] 100%
 tbb-2020.3-1-x86_64        393.4 KiB  8.73 MiB/s 00:00 [#############################] 100%
 suitesparse-5.9.0-1-x...  1101.7 KiB  9.44 MiB/s 00:00 [#############################] 100%
 llvm10-libs-10.0.1-4-...    21.2 MiB  8.32 MiB/s 00:03 [#############################] 100%
 openblas-0.3.13-2-x86_64  1448.8 KiB  6.97 MiB/s 00:00 [#############################] 100%
 libutf8proc-2.6.1-1-x...    76.9 KiB  25.0 MiB/s 00:00 [#############################] 100%
 mbedtls-2.25.0-1-x86_64    848.9 KiB  4.30 MiB/s 00:00 [#############################] 100%
 openlibm-0.7.5-1-x86_64    111.5 KiB  4.03 MiB/s 00:00 [#############################] 100%
 julia-2:1.5.4-1-x86_64      23.6 MiB  2.90 MiB/s 00:08 [#############################] 100%
(11/11) 正在檢查密鑰環里的密鑰                          [#############################] 100%
(11/11) 正在檢查軟體包完整性                            [#############################] 100%
(11/11) 正在載入軟體包文件                              [#############################] 100%
(11/11) 正在檢查文件衝突                                [#############################] 100%
(11/11) 正在檢查可用存儲空間                            [#############################] 100%
:: 正在處理軟體包的變化...
( 1/11) 正在安裝 openblas                               [#############################] 100%
( 2/11) 正在安裝 cblas                                  [#############################] 100%
( 3/11) 正在安裝 libutf8proc                            [#############################] 100%
( 4/11) 正在安裝 metis                                  [#############################] 100%
( 5/11) 正在安裝 lapack                                 [#############################] 100%
( 6/11) 正在安裝 tbb                                    [#############################] 100%
( 7/11) 正在安裝 suitesparse                            [#############################] 100%
( 8/11) 正在安裝 mbedtls                                [#############################] 100%
( 9/11) 正在安裝 openlibm                               [#############################] 100%
(10/11) 正在安裝 llvm10-libs                            [#############################] 100%
(11/11) 正在安裝 julia                                  [#############################] 100%
julia 的可選依賴
    gnuplot: If using the Gaston Package from julia
:: 正在運行事務後鉤子函數...
(1/3) Arming ConditionNeedsUpdate...
(2/3) Updating icon theme caches...
(3/3) Updating the desktop file MIME type cache...

安裝下來倒是沒報錯,看起來沒什麼問題,我們執行一下julia的命令行試試:

[dechin-root 2021-softwares]# julia
julia: /usr/bin/../lib/libc.so.6: version `GLIBC_2.33' not found (required by /usr/bin/../lib/libjulia.so.1)

這一下問題就暴露出來了,有glibc這個依賴需要我們手動安裝,在網上搜了一下方案,直接安裝和升級以下兩個庫即可:

[dechin-root 2021-softwares]# pacman -S glibc lib32-glibc
正在解析依賴關係...
正在查找軟體包衝突...

軟體包 (2) glibc-2.33-4  lib32-glibc-2.33-4

下載大小:  13.35 MiB
全部安裝大小:  64.42 MiB
凈更新大小:  -0.34 MiB

:: 進行安裝嗎? [Y/n] Y
:: 正在獲取軟體包......
 glibc-2.33-4-x86_64          9.8 MiB  9.46 MiB/s 00:01 [#############################] 100%
 lib32-glibc-2.33-4-x86_64    3.5 MiB  9.56 MiB/s 00:00 [#############################] 100%
(2/2) 正在檢查密鑰環里的密鑰                            [#############################] 100%
(2/2) 正在檢查軟體包完整性                              [#############################] 100%
(2/2) 正在載入軟體包文件                                [#############################] 100%
(2/2) 正在檢查文件衝突                                  [#############################] 100%
(2/2) 正在檢查可用存儲空間                              [#############################] 100%
:: 正在處理軟體包的變化...
(1/2) 正在更新 glibc                                    [#############################] 100%
Generating locales...
  en_US.UTF-8... done
  zh_CN.UTF-8... done
Generation complete.
(2/2) 正在更新 lib32-glibc                              [#############################] 100%
:: 正在運行事務後鉤子函數...
(1/5) Reloading system manager configuration...
(2/5) Creating temporary files...
(3/5) Arming ConditionNeedsUpdate...
(4/5) Restarting cronie for libc upgrade...
(5/5) Updating the info directory file...

安裝完成後我們再試一下julia的指令:

[dechin-root 2021-softwares]# julia
               _
   _       _ _(_)_     |  Documentation: //docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.5.4 (2021-03-11)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> 1+2
3

julia> ans
3

julia> println("Hello World!")
Hello World!

當我們看到這個介面的時候,就表示julia已經安裝成功了。

包管理與案例測試

參考了參考鏈接1中的案例,我們來測試一下julia執行簡單的張量網路縮並的功能。關於張量網路計算的背景知識,可以參考一下我們之前寫過的這篇介紹python張量網路計算的部落格,這裡用julia來計算張量網路的話會依賴於Einsum這個第三方包,需要我們來手動安裝。首先我們測試一下直接調用這個包的指令,如果這個包已經被安裝了,那麼調用就不會報錯:

julia> using Einsum
ERROR: ArgumentError: Package Einsum not found in current path:
- Run `import Pkg; Pkg.add("Einsum")` to install the Einsum package.

Stacktrace:
 [1] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.4/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288

這裡我們發現系統中是沒有這個庫的,而這裡調用的時候也已經提示了我們安裝這個包的方法,我們可以嘗試直接按照這個指令來安裝:

julia> import Pkg

julia> Pkg.add("Einsum")
 Installing known registries into `~/.julia`
######################################################################## 100.0%
      Added registry `General` to `~/.julia/registries/General`
  Resolving package versions...
  Installed Compat ─ v3.25.0
  Installed Einsum ─ v0.4.1
Updating `~/.julia/environments/v1.5/Project.toml`
  [b7d42ee7] + Einsum v0.4.1
Updating `~/.julia/environments/v1.5/Manifest.toml`
  [34da2185] + Compat v3.25.0
  [b7d42ee7] + Einsum v0.4.1
  [2a0f44e3] + Base64
  [ade2ca70] + Dates
  [8bb1440f] + DelimitedFiles
  [8ba89e20] + Distributed
  [b77e0a4c] + InteractiveUtils
  [76f85450] + LibGit2
  [8f399da3] + Libdl
  [37e2e46d] + LinearAlgebra
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [a63ad114] + Mmap
  [44cfe95a] + Pkg
  [de0858da] + Printf
  [3fa0cd96] + REPL
  [9a3f8284] + Random
  [ea8e919c] + SHA
  [9e88b42a] + Serialization
  [1a1011a3] + SharedArrays
  [6462fe0b] + Sockets
  [2f01184e] + SparseArrays
  [10745b16] + Statistics
  [8dfed614] + Test
  [cf7118a7] + UUIDs
  [4ec0a83e] + Unicode

安裝過程沒有什麼問題,那我們再次調用看看:

julia> using Einsum
[ Info: Precompiling Einsum [b7d42ee7-0b51-5a75-98ca-779d3107e4c0]

調用沒有問題,說明我們這個包是安裝成功了。接下來正式測試一下張量網路縮並的案例:

julia> A = zeros(5,6,7)
5×6×7 Array{Float64,3}:
[:, :, 1] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 2] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 3] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 4] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 5] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 6] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

[:, :, 7] =
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0

julia> X = randn(5,2)
5×2 Array{Float64,2}:
 -0.573591   0.550235
 -0.893529  -1.25679
 -0.338177   0.632082
 -0.304742   2.67068
 -0.171912  -0.714813

julia> Y = randn(6,2)
6×2 Array{Float64,2}:
 -0.609149  -0.815229
  0.199472   0.554751
 -0.562527   0.259988
 -1.65124    1.08916
 -0.625242  -0.0391435
 -0.943587  -0.695565

julia> Z = randn(7,2)
7×2 Array{Float64,2}:
  0.311165   0.555719
 -0.486201  -1.26421
 -1.90713    0.738125
 -1.26129   -0.274261
 -0.570305  -0.295527
 -0.182373  -0.0410972
 -0.213648  -0.12244

julia> @einsum A[i,j,k] = X[i,r]*Y[j,r]*Z[k,r]
5×6×7 Array{Float64,3}:
[:, :, 1] =
 -0.140556   0.134027   0.179899    0.627755  0.0996249   -0.0442743
  0.738739  -0.442911  -0.0251791  -0.30159   0.201178     0.748148
 -0.222257   0.173872   0.150518    0.556337  0.052044    -0.145031
 -1.15216    0.804416   0.439202    1.77305   0.00119409  -0.942843
  0.356423  -0.231037  -0.0731852  -0.344323  0.0489952    0.326778

[:, :, 2] =
  0.397202  -0.330261  -0.337728  -1.21813   -0.147139    0.220694
 -1.5599     0.968069   0.168698   1.01314   -0.333819   -1.51507
  0.551277  -0.410494  -0.300243  -1.14183   -0.0715246   0.400667
  2.66219   -1.84344   -0.96114   -3.92197    0.0395199   2.20862
 -0.787613   0.517985   0.187925   0.846224  -0.0876327  -0.70743

[:, :, 3] =
 -0.997453   0.443513  -0.509762  -1.36396  -0.699856  -1.3147
 -0.281771  -0.174709  -1.19977   -3.82422  -1.02915   -0.962687
 -0.773218   0.387471  -0.241501  -0.55681  -0.42151   -0.933083
 -1.96108    1.20951    0.185581   1.18738  -0.440543  -1.91956
  0.230419  -0.2273    -0.321604  -1.11604  -0.184337   0.0576331

[:, :, 4] =
 -0.317672   0.0605948  -0.446202   -1.35898   -0.446433  -0.577685
 -0.967509   0.416021   -0.544352   -1.48553   -0.718138  -1.30317
 -0.118501  -0.0110862  -0.28501    -0.89313   -0.259904  -0.281897
  0.362986  -0.329663   -0.406649   -1.43245   -0.211652   0.146789
 -0.291903   0.152008   -0.0710035  -0.144515  -0.143245  -0.34096

[:, :, 5] =
 -0.0667018  -0.0249559  -0.226291     -0.717264   -0.198165   -0.195562
 -0.6132      0.307691   -0.190091     -0.436916   -0.333152   -0.73918
  0.0347997  -0.0651548  -0.157056     -0.521917   -0.113275   -0.0520544
  0.537557   -0.403173   -0.302962     -1.1466     -0.0777703   0.384987
 -0.231936    0.136746   -0.000229789   0.0681898  -0.0695689  -0.239447

[:, :, 6] =
 -0.0452868   0.00832171  -0.0647238   -0.197362   -0.06452    -0.0829776
 -0.141371    0.0611584   -0.0782386   -0.212824   -0.103909   -0.189689
 -0.0163919  -0.00210828  -0.0414473   -0.130132   -0.0375447  -0.0401267
  0.0556227  -0.0498019   -0.0597991   -0.211314   -0.0304527   0.0239016
 -0.0430469   0.0225507   -0.00999881  -0.0197739  -0.0207526  -0.0500169

[:, :, 7] =
 -0.0197261  -0.0129295  -0.0864512   -0.275731   -0.0739839  -0.0687722
 -0.241735    0.123445   -0.0673792   -0.147621   -0.125382   -0.287166
  0.019081   -0.0285214  -0.0607641   -0.203596   -0.0421448  -0.0143435
  0.226918   -0.168415   -0.12164     -0.463661   -0.0279081   0.166014
 -0.0937235   0.0558792   0.00209385   0.0346776  -0.0263901  -0.0955337

在上面這個案例中,我們事先定義好了一個張量A用於存放計算結果,如果我們不事先定義的話,就需要按照以下示例來使用:

julia> @einsum B[i,j,k] := X[i,r]*Y[j,r]*Z[k,r]
5×6×7 Array{Float64,3}:
[:, :, 1] =
 -0.140556   0.134027   0.179899    0.627755  0.0996249   -0.0442743
  0.738739  -0.442911  -0.0251791  -0.30159   0.201178     0.748148
 -0.222257   0.173872   0.150518    0.556337  0.052044    -0.145031
 -1.15216    0.804416   0.439202    1.77305   0.00119409  -0.942843
  0.356423  -0.231037  -0.0731852  -0.344323  0.0489952    0.326778

[:, :, 2] =
  0.397202  -0.330261  -0.337728  -1.21813   -0.147139    0.220694
 -1.5599     0.968069   0.168698   1.01314   -0.333819   -1.51507
  0.551277  -0.410494  -0.300243  -1.14183   -0.0715246   0.400667
  2.66219   -1.84344   -0.96114   -3.92197    0.0395199   2.20862
 -0.787613   0.517985   0.187925   0.846224  -0.0876327  -0.70743

[:, :, 3] =
 -0.997453   0.443513  -0.509762  -1.36396  -0.699856  -1.3147
 -0.281771  -0.174709  -1.19977   -3.82422  -1.02915   -0.962687
 -0.773218   0.387471  -0.241501  -0.55681  -0.42151   -0.933083
 -1.96108    1.20951    0.185581   1.18738  -0.440543  -1.91956
  0.230419  -0.2273    -0.321604  -1.11604  -0.184337   0.0576331

[:, :, 4] =
 -0.317672   0.0605948  -0.446202   -1.35898   -0.446433  -0.577685
 -0.967509   0.416021   -0.544352   -1.48553   -0.718138  -1.30317
 -0.118501  -0.0110862  -0.28501    -0.89313   -0.259904  -0.281897
  0.362986  -0.329663   -0.406649   -1.43245   -0.211652   0.146789
 -0.291903   0.152008   -0.0710035  -0.144515  -0.143245  -0.34096

[:, :, 5] =
 -0.0667018  -0.0249559  -0.226291     -0.717264   -0.198165   -0.195562
 -0.6132      0.307691   -0.190091     -0.436916   -0.333152   -0.73918
  0.0347997  -0.0651548  -0.157056     -0.521917   -0.113275   -0.0520544
  0.537557   -0.403173   -0.302962     -1.1466     -0.0777703   0.384987
 -0.231936    0.136746   -0.000229789   0.0681898  -0.0695689  -0.239447

[:, :, 6] =
 -0.0452868   0.00832171  -0.0647238   -0.197362   -0.06452    -0.0829776
 -0.141371    0.0611584   -0.0782386   -0.212824   -0.103909   -0.189689
 -0.0163919  -0.00210828  -0.0414473   -0.130132   -0.0375447  -0.0401267
  0.0556227  -0.0498019   -0.0597991   -0.211314   -0.0304527   0.0239016
 -0.0430469   0.0225507   -0.00999881  -0.0197739  -0.0207526  -0.0500169

[:, :, 7] =
 -0.0197261  -0.0129295  -0.0864512   -0.275731   -0.0739839  -0.0687722
 -0.241735    0.123445   -0.0673792   -0.147621   -0.125382   -0.287166
  0.019081   -0.0285214  -0.0607641   -0.203596   -0.0421448  -0.0143435
  0.226918   -0.168415   -0.12164     -0.463661   -0.0279081   0.166014
 -0.0937235   0.0558792   0.00209385   0.0346776  -0.0263901  -0.0955337

這裡我們可以發現,julia的變數定義形式跟python是類似的,並不需要事先聲明變數的具體類型。

基本用法示例

在上面一個案例中我們執行了一個簡單的功能測試,並介紹了julia的包的安裝,這裡我們再介紹一下julia語言的一些基本用法。

函數

最常用的julia的函數功能也是一個挺有意思的定義方法,我們可以直接對函數進行賦值來使用:

julia> ∑(x,y)=x+y
∑ (generic function with 1 method)

julia> ∑(3,5)
8

這裡我們就定義了這樣的一個函數。順帶一說,這些常見的希臘字母在julia中可以先按照latex的語法來寫,然後Tab一下就可以彈出來具體字元。比如實際上是\sum<Tab>

注釋

關於julia的注釋沒有太多好說的,單行注釋跟python的一致,多行注釋是#= comments =#這樣的結構(空格是非必須的):

julia> # This is a comment!

julia> #= Test comment line1;
          Test comment line2 =#

julia> #=Test comment line1
         Test comment line2=#

jl文件的執行

跟python的py文件類似的,julia可以將程式碼寫入一個jl文件,再通過julia module.jl這樣的形式來調用:

[dechin-root julia]# echo 'println("Hello World!")' > helloworld.jl
[dechin-root julia]# julia helloworld.jl 
Hello World!

調用python函數

通過PyCall這個包,我們可以在julia內部調用python程式碼。而類似於上述章節中的Einsum,這裡我們也需要用Pkg來安裝一下這個包:

julia> import Pkg

julia> Pkg.add("PyCall")
   Updating registry at `~/.julia/registries/General`
  Resolving package versions...
  Installed VersionParsing ─ v1.2.0
  Installed Parsers ──────── v1.0.16
  Installed Conda ────────── v1.5.1
  Installed MacroTools ───── v0.5.6
  Installed PyCall ───────── v1.92.2
  Installed JSON ─────────── v0.21.1
Updating `~/.julia/environments/v1.5/Project.toml`
  [438e738f] + PyCall v1.92.2
Updating `~/.julia/environments/v1.5/Manifest.toml`
  [8f4d0f93] + Conda v1.5.1
  [682c06a0] + JSON v0.21.1
  [1914dd2f] + MacroTools v0.5.6
  [69de0a69] + Parsers v1.0.16
  [438e738f] + PyCall v1.92.2
  [81def892] + VersionParsing v1.2.0
   Building Conda ─→ `~/.julia/packages/Conda/tJJuN/deps/build.log`
   Building PyCall → `~/.julia/packages/PyCall/tqyST/deps/build.log`

安裝成功後,可以按照如下方法引入一個python的函數來執行計算任務:

julia> using PyCall
[ Info: Precompiling PyCall [438e738f-606a-5dbb-bf0a-cddfbfd45ab0]

julia> math = pyimport("math")
PyObject <module 'math' from '/home/dechin/anaconda3/lib/python3.8/lib-dynload/math.cpython-38-x86_64-linux-gnu.so'>

julia> math.sin(math.pi / 4)
0.7071067811865475

這裡可以看到我們調用python中的math函數計算了一個正弦函數值。

macro裝飾器

macro是julia語言中的一個關鍵字,這裡還不知道怎麼去翻譯它,在我們上一個章節張量網路的示例中其實已經用到了這個功能。說起來功能是類似於python中的裝飾器(decorator)的概念,相關介紹可以參考前面寫的這篇部落格,以及一個python實現的裝飾器實例。其實基本概念是跟模組化編程相關的,通過向上封裝的方法豐富了介面調用的方法。macro的官方示例如下:

julia> macro sayhello(name)
           return :( println("Hello, ", $name, "!") )
       end
@sayhello (macro with 1 method)

julia> @sayhello "Charlie"
Hello, Charlie!

總結概要

在這篇文章中我們介紹了julia程式語言的一些基本特點,這是一門兼顧了高性能與高效開發的程式語言,而且開源免費。不僅具備有python的便捷性,還有接近於C語言的高性能特性,是一門為科學計算而生的程式語言。我們介紹了其在Manjaro Linux平台下的安裝方法,及其基本使用方法,如變數定義、函數定義和調用、包的管理以及與python程式語言的協同工作。

版權聲明

本文首發鏈接為://www.cnblogs.com/dechinphy/p/julia.html
作者ID:DechinPhy
更多原著文章請參考://www.cnblogs.com/dechinphy/

參考鏈接

  1. //zhuanlan.zhihu.com/p/52487166
  2. //cn.julialang.org/JuliaZH.jl/latest/manual/getting-started/
  3. //www.runoob.com/w3cnote/open-source-license.html
  4. //blog.csdn.net/hetengjiao523/article/details/106397332