美文网首页
JULIA-函数

JULIA-函数

作者: 9016 | 来源:发表于2018-10-30 10:05 被阅读56次

    函数就是f(x,y,...),f(x,y,...)就是函数。学过高中数学的都知道。

    函数的基本结构:

    Julia里面的函数定义语法:

    function f(x,y)
    #逻辑运算部分
    end
    

    比如我们定义一个计算两数乘积的函数:

    function multiplier1(x,y)
      return x*y
    end
    

    我们看函数调用返回:

    julia> multiplier1(3,7)
    21
    

    简化的函数定义:

    multiplier2(x,y) = x*y
    

    调用这个函数,看到返回和multiplier1一样。

    julia> multiplier2(3,7)
    21
    

    函数的调用:

    上面的函数multiplier1()和multiplier2(),我们已经给出直接使用f()的语法,历史上还有apply()函数调用其他函数,比如上面的multiplier1()的调用可以写成:

    julia> apply(multiplier1,3,7)
    

    但是到了Julia1.0版本后,已经取消了apply()这个函数。

    函数的返回:

    多数时候我们需要函数完成个运算后返回一个或者多个具体的值。
    比如我们定义一个已知三角形两边和夹角求第三边的函数:

    function thirdSide(x,y,c)
      z = sqrt(x^2+y^2-2*x*y*cosd(c))
      return z
    end
    

    我们拿勾股定理试一下:

    julia> thirdSide(3,4,90)
    5.0
    

    心里装个正三角形:

    julia> thirdSide(3,3,60)
    3.0
    

    匿名函数

    顾名思义,就是不起名字的函数,例如:

      x -> x^2 - 2x + 1
    

    function (x)
      x^2 - 2x + 1
    end
    

    是一样的,但是第一种写法没有函数名,所以调用起来有自己的语法。
    我们使用map()函数演示一下匿名函数的调用方法:

    julia> map( x -> x^2 - 2x + 1,[1,3,5,7,9])
    5-element Array{Int64,1}:
    0
    4
    16
    36
    64
    

    上面这段可以看到函数的嵌套使用,编程中会经常遇到,例如:

    map(round, [1.2,99.5,-10.135])
    3-element Array{Float64,1}:
      1.0
    100.0
    -10.0
    

    多返回值函数:

    定义:

    function add1(a,b)
          return a+1, b+1
     end
    

    调用:

    julia> add1(5,6)
    (6, 7)
    

    函数返回值对变量的赋值:

    julia> x, y = foo(7,9)
    (8,10)
    julia> x
    8
    julia> y
    10
    

    跨结构参数

    先定义函数minmax(),输出小数在前大数在后:

    minmax(x, y) = (y < x) ? (y, x) : (x, y)
    

    再定义range(),输出大数减小数的差((min, max),作为一个Tuples的固定形式存在,是一个整体。):

    range((min, max)) = max - min
    

    跨函数体传递参数:

    print(range(minmax(100, 2)))
    98
    

    很明显,与前面的map(),不同,这是另一种形式的函数嵌套使用。

    变参函数

    所谓变参,是指函数中参数的个数不定,在使用时根据实际情况变化,定义函数时,最后一个参数后紧跟省略号 ... 来定义变参函数:

    julia> vf(a,b,c...) = (a,b,c)
    bar (generic function with 1 method)
    
    julia> vf(1,2)
    (1, 2, ()))
    
    julia> vf(1,2,3,4,5,6)
    (1, 2, (3, 4, 5, 6))
    
    julia> x = (3,4)
    (3, 4)
    
    julia> vf(1,2,x...)
    (1, 2, (3, 4))
    
    julia> x = (2,3,4)
    (2, 3, 4)
    
    julia> vf(1,x...)
    (1, 2, (3, 4))
    
    julia> x = [7,8,9]
    3-element Array{Int64,1}:
    7
    8
    9
    
    julia> vf(1,x...)
    (1, 7, (8, 9))
    
    julia> vf(x...)
    (7, 8, (9,))
    

    原函数可以不是可变参数,一样可以对元组或者阵列引用,定义非可变函数ff():

    julia> ff(a, b) = a + b
    ff (generic function .with 1 method)
    
    julia> x = (5,6)
    (5, 6)
    
    julia> ff(x...)
    11
    
    julia> x = [7,8]
     2-element Array{Int64,1}:
    7
    8
    
    julia> ff(x...)
    15
    

    如果带入参数个数有问题,函数调用会失败。

    julia>x = [7,8,9]
    7
    8
    9
    
    julia> ff(x...)
    ERROR: MethodError: no method matching ff(::Int64, ::Int64, ::Int64)
    Closest candidates are:
      ff(::Any, ::Any) at none:1
    Stacktrace:
    [1] top-level scope at none:0
    
    x = 1
    1
    
    julia> ff(x...)
    ERROR: MethodError: no method matching ff(::Int64)
    Closest candidates are:
      ff(::Any, ::Any) at none:1
    Stacktrace:
    [1] top-level scope at none:0
    

    可选参数

    函数入参中,个别参数为可选项,可以不传入,因为在函数定义时设定了默认值,比如我们定义函数oa():

    function oa(x, y, z = 100)
      return x+y+z
    end
    
    julia> oa(1,2)
    103
    
    julia> oa(1,2,3)
    6
    

    常见的日期函数Date(),就属于可选参数函数:
    julia> using Dates

    julia> Date(2000, 12, 12)
    2000-12-12
    
    julia> Date(2000, 12)
    2000-12-01
    
    julia> Date(2000)
    2000-01-01
    

    Do-Block语法

    前面我们讲了map()函数的用法,当map()引用的函数为多行时,代码的可读性降低。Julia提供了do保留字,优化了代码风格,将遍历的入参提到和map()在同一行:

    julia> map([-1,100,0,0.001,1234567890,-999999]) do x
    if x < 0
      return 0
      elseif x == 0
        return 1
        else return x 
      end
    end
    6-element Array{Real,1}:
        0
    100.0
        1
        0.001
        1.23456789e9
        0
    

    点语法在函数应用中的场景

    科学严谨地描述是:给定函数f(x)应用于数组的每个元素A以产生新的数组f(A)。
    说人话就是:一个函数f(x),一个数组A,要把数组A中每个数都代入f(x)计算,计算结果生成新的数组。
    通常而又朴素的编程技巧告诉我们,我们需要实现得到数组A长度,并声明一个数组B和数组A等长,再建立一个循环体,把f(x)置于循环体内,依次代入数组A的每个数值,并把计算结果放入数组B。
    本来简单的事情,用代码写起来竟然变得这么复杂。
    好在Julia提供了点语法,没多就是英文半角的这个“.”。
    下面以cosd()函数的使用举例:

    julia> a = [0,60,90,120,180]
    5-element Array{Int64,1}:
       0
      60
      90
     120
     180
    
    julia> cosd.(a)
    5-element Array{Float64,1}:
      1.0
      0.5
      0.0
     -0.5
     -1.0
    

    再以梯形面积公式举例:

    julia> a = [10,30,60]
    3-element Array{Int64,1}:
     10
     30
     60
    
    julia> b = [20,50,100]
    3-element Array{Int64,1}:
      20
      50
     100
    
    julia> h = [100,50,20]
    3-element Array{Int64,1}:
     100
      50
      20
    
    julia> f(x,y,h) = (x + y) * h /2
    f (generic function with 2 methods)
    
    julia> f.(a,b,h)
    3-element Array{Float64,1}:
     1500.0
     2000.0
     1600.0
    

    我们再看一下函数嵌套使用中,“@.”的语法,以sin()和asin为例:

    julia> y = [0.0,30.0,60.0,90.0,120.0,150.0,180.0]
    7-element Array{Float64,1}:
       0.0
      30.0
      60.0
      90.0
     120.0
     150.0
     180.0
    
    julia> x = similar(y) # pre-allocate output array
    7-element Array{Float64,1}:
     1.0609978956e-313
     1.9097962122e-313
     2.33419537056e-313
     2.970794108e-313
     3.18299368704e-313
     3.60739284563e-313
     2.1219957915e-314
    
    julia> @.x = asind(sind(y))
    7-element Array{Float64,1}:
      0.0
     30.000000000000004
     59.99999999999999
     90.0
     59.99999999999999
     30.000000000000004
      0.0
    

    上面的x = similar(y),是为了开辟一个新数组接收下面的函数输出。

    相关文章

      网友评论

          本文标题:JULIA-函数

          本文链接:https://www.haomeiwen.com/subject/roewtqtx.html