julia系列3:函数模块与宏
Posted IE06
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了julia系列3:函数模块与宏相关的知识,希望对你有一定的参考价值。
1. 控制流
1.1 复合表达式
复合表达式 使用 begin
和 (;)
或者使用小括号:
1.2 循环
while
和 for
为循环关键字,用end结束,没有:符号并且不需要缩进:
python中的range(N)在julia中用1:N表示,数据类型为UnitRange或者StepRange,和array一起可用于范围遍历。注意array和range的下标从1开始,和python不一样。
1.3 条件极值
关键字为 if-elseif-else-end
和 ?: (ternary operator)
2. 函数
2.1 声明
使用function...end
定义函数,用两个冒号::
来断言具体变量类型(注意不是声明!julia的变量没有类型)
使用@doc funcname可以看到函数前面的注释。
local变量可以强制转类型,需要先声明再赋值。注意字符串转数字要用parse。
2.2 调用
修改参数的函数结尾使用!,这样的函数被称为mutating functions或in-place functions
函数可以用于map和reduce中,也可以加在管道后面
下面是个使用管道的网红自动问答系统:
2.3 常用自定义数学函数
Julia 预定义了非常丰富的数学函数。一些常用的函数如下:
- 数值类型转换: 主要有T(x)和convert(T, x)。其中,T代表目的类型,x代表源值。
- 数值特殊性判断: 有isequal、isfinite、isinf和isnan。
- 舍入: 有四舍五入的round(T, x)、向正无穷舍入的ceil(T, x)、向负无穷舍入的floor(T, x),以及总是向0舍入的trunc(T, x)。
- 除法: 有cld(x, y)、fld(x, y)和div(x, y),它们分别会将商向正无穷、负无穷和0做舍入。其中的x代表被除数,y代表除数。另外,与之相关的还有取余函数rem(x, y)和取模函数mod(x, y),等等。
- 公约数与公倍数: 函数gcd(x, y…)用于求取最大正公约数,而函数lcm(x, y…)则用于求取最小正公倍数。圆括号中的…的意思是,除了x和y,函数还允许传入更多的数值。但要注意,这里的数值都应该是整数。
- 符号获取: 函数sign(x)和signbit(x)都用于获取一个数值的符号。但不同的是,前者对于正整数、0和负整数会分别返回1、0和-1,而后者会分别返回false、false和true。
- 绝对值获取: 用于获取绝对值的函数是abs(x)。一个相关的函数是,用于求平方的abs2(x)。
- 求根: 函数sqrt(x)用于求取x的平方根,而函数cbrt(x)则用于求取x的立方根。
- 求指数: 函数exp(x)会求取x的自然指数。另外还有expm1(x),为接近0的x计算exp(x)-1。
- 求对数: log(x)会求取x的自然对数,log(b, x)会求以b为底的x的对数,而log2(x)和log10(x)则会分别以2和10为底求对数。另外还有log1p(x),为接近0的x计算log(1+x)。
2.4 匿名函数、多返回值、可变参数
用->表示匿名函数,用…表示多参数
3. 重载和多重分派
3.1 方法重载
注意这里x…表示将数组元素拆开:
3.2 多重分派
分派就是指根据变量的类型选择相应的方法,单分派指的是指根据第一个参数类型去选择方法。
下面我们举一个Python中的例子来做解释,Python因为在函数定义时是不知道参数类型的,所以一般没有单分派;但Python中提供了单分派的修饰符,可以实现单分派的功能。
from functools import singledispatch
@singledispatch
def func(arg, verbose=False):
print('initial...\\n')
@func.register(int)
def _(arg, verbose=False):
print(arg)
func(1)
>>1
func(2.3)
>>initial...
4. 模块
4.1 定义
模块是一些互相隔离的工作空间,用法上类似于Python中的库。
使用module...export...end
定义模块,其中export是将这函数导出来,这样就可以直接使用。如下:
module mytest
export myAdd
myAdd(x,y)=x+y
end
4.2 调用
调用时,先include,然后就可以直接使用了
5. 宏
5.1 定义
使用macro定义宏,然后使用@引用宏。总体来说非常像function
5.2 调用
5.3 常用预定义宏
@time:测时间
@show:展示完整表达式
@which:展示数据类型
我们常用@timeit、@time 来做基本的测试,使用方法如下:
m = randn(1<<16, 8)
function test_swaprow(m::VecOrMat)
N = size(m, 1)
for i = 1:N-1
swaprows!(m, i, i+1)
end
m
end
using BenchmarkTools
@benchmark test_swaprow($m)
返回
BenchmarkTools.Trial:
memory estimate: 25.97 MiB
allocs estimate: 653308
--------------
minimum time: 12.866 ms (7.65% GC)
median time: 17.959 ms (8.86% GC)
mean time: 18.326 ms (10.94% GC)
maximum time: 27.736 ms (12.75% GC)
--------------
samples: 273
evals/sample: 1
function swaprows!(v::VecOrMatT, i::Int, j::Int) where T
for c = 1:size(v, 2)
temp = v[i, c]
v[i, c] = v[j, c]
v[j, c] = temp
end
v
end
@benchmark test_swaprow($m)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.459 ms (0.00% GC)
median time: 1.524 ms (0.00% GC)
mean time: 1.582 ms (0.00% GC)
maximum time: 2.926 ms (0.00% GC)
--------------
samples: 3147
evals/sample: 1
以上是关于julia系列3:函数模块与宏的主要内容,如果未能解决你的问题,请参考以下文章