Conditional statements in Julia - julia

I define two non-empty vectors:
tmp = [1, 2, 3]
tmp2 = [1, 2]
When I type
size(tmp, 1) > 0
The output is true. But when I write
size(tmp, 1) > 0 & size(tmp2, 1) > 0
it returns false.
When I put each term into a parentheses, as in
(size(tmp, 1) > 0) & (size(tmp2, 1) > 0 )
it returns true as expected. But I don't understand why size(tmp, 1) > 0 & size(tmp2, 1) > 0 returns false?

This is a result of 2 things. The first is operator precedence. The code you wrote is parsed as size(tmp, 1) > (0 & size(tmp2, 1)) > 0 (ie as a chained comparison).
The bigger issue, however is that you probably wanted to use && instead of &. & is a bitwise and, while && is a logical and. As such, && has the precedence you expect here.

Related

Check multiple conditions on the same function output in Julia

Is there a way to check multiple Boolean conditions against a value (to achieve the same as below) without computing sum twice or saving the result to a variable?
if sum(x) == 1 || sum(x) > 3
# Do Something
end
You can use one of several options:
Anonymous function:
if (i->i>3||i==1)(sum(x))
# Do Something
end
Or,
if sum(x) |> i->i>3||i==1
# Do Something
end
DeMorgan's theorem:
if !(3 >= sum(x) != 1)
# Do Something
end
And if used inside a loop:
3 >= sum(x) != 1 && break
# Do Something
or as function return:
3 >= sum(x) != 1 && return false
But using a temporary variable would be the most readable of all:
s = sum(x)
if s > 3 || s == 1
# Do Something
end
Syntactically, a let is valid in that position, and the closest equivalent to AboAmmar's variant with a lambda:
if let s = sum(x)
s == 1 || s > 3
end
# do something
end
I'd consider this rather unidiomatic, though.

I am not able to understand what this piece of code is doing. can anyone please explain?

