julia系列3:函数模块与宏

Posted IE06

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了julia系列3:函数模块与宏相关的知识,希望对你有一定的参考价值。

1. 控制流

1.1 复合表达式

复合表达式 使用 begin(;)或者使用小括号:

1.2 循环

whilefor为循环关键字,用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:函数模块与宏的主要内容,如果未能解决你的问题,请参考以下文章

julia系列3:函数模块与宏

第六章 实验报告(函数与宏定义)

第六章 实验报告 (函数与宏定义)

第六章 实验报告 (函数与宏定义)

julia系列11:struct和类

julia系列5:文本图像其他语言函数互动