Writing a piecewise function inside deff - if-statement

I am using deff to define piecewise functions in Scilab. I use if-else statements to define the function in different intervals. All of them seem to work except for this one.
This is my approach:
deff('a=f(p)', ["if(q >= -2 & q <= -1) then"; "a=1"; "elseif(q >= 1 & q <= 2) then"; "a=-1"; "else"; "a=0"; "end";])
The same approach worked on similar functions such as this.
eff('a=f(p)', ["if((p > 0 & p <= 2)) then"; "a=p/2"; "else"; "a=0"; "end";])
I have defined q as so:
q = -3:Ts:3;
where Ts is some floating point number. What am I doing wrong?

You cannot use your function as-is when the input is a vector. A possible workaround is to use feval:
a = feval(q,f)
Another (better) solution is to code f in a vectorized manner:
function a = f(q)
a = 1*(q >= -2 & q <= -1) - 1*(q >= 1 & q <= 2)
end
the 1* are not necessary unless you need to change the values.

Related

C++ IF Statement inside a function issue

I am having some trouble with a basic program for a C++ class. In the following function, i have debugged and the arguments being passed in are correct, however the if statement below is returning 'F' for the first element of the array I pass in, and the second and each thereafter score I pass in is being returned as 'D'.
When I do the math out, my data set should hit each part of the if statement at least once, however im guessing maybe my PEMDAS is off?
Here is the if statement:
char grade(double score, double m, double s) {
if (score < (m - 1.5 * s)) {
return 'F';
}
if ((m - (1.5*s)) <= score < (m - (0.5 * s))) {
return 'D';
}
if ((m - (0.5 * s)) <= score < (m + (0.5 * s))) {
return 'C';
}
if ((m + (0.5 * s)) <= score < (m + (1.5 * s))) {
return 'B';
}
if ((m + (1.5 * s)) <= score) {
return 'A';
}
else {
return 'X';
}
}
An expression like:
a < b < c
does not do what you think it does. It actually evaluates as:
(a < b) < c
where a < b is a truth value giving 0 for false and 1 for true`. Then that value is used in the rest of the expression.
By way of example, the expression 100 < 200 < 42 will be true because 100 < 200 evaluates to 1, which is definitely less than 42.
Instead you should be using something like:
(a < b) && (b < c)
In any case, you can clean up that code quite a bit by realising that:
The construct if (condition) return else ... is totally unnecessary - the return means that the rest of the code will execute only if condition is false, rendering the else superfluous.
Because your ranges are mutually exclusive, the checks can be simplified. In other words, no need to check if (m - (1.5*s)) <= score in the D case since, if that weren't true, the code would already have returned F.
It is currently impossible to get an X grade since there is no score that doesn't get captured one of the if statements, excepting possibly some edge cases like NaN but I'm going to assume you're not worried about that.
With those points in mind, the code can be simplified to:
char grade(double score, double m, double s) {
if (score < m - 1.5 * s) return 'F';
if (score < m - 0.5 * s) return 'D';
if (score < m + 0.5 * s) return 'C';
if (score < m + 1.5 * s) return 'B';
return 'A';
}
We would need to know the input data values to have a complete understanding, however as others have pointed out, comparisons don't work like that in C++.
Take this comparison:
(m - (1.5*s)) <= score < (m - (0.5 * s))
What this is doing is first evaluating:
(m - (1.5*s)) <= score
Due to the first if statement failing, this will always evaluate to true. In C++, boolean values are integers, and true is usually represented by "1" (in practice it doesn't have to be, and can be represented by any non-zero number, but I think in this specific case it's being set to 1).
Then it's evaluating:
1 < (m - (0.5*s))
Which I'm assuming always returns true given your values of "m" and "s".
What you should be doing instead is using a compound statement:
if (m - 1.5*s <= score && score < m - 0.5*s)
(you can keep the parentheses if you like, but they're unnecessary here due to C++'s operator precedence rules)
Just drop all of the lower-bound comparisons (which, as others have said, do not do what you thought): if any of them don’t apply, you would already have returned one of the lower scores.

Fast inner product of ternary vectors

Consider two vectors, A and B, of size n, 7 <= n <= 23. Both A and B consists of -1s, 0s and 1s only.
I need a fast algorithm which computes the inner product of A and B.
So far I've thought of storing the signs and values in separate uint32_ts using the following encoding:
sign 0, value 0 → 0
sign 0, value 1 → 1
sign 1, value 1 → -1.
The C++ implementation I've thought of looks like the following:
struct ternary_vector {
uint32_t sign, value;
};
int inner_product(const ternary_vector & a, const ternary_vector & b) {
uint32_t psign = a.sign ^ b.sign;
uint32_t pvalue = a.value & b.value;
psign &= pvalue;
pvalue ^= psign;
return __builtin_popcount(pvalue) - __builtin_popcount(psign);
}
This works reasonably well, but I'm not sure whether it is possible to do it better. Any comment on the matter is highly appreciated.
I like having the 2 uint32_t, but I think your actual calculation is a bit wasteful
Just a few minor points:
I'm not sure about the reference (getting a and b by const &) - this adds a level of indirection compared to putting them on the stack. When the code is this small (a couple of clocks maybe) this is significant. Try passing by value and see what you get
__builtin_popcount can be, unfortunately, very inefficient. I've used it myself, but found that even a very basic implementation I wrote was far faster than this. However - this is dependent on the platform.
Basically, if the platform has a hardware popcount implementation, __builtin_popcount uses it. If not - it uses a very inefficient replacement.
The one serious problem here is the reuse of the psign and pvalue variables for the positive and negative vectors. You are doing neither your compiler nor yourself any favors by obfuscating your code in this way.
Would it be possible for you to encode your ternary state in a std::bitset<2> and define the product in terms of and? For example, if your ternary types are:
1 = P = (1, 1)
0 = Z = (0, 0)
-1 = M = (1, 0) or (0, 1)
I believe you could define their product as:
1 * 1 = 1 => P * P = P => (1, 1) & (1, 1) = (1, 1) = P
1 * 0 = 0 => P * Z = Z => (1, 1) & (0, 0) = (0, 0) = Z
1 * -1 = -1 => P * M = M => (1, 1) & (1, 0) = (1, 0) = M
Then the inner product could start by taking the and of the bits of the elements and... I am working on how to add them together.
Edit:
My foolish suggestion did not consider that (-1)(-1) = 1, which cannot be handled by the representation I proposed. Thanks to #user92382 for bringing this up.
Depending on your architecture, you may want to optimize away the temporary bit vectors -- e.g. if your code is going to be compiled to FPGA, or laid out to an ASIC, then a sequence of logical operations will be better in terms of speed/energy/area than storing and reading/writing to two big buffers.
In this case, you can do:
int inner_product(const ternary_vector & a, const ternary_vector & b) {
return __builtin_popcount( a.value & b.value & ~(a.sign ^ b.sign))
- __builtin_popcount( a.value & b.value & (a.sign ^ b.sign));
}
This will lay out very well -- the (a.value & b.value & ... ) can enable/disable an XOR gate, whose output splits into two signed accumulators, with the first pathway NOTed before accumulation.

How to assign binary variable in AMPL in respect to another variable

I have a problem with AMPL modelling. Can you help me how to define a binary variable u that suppose to be equall to 0 when another variable x is also equall to 0 and 1 when x is different than 0?
I was trying to use logical expressions but solver that I am working with (cplex and minos) doesn't allow it.
My idea was:
subject to:
u || x != u && x
Take M a 'big' constant such as x < M holds, and assume x is an integer (or x >= 1 if x is continuous). You can use the two constraints:
u <= x (if x=0, then u=0)
x <= M*u (if x>0, then u=1)
with u a binary variable.
If now x is continuous and not necessarily greater than 1, you will have to adapt the constraints above (for example, the first constraint here would not be verified with x=0.3 and u=1).
The general idea is that you can (in many cases) replace those logical constraints with inequalities, using the fact that if a and b are boolean variables, then the statement "a implies b" can be written as b>=a (if a=1, then b=1).

How to compare two logical expressions for equality?

I have two logical expression (just examples):
!(n >= x || n < -y)
and
n < x && n >= -y
Are there any tools out there to compare expressions like these to see if they are logically equal for all values? Or just to help me find the most compact/simple form?
The "most compact/simple form" answer would depend on your notion of compactness/simplicity. For instance, you can perform a number of simplification steps such as conversion to the conjunctive normal form (elimination of ||) followed by negation elimination (replacing !(n > y) by (n <= y)).
Equivalence of formulas F and G can be checked by taking the conjunction of F and the negation of G and checking for satisfiability of F && !G with, e.g., a constraints solver. You should be careful with your domain though since the result depends on your domain (integers, rationals, reals): 2 < n && n < 3 is not satisfiable for the integers, but it is satisfiable for the reals!

Turn while loop into math equation?

I have two simple while loops in my program that I feel ought to be math equations, but I'm struggling to convert them:
float a = someValue;
int b = someOtherValue;
int c = 0;
while (a <= -b / 2) {
c--;
a += b;
}
while (a >= b / 2) {
c++;
a -= b;
}
This code works as-is, but I feel it could be simplified into math equations. The idea here being that this code is taking an offset (someValue) and adjusting a coordinate (c) to minimize the distance from the center of a tile (of size someOtherValue). Any help would be appreciated.
It can be proved that the following is correct:
c = floor((a+b/2)/b)
a = a - c*b
Note that floor means round down, towards negative infinity: not towards 0. (E.g. floor(-3.1)=-4. The floor() library functions will do this; just be sure not to just cast to int, which will usually round towards 0 instead.)
Presumably b is strictly positive, because otherwise neither loop will never terminate: adding b will not make a larger and subtracting b will not make a smaller. With that assumption, we can prove that the above code works. (And paranoidgeek's code is also almost correct, except that it uses a cast to int instead of floor.)
Clever way of proving it:
The code adds or subtracts multiples of b from a until a is in [-b/2,b/2), which you can view as adding or subtracting integers from a/b until a/b is in [-1/2,1/2), i.e. until (a/b+1/2) (call it x) is in [0,1). As you are only changing it by integers, the value of x does not change mod 1, i.e. it goes to its remainder mod 1, which is x-floor(x). So the effective number of subtractions you make (which is c) is floor(x).
Tedious way of proving it:
At the end of the first loop, the value of c is the negative of the number of times the loop runs, i.e.:
0 if: a > -b/2 <=> a+b/2 > 0
-1 if: -b/2 ≥ a > -3b/2 <=> 0 ≥ a+b/2 > -b <=> 0 ≥ x > -1
-2 if: -3b/2 ≥ a > -5b/2 <=> -b ≥ a+b/2 > -2b <=> -1 ≥ x > -2 etc.,
where x = (a+b/2)/b, so c is: 0 if x>0 and "ceiling(x)-1" otherwise. If the first loop ran at all, then it was ≤ -b/2 just before the last time the loop was executed, so it is ≤ -b/2+b now, i.e. ≤ b/2. According as whether it is exactly b/2 or not (i.e., whether x when you started was exactly a non-positive integer or not), the second loop runs exactly 1 time or 0, and c is either ceiling(x) or ceiling(x)-1. So that solves it for the case when the first loop did run.
If the first loop didn't run, then the value of c at the end of the second loop is:
0 if: a < b/2 <=> a-b/2 < 0
1 if: b/2 ≤ a < 3b/2 <=> 0 ≤ a-b/2 < b <=> 0 ≤ y < 1
2 if: 3b/2 ≤ a < 5b/2 <=> b ≤ a-b/2 < 2b <=> 1 ≤ y < 2, etc.,
where y = (a-b/2)/b, so c is: 0 if y<0 and 1+floor(y) otherwise. [And a now is certainly < b/2 and ≥ -b/2.]
So you can write an expression for c as:
x = (a+b/2)/b
y = (a-b/2)/b
c = (x≤0)*(ceiling(x) - 1 + (x is integer))
+(y≥0)*(1 + floor(y))
Of course, next you notice that (ceiling(x)-1+(x is integer)) is same as floor(x+1)-1 which is floor(x), and that y is actually x-1, so (1+floor(y))=floor(x), and as for the conditionals:
when x≤0, it cannot be that (y≥0), so c is just the first term which is floor(x),
when 0 < x < 1, neither of the conditions holds, so c is 0,
when 1 ≤ x, then only 0≤y, so c is just the second term which is floor(x) again.
So c = floor(x) in all cases.
c = (int)((a - (b / 2)) / b + 1);
a -= c * b;
Test case at http://pastebin.com/m1034e639
I think you want something like this:
c = ((int) a + b / 2 * sign(a)) / b
That should match your loops except for certain cases where b is odd because the range from -b/2 to b/2 is smaller than b when b is odd.
Assuming b is positive, abs(c) = floor((abs(a) - b/2) / b). Then, apply sign of a to c.