How to set product to 0 if its a product over an empty list in Julia? - list

In my code I use Julia's prod() function to do a product over the elements of a list. However, sometimes that list is empty, in which case I want prod(myList) to just return 0 (or any fixed number like 1). I tried searching online, but the only things I could find were for iterators or stuff like that.
I'm using Julia version 1.5.2.

Would a simple ternary operator work for your case?
isempty(my_list) ? 0 : prod(my_list)

What you want is incorrect/unconventional. The product of the elements of an empty sequence should be 1, because that is the multiplicative identity element.

"Any fixed number" is easy:
reduce(*, ls; init=1)
But this does not work well with zero, since that is an annihilator and sends the whole product to zero:
julia> ls = [1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> reduce(*, ls; init=0)
0
Now, returning 1 and then checking for that works if you only have integers. It doesn't as soon as you have a product over rationals, since then the resulting 1 could also stem from x * (1/x).

julia> zeroprod(x) = isempty(x) ? zero(eltype(x)) : prod(x)
zeroprod (generic function with 1 method)

Related

How to covert an array of type Float to Any in Julia?

I would like to convert an array to a python like list in Julia.
To create an array of type Any one may initialize an empty array with this syntax array = []. However if I want to perform conversion, i.e. lets take an array of type Array(Float64,1) to type Any, what would be the correct approach?
Or If there are any alternate approaches to create a list in Julia?
My approach to create a function which takes an array and convert it to type any:
function list(x)
x = convert(Any, x)
return x
end
x_test = [0.19, 0.03, 0.27]
t1 = typeof(x_test)
println("type of x_test is: $t1")
x_test = list(x_test)
t2 = typeof(x_test)
println("type of x_test is: $t2")
Output:
type of x_test is: Array{Float64,1}
type of x_test is: Array{Float64,1}
Please suggest a method or solution to achieve this conversion task.
Thanks.
You can do:
julia> list(x) = Any[i for i ∈ x]
list (generic function with 1 method)
julia> list([0.19, 0.03, 0.25])
3-element Vector{Any}:
0.19
0.03
0.25
But as Oscar says in his comments, why would you ever want to do that? It's true that Python performance often suffers because of a lack of type information, that doesn't mean Julia becomes "like Python" if you deliberately prevent the compiler from optimizing (it will become a lot slower though in almost all cases!)
The shortest form is Vector{Any}(a) as in code here:
julia> a=[1,2,3]
3-element Vector{Int64}:
1
2
3
julia> Vector{Any}(a)
3-element Vector{Any}:
1
2
3
However, if you want to be able to hold in a copy of a other elements such as Strings you will be much more efficient by strictly telling that:
julia> b = Vector{Union{eltype(a),String}}(a)
3-element Vector{Union{Int64, String}}:
1
2
3
julia> push!(b,"jan")
4-element Vector{Union{Int64, String}}:
1
2
3
"jan"
You were not far, you just need to convert to an array of Any:
julia> convert(Array{Any}, x_test)
3-element Vector{Any}:
0.19
0.03
0.27
But as others have said, it's not a good idea to hide type information in general because it will just slow things down.

Prolog List Neighbour of a Element

I am having problems with list of prolog. I want to make this:
[1,2,3,4,5]
[5,6,9,12,10]
You take a number for example 3, and you do a plus operation with the neighbours so the operation is 2+3+4 = 9. For the first and the last element you pretend there is an imaginary 1 there.
I have this now:
sum_list([A,X,B|T], [Xs|Ts]):-
add(A,X,B,Xs),
sum_list([X,B|T], Ts).
I haven't consider the first and the last element. My problem is I don't know how to get the element before and the next and then how to move on.
Note: I not allow to use meta-predicates.
Thanks.
I'm not sure how you calculated the first 5. The last 10 would be 4 + 5 + implicit 1. But following that calculation, the first element of your result should be 4 instead of 5?
Anyways, that doesn't really matter in terms of writing this code. You are actually close to your desired result. There are of course multiple ways of tackling this problem, but I think the simplest one would be to write a small 'initial' case in which you already calculate the first sum and afterwards recursively calculate all of the other sums. We can then write a case in which only 2 elements are left to calculate the last 'special' sum:
% Initial case for easily distinguishing the first sum
initial([X,Y|T],[Sum|R]) :-
Sum is X+Y+1,
others([X,Y|T],R).
% Match on 2 last elements left
others([X,Y],[Sum|[]]) :-
Sum is X+Y+1.
% Recursively keep adding neighbours
others([X,Y,Z|T],[Sum|R]) :-
Sum is X+Y+Z,
others([Y,Z|T],R).
Execution:
?- initial([1,2],Result)
Result = [4,4]
?- initial([1,2,3,4,5],Result)
Result = [4, 6, 9, 12, 10]
Note that we now don't have any cases (yet) for an empty list or a list with just one element in it. This still needs to be covered if necessary.

What the intention of this code?(Python 2.7)

Could somebody tell me the intention of the code below:
def factor(a):
d=2
while (d<=(a/2)):
if((a/d)*d==a):
return ((a/d),d)
d=d+1
return(a,1)
I think it uses the binary search, am I right?
why don't you plug in numbers and see what the result is? No, this is not a binary search. As the function name indicated, it returns the 2 factors of a number.
say:
a,b = factor(10) // a will be 5, b will be 2

list numbers 1 to n in function - SML

I need to create a function in sml that takes a single number and returns a list of all the numbers that are prime below it. I can do that but I dont know how to create a list so i can use to see if 1 is prime then 2 then 3 then 4 then 5 and so on.
Basicly i need a way to generate a list inside of an SML function and that list has the numbers from 2 to n.
The List.tabulate function will populate a list for you. Here's an example, giving you the numbers [2..n]:
List.tabulate(n-1, fn x => x+2);
I found out that we can not use external libraries for this so I actually was able to come up with a solution of my own. It does the numbers from start to up to, but not including, ending
fun createList(start:int, ending:int) = if(start = ending) then
[]
else
start::createList(start + 1, ending);

Why is [1..n] not handled the same way as [n..1] in Haskell?

I was trying to solve a problem that required the maximum value of a list after being mapped over by a function. The list is a range from a to b where a>b or b>a. Because Haskell can also define decreasing lists i thought that i didn't need to check if a>b and there was no need to flip the bounds to b..a. The function looks somewhat like this:
f a b = maximum . map aFunction $ [a..b]
But if the list is decreasing i.e. a>b then Haskell gives me an exception:
Prelude.maximum: empty list
So for some reason a decreasing list hands over an empty list to the maximum function. Why is that?
I know that maximum is defined in terms of a foldl1 max and that foldl1 needs a non empty list but i don't know why a list like [10..1] is empty when handed to a foldl1.
[a..b] desugars to enumFromTo a b. For standard numeric types (modulo a couple of quirks for floating), this keeps adding one until you are >= b. So where b < a this is empty.
You can change the increment by using the following syntax [a,a'..b] which then takes steps in increments of a'-a. So [10,9..1] will be what you want.
This is because of the way the sequence is defined in Haskell Report Arithmetic Sequences
:
[ e1..e3 ] = enumFromTo e1 e3
and Haskell Report The Enum Class
The sequence enumFromTo e1 e3 is the list [e1,e1 + 1,e1 + 2, ... e3]. The list is empty if e1 > e3.
(emphasis added).
They are handled exactly the same way. You start from the first bound and count up.