boolean matching using & operator - julia

Ok lets take this logic here:
dummy = [1 2 3 4 5]
num_test = convert(Array{Int64},3 .== dummy)
I get the result:
0 0 1 0 0
If I try and match two statements:
num_test = convert(Array{Int64},3 .== dummy & 4 .== dummy)
It doesnt evaluate:
0 0 0 0 0
As i am writing this, is this because in the .== vectored call its looking for 3 & 4 on the same index element position?
I can do similar operations in R. But same type of logic not transferring to Julia or am I using incorrect syntax Julia?
Thanks

I'm assuming that the operation you are trying to perform is to evaluate 3 .== dummy and 4 .== dummy, and then compare the two element-wise. Given this, there are two problems here:
1) Order of operations. You need (3 .== dummy) & (4 .== dummy).
2) If you are on a recent v0.6, you should also be seeing a deprecation warning, since from v0.7+, you will need to broadcast the & operator. So use (3 .== dummy) .& (4 .== dummy).
As I understand the question, the conversion to Vector{Int} part is fine, and should work as expected, although you could just write Int.((3 .== dummy) .& (4 .== dummy)).
Given all of the above, you should now see the following outcomes:
julia> Int.((3 .== dummy) .& (4 .== dummy))
1×5 Array{Int64,2}:
0 0 0 0 0
julia> Int.((3 .== dummy) .| (4 .== dummy))
1×5 Array{Int64,2}:
0 0 1 1 0
One final note, I'm assuming you deliberately defined dummy to be a single-row Matrix rather than a Vector. If you wanted your final output to be a Vector, then you would use dummy = [1,2,3,4,5]

Related

Rewriting on Infinite Matrices

