Numpy returning False even though both arrays are the same? - numpy

From my understanding of numpy, the np.equal([x, prod]) command compares the arrays element by element and returns True for each if they are equal. But every time I execute the command, it returns False for the first comparison. On the other hand, if I copy-paste the two arrays into the command, it returns True for both, as you can see in the screenshot. So, why is there a difference between the two?

You cannot compare floating-point numbers, as they are only an approximation. When you compare them by hardcoded values, they will be equal as they are approximated in the exact same way. But once you apply some mathematical operation on them, it's no longer possible to check if two floating-points are equal.
For example, this
a = 0
for i in range(10):
a += 1/10
print(a)
print(a == 1)
will give you 0.9999999999 and False, even though (1/10) * 10 = 1.
To compare floating-point values, you need to compare the two values against a small delta value. In other words, check if they're just a really small value apart. For example
a = 0
for i in range(10):
a += 1/10
delta = 0.00000001
print(a)
print(abs(a - 1) < delta)
will give you True.
For numpy, you can use numpy.isclose to get a mask or numpy.allclose if you only want a True or False value.

Related

Strange roots `using numpy.roots`

Is there something wrong in the evaluation of the polinomial (1-alpha*z)**9 using numpy? For
alpha=3/sqrt(2) my list of coefficients is given in the array
psi_t0 = [1.0, -19.0919, 162.0, -801.859, 2551.5, -5412.55, 7654.5, -6958.99, 3690.56, -869.874]
According to numpy documentation, I have to invert this array in order to compute the zeros, i.e.
psi_t0 = psi_t0[::-1]
Thus giving
a = np.roots(psi_t0)
[0.62765842+0.06979364j 0.62765842-0.06979364j 0.52672941+0.14448097j 0.52672941-0.14448097j 0.42775926+0.13031547j 0.42775926-0.13031547j 0.36690056+0.07504044j 0.36690056-0.07504044j 0.34454214+0.j]
which is completely crap since the roots must be all equal to sqrt(2)/3.
As you take the 9th power you'll find that you create a very "wide" zero, indeed, if you step eps away from the true zero and evaluate you'll get something of O(eps^9). In view of that numerical inaccuracies are all but expected.
>>> np.set_printoptions(4)
>>> print(C)
[-8.6987e+02 3.6906e+03 -6.9590e+03 7.6545e+03 -5.4125e+03 2.5515e+03
-8.0186e+02 1.6200e+02 -1.9092e+01 1.0000e+00]
>>> np.roots(C)
array([0.4881+0.0062j, 0.4881-0.0062j, 0.4801+0.0154j, 0.4801-0.0154j,
0.4681+0.0172j, 0.4681-0.0172j, 0.458 +0.011j , 0.458 -0.011j ,
0.4541+0.j ])
>>> np.polyval(C,_)
array([1.4622e-13+6.6475e-15j, 1.4622e-13-6.6475e-15j,
1.2612e-13+1.5363e-14j, 1.2612e-13-1.5363e-14j,
1.0270e-13+1.3600e-14j, 1.0270e-13-1.3600e-14j,
1.1346e-13+9.7179e-15j, 1.1346e-13-9.7179e-15j,
1.0936e-13+0.0000e+00j])
As you can see the roots numpy returns are "good" in that the polynomial evaluates to something pretty close to zero at these points.

Given no modulus or if even/odd function, how would one check for an odd or even number?

I have recently sat a computing exam in university in which we were never taught beforehand about the modulus function or any other check for odd/even function and we have no access to external documentation except our previous lecture notes. Is it possible to do this without these and how?
Bitwise AND (&)
Extract the last bit of the number using the bitwise AND operator. If the last bit is 1, then it's odd, else it's even. This is the simplest and most efficient way of testing it. Examples in some languages:
C / C++ / C#
bool is_even(int value) {
return (value & 1) == 0;
}
Java
public static boolean is_even(int value) {
return (value & 1) == 0;
}
Python
def is_even(value):
return (value & 1) == 0
I assume this is only for integer numbers as the concept of odd/even eludes me for floating point values.
For these integer numbers, the check of the Least Significant Bit (LSB) as proposed by Rotem is the most straightforward method, but there are many other ways to accomplish that.
For example, you could use the integer division operation as a test. This is one of the most basic operation which is implemented in virtually every platform. The result of an integer division is always another integer. For example:
>> x = int64( 13 ) ;
>> x / 2
ans =
7
Here I cast the value 13 as a int64 to make sure MATLAB treats the number as an integer instead of double data type.
Also here the result is actually rounded towards infinity to the next integral value. This is MATLAB specific implementation, other platform might round down but it does not matter for us as the only behavior we look for is the rounding, whichever way it goes. The rounding allow us to define the following behavior:
If a number is even: Dividing it by 2 will produce an exact result, such that if we multiply this result by 2, we obtain the original number.
If a number is odd: Dividing it by 2 will result in a rounded result, such that multiplying it by 2 will yield a different number than the original input.
Now you have the logic worked out, the code is pretty straightforward:
%% sample input
x = int64(42) ;
y = int64(43) ;
%% define the checking function
% uses only multiplication and division operator, no high level function
is_even = #(x) int64(x) == (int64(x)/2)*2 ;
And obvisouly, this will yield:
>> is_even(x)
ans =
1
>> is_even(y)
ans =
0
I found out from a fellow student how to solve this simplistically with maths instead of functions.
Using (-1)^n :
If n is odd then the outcome is -1
If n is even then the outcome is 1
This is some pretty out-of-the-box thinking, but it would be the only way to solve this without previous knowledge of complex functions including mod.

