How can I transform this matlab code into Julia

>> val = zeros(3, 3);
>> row = zeros(3, 3);
>> A = [1 2 3; 6 5 1; 1 7 4];

[val(1, :), row(1, :)] = max(A)

val =

     6     7     4
     0     0     0
     0     0     0


row =

     2     3     3
     0     0     0
     0     0     0

How can I get the max value and row number and save them.

1 Like
julia> vals, idx = findmax(A, dims=1)
([6 7 4], CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(3, 2) CartesianIndex(3, 3)])

julia> vals
1×3 Matrix{Int64}:
 6  7  4

julia> idx
1×3 Matrix{CartesianIndex{2}}:
 CartesianIndex(2, 1)  CartesianIndex(3, 2)  CartesianIndex(3, 3)

If you need the row only and not the full index:

row = first.(Tuple.(idx))
1×3 Matrix{Int64}:
 2  3  3
4 Likes

yes, I only need the row only. Thanks, it solves my problem.

1 Like

Dear @skleinbo ,

how can I transform this matlab code into Julia code.

Here is the MATLAB code.

>> xx = zeros(2, 3)

xx =

     0     0     0
     0     0     0

>> yy = zeros(2, 3)

yy =

     0     0     0
     0     0     0

>> location = [1 2 3; 2 3 4]

location =

     1     2     3
     2     3     4

>> [xx(1,:), yy(1,:)] = ind2sub([2,2], location(1,:))

xx =

     1     2     1
     0     0     0


yy =

     1     1     2
     0     0     0

I want to transform this matlab code into Julia. and I try to rewrite the code,but get an error.

julia> xx = zeros(2, 3)
2×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0

julia> yy = zeros(2, 3)
2×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0


julia> location = [1 2 3; 2 3 4]
2×3 Matrix{Int64}:
 1  2  3
 2  3  4

julia> xx[1,:] .= CartesianIndices((2, 2))[location[1,:]][1]
ERROR: iteration is deliberately unsupported for CartesianIndex. Use `I` rather than `I...`, or use `Tuple(I)...`
Stacktrace:

Can you help me to correct my code to get the row and column index by the first row of location?

You can use LinearIndices and CartesianIndices to convert between linear and cartesian indices.

Edit: Ah, sorry, didn’t see you had discovered that already. You need to convert the cartesian indices to a tuple before indexing first, like the error suggests. Maybe

xx[1,:] .= first.(Tuple.(CartesianIndices((2, 2))[location[1,:]]))

As you can see, this is a bit unwieldy and inelegant and should prompt you to consider a less MATLABy way.

I try to use loop .

julia> for i in 1:2, j in 1:3
          xx[i, j] = CartesianIndices((2, 2))[location[i, j]][1]
       end

julia> for i in 1:2, j in 1:3
          yy[i, j] = CartesianIndices((2, 2))[location[i, j]][2]
       end

julia> xx
2×3 Matrix{Float64}:
 1.0  2.0  1.0
 2.0  1.0  2.0

julia> yy
2×3 Matrix{Float64}:
 1.0  1.0  2.0
 1.0  2.0  2.0

This is the result what I need. But I don’t think loop is the best way.

Thanks so much.This solves my problem.

Does Julia have the same function ind2sub or sub2ind? I think CartesianIndices or LinearIndices is worse than matlab function ind2sub.

Not for a long time PSA: replacement of ind2sub/sub2ind in Julia 0.7+

@skleinbo I have another problem. I have convert the results to Int, but why the type is still Float64?

 pol_ind_kp[iak_state, :] = Int.(first.(Tuple.(CartesianIndices((nk, na))[Int.(location[iak_state, :])])))
 
typeof(pol_ind_kp)
Matrix{Float64} (alias for Array{Float64, 2})

I have solved the problem by myself. I forget to set the zeros matrix Int when I define the pol_ind_kp.

Loops aren’t bad. They’re often the best way to solve a problem.

1 Like

Thanks for your reply. But I think loops may take a very long time.

They do in Matlab, but loops in Julia are fast.

2 Likes

Oh, It is really a good news to me. I use matlab and Stata very often. And loops always take a very long time. Thank you very much.

Matlab to Julia requires significant unlearning of bad habits. Another one for free: whenever you type rand(1) or rand(n,1), you almost certainly want rand() or rand(n).

Read carefully the Performance Tips · The Julia Language

Particularly the first one. There is where most commonly new Julia users fail to get a good performance.

Dear @skleinbo ,

how can I use LinearIndices to get the index. In matlab, we can use sub2ind.

>> A = [1 2 1; 2 2 1]

A =

     1     2     1
     2     2     1

>> inds = sub2ind([2,2], A(1,:), A(2,:))

inds =

     3     4     1

@ murphyk I try to use function sub2indv which @ murphyk wrote.

function subv2ind(shape, cindices)
    """Return linear indices given vector of cartesian indices.
    shape: d-tuple of dimensions.
    cindices: n-iterable of d-tuples, each containing cartesian indices.
    Returns: n-vector of linear indices.

    Based on:
    https://discourse.julialang.org/t/psa-replacement-of-ind2sub-sub2ind-in-julia-0-7/14666/8
    Similar to this matlab function:
    https://github.com/tminka/lightspeed/blob/master/subv2ind.m
    """
    lndx = LinearIndices(Dims(shape))
    n = length(cindices)
    out = Array{Int}(undef, n)
    for i = 1:n
        out[i] = lndx[cindices[i]...]
    end
    return out
end


julia> A = [1 2 1; 2 2 1]
2×3 Matrix{Int64}:
 1  2  1
 2  2  1

julia> subv2ind((2, 2), Tuple.(zip(A[1, :], A[2, :])))
3-element Vector{Int64}:
 3
 4
 1

Is there another simpler way to do this?

julia> subv2ind((2, 2), [(i, j) for (i, j) in zip(A[1, :], A[2, :])])
3-element Vector{Int64}:
 3
 4
 1