# Specifying the numerical precision and ranks of the array arguments of a function

**URL:** <https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814>\
**Category:** New to Julia\
**Created:** [May 25, 2021, 8:50pm UTC](https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814 "2021-05-25T20:50:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://discourse.julialang.org/u/Beliavsky)\
**Post date:** [May 25, 2021, 8:50pm UTC](https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814/1 "2021-05-25T20:50:52Z")

</div>

Following is a Fortran function for matrix vector multiplication. It specifies that `a(:,:)` is a rank-2 array of 64-bit floats and that `x(:)` and `b(:)` are rank-1 arrays of 64-bit floats.

```julia
function matrix_vec_mult(a,x) result(b)
! return the product of matrix a and vector x
use iso_fortran_env, only: real64
real(kind=real64), intent(in) :: a(:,:)
real(kind=real64), intent(in) :: x(:)
real(kind=real64) :: b(size(a,1))
integer :: i
do i=1,size(a,1)
   b(i) = sum(a(i,:)*x)
end do
end function matrix_vec_mult

```

I know that arguments can be declared `Array{Number}` in Julia, but is it possible to be as specific as the code above regarding argument rank and numerical precision?

The `intent(in)` designation means that the argument cannot be changed within the procedure. Is there a Julia analog for that?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 25, 2021, 8:58pm UTC](https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814/2 "2021-05-25T20:58:10Z")

</div>

> [@Beliavsky](#):
>
> is it possible to be as specific as the code above regarding argument rank and numerical precision?

Yes, that would be `Array{Float64, 2}` and `Array{Float64, 1}` respectively (or the aliases `Matrix{Float64}` and `Vector{Float64}`).

> [@Beliavsky](#):
>
> The `intent(in)` designation means that the argument cannot be changed within the procedure. Is there a Julia analog for that?

No, this isn’t really possible in Julia. Immutable `struct`s can help organize data and control mutability, but there’s nothing you can do in a function definition to enforce that the function won’t mutate some mutable input (other than documenting that fact).

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 25, 2021, 9:12pm UTC](https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814/3 "2021-05-25T21:12:41Z")

</div>

Note that while you can specify what types your functions take, there is not a performance advantage in doing so.

```julia
function matrix_vec_mult(a,x)
    b = Vector{eltype(a)}(undef, size(a,1))
    for i=1:size(a,1)
        b[i] = sum(a[i,:]*x)
    end
    return b
end

```

will have the exact same performance as

```julia
function matrix_vec_mult(a::Matrix{Float64},x::Vector{Float64})
    b = Vector{Float64}(undef, size(a,1))
    for i=1:size(a,1)
        b[i] = sum(a[i,:]*x)
    end
    return b
end

```

because Julia always compiles a specialized version of your code for the argument types provided.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 25, 2021, 9:20pm UTC](https://discourse.julialang.org/t/specifying-the-numerical-precision-and-ranks-of-the-array-arguments-of-a-function/61814/4 "2021-05-25T21:20:53Z")

</div>

> [@Oscar\_Smith](#):
>
> `sum(a[i,:]*x)`

Note that this will give an error in Julia, because a 1d slice like `a[i,:]` creates a 1d array, not a row vector.

You can use `sum(a[i,:] .* x)`, though this is suboptimal because it creates a temporary array before summing. To avoid that temporary array, you can use `dot(a[i,:], x)` from the `LinearAlgebra` package (noting that `dot` conjugates the first argument if it is complex), or `a[i,:]' * x` (same as `dot`) or `transpose(a[i,:]) * x` (which doesn’t conjugate). `a[i,:]` also creates a copy for the slice, but you can avoid that by putting `@views` (e.g. before `function`).

(Of course, in reality you would just use `b = a * x` for a matrix–vector multiplication.)