I've taken a project named with "Symbolic Linear Algebra" which is about doing basic operations on infinite matrices like addition, multiplication, accessing specific element etc. I will be implementing those on Julia.
For specifying those infinite matrices we'll have some mathematical cases like:
So the visual representation of matrix will be like:
For example let's say we want to find A + A' for this example. Here our cases change so we need to rewrite those cases to get desired output right ? I know Mathematica does this but how can I implement this? Yes, this was too general so let me ask some questions;
Let's start with taking cases as input. There can be many cases with different rules like if i % 2 == 0 or i == j like in this example how can I provide a generic input ?
Let's say that I'm done with input and I want to make those simple operations. How can I combine those cases in a programming language like Julia ?
I've wrote some non-generic dumb code to see how things will go so I will provide my code to apply minimum reproducible example but don't take it seriously, I think I'm just looking for a clue or a roadmap to get rid of the question marks in my head.
using Parameters
struct inf_matrix
mod_of :: Integer
mod_value :: Integer
i_coefficient :: Integer
j_coefficient :: Integer
value :: Integer
end
function single_demo(_mod_of :: Integer, _mod_value :: Integer, _i_coefficient :: Integer, _j_coefficient :: Integer, _value :: Integer)
test_matrix = inf_matrix(_mod_of, _mod_value, _i_coefficient, _j_coefficient, _value)
return test_matrix
end
function get_elem(st::inf_matrix ,i :: Integer, j :: Integer)
#This function is not completed yet
if (i % st.mod_of == st.mod_value) && (2 * st.i_coefficient == j)
return st.value;
else
return -1
end
end
demo_1 = single_demo(2, 0 ,1, 2, 1)
println(get_elem(demo_1, 1, 0))
Any help would be appreciated.
Here is how you could do this
import Base: getindex, +, *
abstract type InfiniteMatrix end
struct InfiniteIdentity <: InfiniteMatrix end
getindex(::InfiniteIdentity, i, j) = i .== j'
struct InfiniteConstant <: InfiniteMatrix
c
end
getindex(m::InfiniteConstant, i::Integer, j::Integer) = m.c
getindex(m::InfiniteConstant, i, j) = fill(m.c, size(i)..., size(j)...)
struct InfiniteMatrixFilter <: InfiniteMatrix
condition::Function
iftrue::InfiniteMatrix
iffalse::InfiniteMatrix
end
getindex(m::InfiniteMatrixFilter, i, j) = ifelse.(m.condition.(i,j'), m.iftrue[i,j], m.iffalse[i,j])
struct InfiniteMatrixFunction <: InfiniteMatrix
f::Function
args
end
getindex(m::InfiniteMatrixFunction, i, j) = m.f(getindex.(m.args, Ref(i), Ref(j))...)
+(m1::InfiniteMatrix, m2::InfiniteMatrix) = InfiniteMatrixFunction(+, (m1, m2))
*(n::Number, m::InfiniteMatrix) = InfiniteMatrixFunction(x -> n*x, (m,))
julia> i = InfiniteIdentity()
InfiniteIdentity()
julia> c1 = InfiniteConstant(1)
InfiniteConstant(1)
julia> (2i+3c1)[1:5, 1:5]
5×5 Array{Int64,2}:
5 3 3 3 3
3 5 3 3 3
3 3 5 3 3
3 3 3 5 3
3 3 3 3 5
julia> m = InfiniteMatrixFilter((i,j) -> i%2 == 0, c1, 0c1)
InfiniteMatrixFilter(var"#43#44"(), InfiniteConstant(1), InfiniteMatrixFunction(var"#41#42"{Int64}(0), (InfiniteConstant(1),)))
julia> m[1:5, 1:5]
5×5 Array{Int64,2}:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
(this is only a proof of concept and it's not optimized or bugfree)

Julia: Finding values larger than 0 in vector with missing

I'm fairly new to Julia and as a Matlab/R User I find it, for the most part, really nice to work with.
However, I'm a little confused by the missing values and how to work with them.
Let's say I have a vector:
a=[missing -1 2 3 -12] #Julia
a=[NaN -1 2 3 -12] #Matlab
In Matlab I would just do the following to find the values below 0
a(a<0)
which gives me
-1 -12
The same unfortunately doesn't work in Julia and when I try
a[a.<0]
in Julia I just get the following error
ERROR: ArgumentError: unable to check bounds for indices of type Missing
I also tried the following
a[findall(skipmissing(a).<0)]
which gives me
missing
3
since, of course, I skipped the missing value in the findall-function. I'm pretty sure there is an easy and logical way to do this, but I don't seem to be able to find it.
Can someone please show me the way?
Best,
Richard
Here is the simplest way to do it:
julia> a=[missing -1 2 3 -12]
1×5 Array{Union{Missing, Int64},2}:
missing -1 2 3 -12
julia> a[isless.(a, 0)]
2-element Array{Union{Missing, Int64},1}:
-1
-12
This uses the fact that missing is considered larger than any number by isless.
Another way to write it:
julia> filter(x -> isless(x, 0), a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
Now in order to avoid this special trick with isless you can do the following (using coalesce is a general approach that can be used for safe handling of missing values):
julia> a[coalesce.(a .< 0, false)]
2-element Array{Union{Missing, Int64},1}:
-1
-12
or
julia> filter(x -> coalesce(x < 0, false), a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
finally you can be more explicit like:
julia> filter(x -> !ismissing(x) && x < 0, a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
or
julia> [v for v in a if !ismissing(v) && v < 0]
2-element Array{Int64,1}:
-1
-12
(you could use comprehension syntax also in the examples above)

Julia: creating SparseArrays

I want to create a sparse array where I define a rule to combine duplicates. The documentation says that I can do this with sparse(i,j,v,[m,n,combine]). I've tried in the example below but am unsuccessful. Can you please advise?
i = [1,2,3,3];
j = [1,2,3,2];
v = [10.,11.,12.,13.];
full(sparse([i;j],[j;i],[v;v], [3,3,combine(a,b)=mean([a,b])]))
full(sparse([i;j],[j;i],[v;v], [3,3,mean]))
full(sparse([i;j],[j;i],[v;v], [3,3,-(a,b)]))
full(sparse([i;j],[j;i],[v;v], [3,3,-]))
Square brackets in docstring mean that those are optional arguments. The way to write it is:
julia> full(sparse([i;j],[j;i],[v;v], 3,3,-))
3×3 Array{Int64,2}:
0 0 0
0 0 13
0 13 0
you can omit the last argument, then combine defaults to +:
julia> full(sparse([i;j],[j;i],[v;v], 3,3))
3×3 Array{Int64,2}:
20 0 0
0 22 13
0 13 24
You can check what argument sets the function accepts using methods(sparse). Additionally if you e.g. write #edit sparse([i;j],[j;i],[v;v]) you will go to the source code of sparse and can learn exactly what is accepted.

How do you select a subset of an array based on a condition in Julia

How do you do simply select a subset of an array based on a condition? I know Julia doesn't use vectorization, but there must be a simple way of doing the following without an ugly looking multi-line for loop
julia> map([1,2,3,4]) do x
return (x%2==0)?x:nothing
end
4-element Array{Any,1}:
nothing
2
nothing
4
Desired output:
[2, 4]
Observed output:
[nothing, 2, nothing, 4]
You are looking for filter
http://docs.julialang.org/en/release-0.4/stdlib/collections/#Base.filter
Here is example an
filter(x->x%2==0,[1,2,3,5]) #anwers with [2]
There are element-wise operators (beginning with a "."):
julia> [1,2,3,4] % 2 .== 0
4-element BitArray{1}:
false
true
false
true
julia> x = [1,2,3,4]
4-element Array{Int64,1}:
1
2
3
4
julia> x % 2 .== 0
4-element BitArray{1}:
false
true
false
true
julia> x[x % 2 .== 0]
2-element Array{Int64,1}:
2
4
julia> x .% 2
4-element Array{Int64,1}:
1
0
1
0
You can use the find() function (or the .== syntax) to accomplish this. E.g.:
julia> x = collect(1:4)
4-element Array{Int64,1}:
1
2
3
4
julia> y = x[find(x%2.==0)]
2-element Array{Int64,1}:
2
4
julia> y = x[x%2.==0] ## more concise and slightly quicker
2-element Array{Int64,1}:
2
4
Note the .== syntax for the element-wise operation. Also, note that find() returns the indices that match the criteria. In this case, the indices matching the criteria are the same as the array elements that match the criteria. For the more general case though, we want to put the find() function in brackets to denote that we are using it to select indices from the original array x.
Update: Good point #Lutfullah Tomak about the filter() function. I believe though that find() can be quicker and more memory efficient. (though I understand that anonymous functions are supposed to get better in version 0.5 so perhaps this might change?) At least in my trial, I got:
x = collect(1:100000000);
#time y1 = filter(x->x%2==0,x);
# 9.526485 seconds (100.00 M allocations: 1.554 GB, 2.76% gc time)
#time y2 = x[find(x%2.==0)];
# 3.187476 seconds (48.85 k allocations: 1.504 GB, 4.89% gc time)
#time y3 = x[x%2.==0];
# 2.570451 seconds (57.98 k allocations: 1.131 GB, 4.17% gc time)
Update2: Good points in comments to this post that x[x%2.==0] is faster than x[find(x%2.==0)].
Another updated version:
v[v .% 2 .== 0]
Probably, for the newer versions of Julia, one needs to add broadcasting dot before both % and ==

Location of minimum in Julia

Does Julia have a build in command to find the index of the minimum of a vector? R, for example, has a which.min command (and a which.max, of course).
Obviously, I could write the following myself, but it would be nice not to have to.
function whichmin( x::Vector )
i = 1
min_x=minimum(x)
while( x[i] > min_x )
i+=1
end
return i
end
Apologies if this has been asked before, but I couldn't find it. Thanks!
Since 0.7-alpha, indmin and indmax are deprecated.
Use argmin and argmax instead.
For a vector it just returns the linear index
julia> x = rand(1:9, 4)
4-element Array{Int64,1}:
9
5
8
5
julia> argmin(x)
2
julia> argmax(x)
1
If looking for both the index and the value, use findmin and findmax.
For multidimensional array, all these functions return the CartesianIndex.
I believe indmax(itr) does what you want. From the julia documentation:
indmax(itr) → Integer
Returns the index of the maximum element in a collection.
And here's an example of it in use:
julia> x = [8, -4, 3.5]
julia> indmax(x)
1
There's also findmax, that returns both the maximum value and its position.
For multidim array, you'll have to switch between linear indexes et multidim indexes:
x = rand(1:9, 2,3)
# 2×3 Array{Int64,2}:
# 5 1 9
# 3 3 8
indmin(x)
# 3
# => third element in the column-major ordered array (value=1)
ind2sub(size(x),indmin(x))
# (1, 2)
# => (row,col) indexes: what you are looking for.
-- Maurice

Resources