Julia随手记
最近在学julia,随手记一些零散知识点。
视频教程Julia教程 从入门到进阶、快速入门 Julia 语言 | 罗秀哲虽然有点久了,但大部分还是OK哒。
还有Jupyter教程。
安装
官网下载,VScode扩展。具体不多说了,很多教程。
Julia REPL
read-eval-print-loop 交互式命令行,四种模式:
- 正常模式:其他模式下按
back
键。 - help模式:按
?
键。查询命令,如print。 - shell模式:按
;
键。使用系统自带命令,如ls。 - package模式:按
]
键。增加删除库。
变量
println()
打印函数
emoji可做变量名,\:smile_cat:
+tab键
可以用Latex字符
#
单行注释
#= xxx xxx =#
多行注释
变量类型
typeof() 查看类型
supertype() 父类型
subtypes() 子类型,有s
sizeof() 占用字节
# 打印类型树
function showTypeTree(T, level=0)
println("\t"^level, T)
for t in subtypes(T)
if t != Any
showTypeTree(t, level +1)
end
end
end
showTypeTree(Real)
Real
AbstractFloat
BigFloat
Float16
Float32
Float64
AbstractIrrational
Irrational
Integer
Bool
Signed
BigInt
Int128
Int16
Int32
Int64
Int8
Unsigned
UInt128
UInt16
UInt32
UInt64
UInt8
Rational
复数
用im表示,如x=1+2im
。sqrt(-1+0im)
可运行。
分数、有理数
用//
表示。
字符和字符串
x='a' # 单引号字符
str="Hello" # 双引号,序号从1开始而不是从0开始
str2="World"
str3="""
many
rows
"""
$带入表达式的值
string(str, str2) # 字符串拼接
str * ',' * str2 # 用乘号拼接
str^3 # 重复3次
元组Tuple
有序,不可变
x=(1,2,3,4)
myfavoriteanimals = ("penguins", "cats", "sugargliders")
命名元组
myfavoriteanimals = (bird = "penguins", mammal = "cats", marsupial = "sugargliders")
myfavoriteanimals[1]
myfavoriteanimals.bird
字典Dictionary
无序,可变
dic=Dict("a"=>1, "b"=>2)
pop!(dic, "a")
删除
数组Array
有序,可变
mixture = [1, 1, 2, 3, "Ted", "Robyn"]
numbers = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
rand(4, 3)
push!
在最后添加元素
pop!
删除最后元素
复制数组时,=
后改变同时影响,copy()
只影响一个
Set
s=Set([1,2,3,2,1])
数学运算
+-*/^%
加减乘除 乘方 取余
2x
乘法,可省略*
|>
函数管道运算符
A'
或transpose(A)
转置
A\b
解线性方程组Ax=b
LinearAlgebra
线性代数标准包可以获得结构化的矩阵,如 Diagonal,Triangular,Symmetric,Hermitian等。
向量运算同MATLAB [1,2,3].*3
支持链式比较 1<=2<=3<=5>3
collect(1:4)
,
;
空格
矩阵分隔拼接效果不同
.+
.-
.*
./
sin.(A)
对元素进行操作加点
函数
function f1(x,y)
x+y #最后一行默认为返回值
end
等号f2(x) = x^2
匿名函数f3 = x -> x^2
map(x->x*2+1, [1,2,3,4])
#可变参数
function f1(x...)
r1=length(x)
r2=x[r1]
return r1,r2
end
函数名以 ! 结束的原地修改传入的变量,函数名非以 ! 结束的则不会改变传入的变量。
高阶函数map
与broadcast
。
多重派发:同一个函数可以有多个方法,methods()
查看所有方法,@which f(1+2)
查看所派发的方法。@code_llvm
查看LLVM代码。
匹配类型树里靠下的方法。
foo(x::String, y::String) = println("My inputs x and y are both strings!")
两个冒号和关键字限制输入类型。
foo(x::Int, y::Int) = println("My inputs x and y are both integers!")
增加新方法,没有覆写。
控制
for <var> in <loop iterable>
<loop body>
end
while <condition>
<loop body>
end
C = [i + j for i in 1:m, j in 1:n]
if <condition 1>
<option 1>
elseif <condition 2>
<option 2>
else
<option 3>
end
三元运算符a ? b : c
# 异常处理
try
sqrt(-1)
catch
println("pass")
finally
close(f)
end
类型
分为抽象类型(abstract)和实体类型(concrete)。
抽象类型分为可变类型(mutable)和不可变类型(immutable)。
没有class,没有子类型的继承关系。
只有抽象类型可以作为超类型。
继承行为,不是继承结构。
abstract type name end # 抽象类型
primitive type name bits end # 原始类型
struct # 自定义类型
mutable struct # 可变复合类型
绘图
- 官方Plots。添加信息要加“!”,如
xlabel!("xxx")
,title!("xxx")
,xflip!()
- 快速绘图GR
- 科学计算Gadfly
- 基于python的PyPlot
IO操作
readlines()
readline()
open()
read()
write()
close()
JLD2是一种HDF5格式。
IOBuffer()对内存操作。
模块
第一次使用时需要add。
using Pkg
Pkg.add("xxx")
using或import导入模块。using不允许增加新方法,import允许。
module name end 定义模块,调用前先push!(LOAD_PATH, “.”)找到module。
3个重要模块:Main,Core,Base
元编程
一般代码的操作对象是数据,元编程操作的对象是其他代码。
Meta.parse()
Meta.show_sexpr()
macro end
语法替换,在预编译时替换
并行计算
协程通过Channel实现多个任务之间的通信。
c1=Channel(32)
isready(c1) # 查看是否有元素
put!(c1, 1)
fetch(c1) # 只能读取一个,但不改变
take!(c1) # 读取后删除
close(c1) # 关闭后不能再写入
多线程 Base.Threads
多进程 (多核心、分布式处理)
科学计算
DataFrames
与pandas相似
RDatasets
包含许多公开数据集
Gadfly
绘图工具
Distributions
概率分布
Statistics
StatsBase
统计
TimeSeries
时间序列
MLBase
机器学习基础库,不包含算法,但提供很多工具如cross validation。
DecisionTree
决策树
MultivariateStats
高维数据计算,如PCA
高性能代码技巧
避免全局变量
变量最好是局部的,尽可能作为参数传递给函数。
注重性能和测试性能的代码最好放置在函数之中。
全局变量最好声明为常量const VAL=0
code generation
@code_
+\tab
查看宏
@code_lowered
底层运行过程@code_typed
运行时type变化@code_llvm
编译器的运行过程@code_native
机器语言@code_warntypes
是否有类型上的warning
抽象类型 具体类型
具体类型Array内存连续存放,节省时间空间
抽象类型Any指针指向位置,运行时间长
隐藏的类型转换
定义变量时尽量保持与运算时的类型一致。
zero()
eltype()
one()
similar()
避免拥有抽象类型参数的容器
mutable struct me{T<:AbstractFloat}
x::T
end
包含多个变量时,如果知道某个变量的类型,要明确指出。
运行时可变的参数会损失性能。
参数类型优化 方法替代
Val()
使用恰当会提升性能,不恰当会更差。
用方法代替函数中的判断条件。
矩阵优化
多维矩阵列优先,因为列在内存上是连续的。操作列比行快。
f.(x)
比手动在每一项加点快。
向量化并没有比循环快。甚至循环更快。
其他技巧
输出预分配
copy内存拷贝;view只是映射关系,更快。
println(a, " ", b)
比println("$a $b")
好。
避免不必要Array:x+y+z
比sum([x,y,x])
好。
有现成函数不要自己写计算过程:abs2(z)
比abs(z)^2
好,div(x,y)
>trunc(x/y)
, fld(x,y)
>floor(x/y)
, cld(x,y)
>ceil(x/y)
。