How do I get the minimum positive value over a set of integer expressions?

I have a model with the following condition:
z[i] = min{t*x[i][t] | x[i][t] = 1},
x[i][t] - boolean,
z[i] - integer
Which means I am trying to find a minimum positive value over a set of integer expressions. The "min" condition can be easily converted into a set of linear conditions if only we weren't looking for a positive value but a boolean (0 or 1) one.
Here the situation is a bit more complicated. Let's say that
t*x[i][t]
can have the following values:
0,3,4,5
I am looking for a way to get the value 3 (minimum positive one) and assign it to another variable (z[i])
Is there a way to convert the condition into a set of linear ones so that my model is not a non-linear programming model?

"Updating" the RNG in Python

I have to iterate an operation over several sets of partially randomized copies of an initial array of 0 and 1.
I would like the copies to be different, of course, but also the sets.
For now I use this code (I omitted certain parts that should not interfere in the problem):
def randomizer(b) :
"""randomizes a fraction 'rate' (global variable) of b"""
c = np.copy(b)
num_elem = len(c)
idx = np.random.choice(range(num_elem), int(num_elem*rate), replace=False)
c[idx] = f(c[idx])
return c
def randomizePatterns(pattern, randomizer) :
"""Return nbTrials partially randomized copies of the given input pattern"""
outputs = np.tile(pattern,(nbTrials,1))
for line in xrange(nbTrials) :
outputs[line] = randomizer(outputs[line,:])
return outputs
def test(pattern,randomizer) :
randomPatterns = randomizePatterns(pattern, randomizer)
"""test the dynamics of a neural network with a fixed but initially random
connection scheme, and returns a boolean corresponding to if
the original pattern that was randomized is retrieved from at least
90% of the randomized patterns"""
return boolean
def metaTest(pattern):
successNumber = 0
for plop in xrange(10):
if test(pattern, randomizer) :
successNumber += 1
return successNumber
The other input to test is a random matrix of floats in [0,4] that I visualize and that has the expected behavior.
When I run metaTest, I always get either 0 or 10, never an intermediate value.
Given the nature of test, I expect a result about 5. I get each result for approximately half of the inputs.
To be more precise, printing the random patterns after each incrementation of plop, I get the same thing ten times, and I would like that to change.

How to assign values randomly based on a percentage in SAS?

This question pertains to SAS. I need to generate a variable randomly, let's call it "species," for which 60% of the cases are 1's and the remaining 40% of cases are 0's. There are 15,000 cases of x_1 (where x_1 is a random, uniformly distributed variable) which need assignment of either 1 or 0. It's got to be generated with an if-then-do statement, right? So far, I have:
data species_list;
set work.species_list;
if x_1 <= 0.6 then do;
Species = 1;
end;
else if x_1 > 0.6 then do;
Species = 0;
end;
run;
This part is easy enough. But, I need the 1's and 0's to be randomly assigned to the 15,000 cases, not based on some inequality.
If x_1 is a random, uniformly distributed variable, then this inequality does distribute them 'randomly' (as much as can be done with a computer, anyway).
From what I recall, your inequality will work, more or less. It's not perfect; most likely your random number has a lower bound of 0 and an upper bound of 0.999999, so it's not quite going to give perfect 60/40 split, though with 15000 you probably will see a reasonably close match.
A somewhat better way is to use proc surveyselect. This doesn't require your x_1 variable.
proc surveyselect data=species_list out=species_out samprate=0.6 outall seed=12345;
run;
That would sample 60% and give them a 1, and the remaining 40% would be a 0. Easy as pie.
If you want to produce a random variable in SAS you can use the rand function.
You could use:
Species = ifn(rand("uniform") <= 0.6, 1, 0);
or:
x_1 = rand("uniform");
if x_1 <= 0.6 then Species = 1;
else Species = 0;
Depending on which one is more understandable to you.
rand(dist [, parameters]) produces a random number generated from one of several distributions.
ifn(condition, trueValue, falseValue) will return its second or third (numeric) argument depending on whether the condition evaluates to true or false.
It is not necessary to wrap your conditional statements in do; end; if you only want to run one statement.
If you want reproducable results you can provide a seed to the PRNG with call streaminit.