excelTbl[, .(sum(`Current Period Amount`),
sum(`Comparison Period Amount`),
sum(`% Change`),
type = if (sum(`Current Period Amount`) - sum(`Comparison Period Amount`)< 0) "N" else "P"),
by = .(Class, AccountSubType)][round(V1) != 0 &
round(V2) != 0 &
(if (logicalOp == 1) {
((abs(V2 - V1) * 100 / abs(V2)) >= variancePer) &
#(abs(V3)*100 >= variancePer) &
(abs(V2 - V1) >= varianceAmt * 1000000)
} else {
((abs(V2 - V1) * 100 / abs(V2)) >= variancePer) |
#(abs(V3)*100 >= variancePer) |
(abs(V2 - V1) >= varianceAmt * 1000000)
}), 1:2]
round(V1) != 0 returns a logical vector as long as there are rows in the table. For example,
1:5 < 3
# [1] TRUE TRUE FALSE FALSE FALSE
... & round(V2) != 0 is a vectorized "AND", where it is still as long as there are rows in the table. For example,
(1:5 < 3) & (6:10 < 7)
# [1] TRUE FALSE FALSE FALSE FALSE
if (logicalOp == 1) ... else ... will calculate one of two logical vectors based on the value of logicalOp. If it is 1, then it logically "AND"s the logical vector returned from
((abs(V2 - V1) * 100 / abs(V2)) >= variancePer) &
(abs(V2 - V1) >= varianceAmt * 1000000)
otherwise the other vector.
This is vector-wise "AND"ed with the results of the two round logical vectors.
And because all of that is before the first comma (it is in the i= component of the bracket indexing), it defined which rows to return. If you have a logical vector as long as there are rows, then the rows with TRUE will be preserved, FALSE will be discarded.
While many things in data.table operate in-place (referential semantics, as opposed to R's regular copy-on-write semantics), anything that subsets the rows like this will return another data.table object and not modify the original in-place. Because of this, the value of this code chunk should be captured into a new variable.
After the comma, 1:2 selects the first two columns.
Interestingly, the first bracket block creates a data.table with six columns, named Class and AccountSubType (the groups defined with by=), V1, V2, V3, and type. However, the second bracket block only references V1 and V2 in the filtering and then discards all except Class and AccountSubType, so ... it seems there is unnecessary calculation.

if else statement concatenation - R

This is a very common question: 1, 2, 3, 4, 5, and still I cannot find even an answer to my problem.
If a == 1, then do X.
If a == 0, then do Y.
If a == 0 and b == 1, then do Z.
Just to explain: the if else statements has to do Y if a==0 no matter the value of b. But if b == 1 and a == 0, Z will do additional changes to those already done by Y.
My current code and its error:
if (a == 1){
X
} else if(a == 0){
Y
} else if (a == 0 & b == 1){
Z}
Error in !criterion : invalid argument type
An else only happens if a previous if hasn't happened.
When you say
But if b == 1 and a == 0, Z will do additional changes to those already done by Y
Then you have two options:
## Option 1: nest Z inside Y
if (a == 1){
X
} else if(a == 0){
Y
if (b == 1){
Z
}
}
## Option 2: just use `if` again (not `else if`):
if (a == 1) {
X
} else if(a == 0) {
Y
}
if (a == 0 & b == 1) {
Z
}
Really, you don't need any else here at all.
## This will work just as well
## (assuming that `X` can't change the value of a from 1 to 0
if (a == 1) {
X
}
if (a == 0) {
Y
if (b == 1){
Z
}
}
Typically else is needed when you want to have a "final" action that is done only if none of the previous if options were used, for example:
# try to guess my number between 1 and 10
if (your_guess == 8) {
print("Congratulations, you guessed my number!")
} else if (your_guess == 7 | your_guess = 9) {
print("Close, but not quite")
} else {
print("Wrong. Not even close!")
}
In the above, else is useful because I don't want to have enumerate all the other possible guesses (or even bad inputs) that a user might enter. If they guess 8, they win. If they guess 7 or 9, I tell them they were close. Anything else, no matter what it is, I just say "wrong".
Note: this is true for programming languages in general. It is not unique to R.
However, since this is in the R tag, I should mention that R has if{}else{} and ifelse(), and they are different.
if{} (and optionally else{}) evaluates a single condition, and you can run code to do anything in {} depending on that condition.
ifelse() is a vectorized function, it's arguments are test, yes, no. The test evaluates to a boolean vector of TRUE and FALSE values. The yes and no arguments must be vectors of the same length as test. The result will be a vector of the same length as test, with the corresponding values of yes (when test is TRUE) and no (when test is FALSE).
I believe you want to include Z in the second condition like this:
if (a == 1){X}
else if(a == 0){
Y
if (b == 1){Z}
}

What does "&&" do?

I can't seem to find the resource I need. What does && do in a code that is comparing variables to determine if they are true? If there is a link with a list of the symbol comparisons that would be greatly appreciated.
example: Expresssion 1: r = !z && (x % 2);
In most programming languages that use &&, it's the boolean "and" operator. For example, the pseudocode if (x && y) means "if x is true and y is true."
In the example you gave, it's not clear what language you're using, but
r = !z && (x % 2);
probably means this:
r = (not z) and (x mod 2)
= (z is not true) and (x mod 2 is true)
= (z is not true) and (x mod 2 is not zero)
= (z is not true) and (x is odd)
In most programming languages, the operator && is the logical AND operator. It connects to boolean expressions and returns true only when both sides are true.
Here is an example:
int var1 = 0;
int var2 = 1;
if (var1 == 0 && var2 == 0) {
// This won't get executed.
} else if (var1 == 0 && var2 == 1) {
// This piece will, however.
}
Although var1 == 0 evaluates to true, var2 is not equals to 0. Therefore, because we are using the && operator, the program won't go inside the first block.
Another operator you will see ofter is || representing the OR. It will evaluate true if at least one of the two statements are true. In the code example from above, using the OR operator would look like this:
int var1 = 0;
int var2 = 1;
if (var1 == 0 || var2 == 0) {
// This will get executed.
}
I hope you now understand what these do and how to use them!
PS: Some languages have the same functionality, but are using other keywords. Python, e.g. has the keyword and instead of &&.
It is the logical AND operator
(&&) returns the boolean value true if both operands are true and returns false otherwise.
boolean a=true;
boolean b=true;
if(a && b){
System.out.println("Both are true"); // Both condition are satisfied
}
Output
Both are true
The exact answer to your question depends on the which language your are coding in. In R, the & operator does the AND operation pairwise over two vectors, as in:
c(T,F,T,F) & c(T,T,F,F)
#> TRUE FALSE FALSE FALSE
whereas the && operator operated only on the first element of each vector, as in:
c(T,F,T,F) && c(T,T,F,F)
#> TRUE
The OR operators (| and ||) behave similarly. Different languages will have different meanings for these operators.
In C && works like a logical and, but it only operates on bool types which are true unless they are 0.
In contrast, & is a bitwise and, which returns the bits that are the same.
Ie. 1 && 2 and 1 && 3 are true.
But 1 & 2 is false and 1 & 3 is true.
Let's imagine the situation:
a = 1
b = 2
if a = 1 && b = 2
return "a is 1 and b is 2"
if a = 1 && b = 3
return "a is 1 and b is 3"
In this situation, because a equals 1 AND b = 2, the top if block would return true and "a is 1 and b is 2" would be printed. However, in the second if block, a = 1, but b does not equal 3, so because only one statement is true, the second result would not be printed. && Is the exact same as just saying and, "if a is 1 and b is 1".

What functions work with JuMPArrays?

Is there a way to make certain functions such as isinteger() work with JuMPArrays?
I am using Julia/JuMP to solve an optimization problem, and after I get the solution, I want to check if the solution is integer. So here is what I wrote:
#defVar(m, 0<= x[1:3] <= 1)
...
xstar = getValue(x)
if isinteger(xstar)
...
end
And I get an error saying isinteger() has no method matching isinteger(::JuMPArray).
Thanks
So in general you can get an underlying array from a JuMPArray by using [:], e.g.
m = Model()
#variable(m, 0 <= x[1:3] <= 1)
#variable(m, 0 <= y[1:10, 1:10] <= 1)
solve(m)
xstar = getvalue(x)[:]
ystar = getvalue(y)[:,:]
Note that the reason for this is that JuMPArrays don't have to start with index 1, so the user needs to explicitly say they want a normal Julia array before doing things.
Regardless, you shouldn't use isinteger. Solvers don't always return very precise answers, e.g. they might say x[1] = 0.999996 but they really mean it is 1. You should do something like
for i in 1:3
if getvalue(x[i]) >= 0.999
println("x[$i] is 1!")
elseif getvalue(x[i]) <= 0.001
println("x[$i] is 0!")
end
end
to make sure you don't get any false negatives. If the variable is restricted to be integer or binary, use iround, e.g.
for i in 1:3
v = iround(getvalue(x[i]))
if v == 1
println("x[$i] is 1!")
elseif v == 0
println("x[$i] is 0!")
end
end
but it looks like in this case you are just seeing if the solution is naturally 0 or 1.

Resources