Convert a scipy interp1d array to a float value in Python - python

in my current project I have currently a conversion issue:
In a first step I am interpolating two lists with scipy interp1d.
f_speed = scipy.interpolate.interp1d(t, v, 'cubic')
After that I want to get one specific point in this function. This value is now an array from scipy with only one value in it.
currentSpeed = f_speed(tpoint)
# result: array(15.1944)
As a last step I want to calculate other values with the value from the interpolated function, but I only get 0 as a value. There is no Error at all.
real_distance = currentSpeed * (1/15) # some calculations
# result: 0, all results with further calculations are zero
I need a conversion from scipy array to a regular float value to proceed my calculations. Is there any function to do this?
I tried several things like V = currentSpeed[0], or .tolist from numpy (not possible in scipy)...
Thanks for your help in advance!!

You did not specify which Python version you're using, but if you're using Python 2.7, then operator / stands for integer division. It means that 1/15 will produce 0. Multiplying something with this results will end up being 0, regardless of how you access array values.
To solve the problem, make sure at least one operand is a float number.
result1 = 1/15 # Produces 0
result2 = 1.0/15 # Produces 0.06666666666666667
If you apply this to your code, you should use
real_distance = currentSpeed * (1.0/15)

Are you using Python 2? If so the problem is the division.
Integer division will result in an integer so 1/15 will result in 0.
Try 1.0/15 instead. By using 1.0 you make it explicitly a float an then the result will be as expected.

Related

Ensure that calculations are done 64 bits (or at least warn of overflow)

I am using python and NumPy. I had the following basic quantity to compute:
(QL * (7**k))**2
Where
QL = 200003
k = 4
What puzzled me is that it returned a wrong (negative) number, which doesn't make sense. Then I realised after looking on the internet that the problem was because k was a 32-bit numpy integer.
A minimal working example can be the following:
QL = 200000
k = np.arange(10)[4]
print((QL * 7**k)**2)
This returns 406556672 instead of the correct answer 230592040000000000. The number is not negative here, but the same problem still occurs.
My question is:
How can I make sure that all the numbers used in my code are of the biggest possible integer size?
I don't want to explicitly specify it for each number that I create.
How can I at least force python to warn me when such things happen?
When you write QL = 200003; k = 4 in Python, the numbers are interpreted as ints. By default, if you were to convert these into numpy arrays or scalars, you would end up with whatever the default integer type is on your system.
Here is an example using one-element arrays:
QL = np.array([200003])
k = np.array([4])
On my system, I find that the dtype of both arrays is int32. You can change that by selecting your preferred dtype:
QL = np.array([200003], dtype=np.int64)
k = np.array([4], dtype=np.int64)
If you don't have access to the arrays at creation time, you can always convert them:
QL = QL.astype(np.int64)
k = k.astype(int64)
An option that is worth considering for integer math is skipping numpy altogether and using Python's infinite precision integers. If one of the numbers is a numpy scalar or one-element array, you can retrieve the corresponding Python object using the item method:
QL = QL.item()
k = k.item()
Numpy should raise at least a warning for overflow, but apparently this fails for some operations: https://github.com/numpy/numpy/issues/8987
TL;DR
In your case, k is a numpy scalar of type int32. You can do either one of the following:
For a numpy 64-bit result:
k = np.int64(k)
For an infinite-precision Python result:
k = k.item()
If you don't want to cast each k explicitly, you can create the range using the correct type:
k = np.arange(10, dtype=np.int64)[4]
There is no reliable way to set the default integer type for all new arrays without specifying it explicitly.

Python won't show me np.exp marketshare values

I'm trying to estimate marketshares with the following formula:
c = np.exp(-Mu*a)/(np.exp(-Mu*a)+np.exp(-Mu*b))
in which a and b are 9x9 matrices with cell values that can be larger than 1000. Because the numbers are so small, Python returns NaN values. In order to enhance precision of the estimation i have already tried np.float128 but all this does is raise the error that numpy doesn't have an attribute called float128. I have also tried longdouble, again without success. Are there other ways to make Python show the actual values of the cells instead of NaN?
You have:
c = np.exp(-Mu*a)/(np.exp(-Mu*a)+np.exp(-Mu*b))
Multipying the numerator and denominator by e^(Mu*a), you get:
c = 1/(1+np.exp(Mu*(a-b)))
This is just a reformulation of the same formula.
Now, if the exp term is still too small, and you do not need a more precise result, then your c is approximately very close to 1. And if you still need to control precision, you can take log on both sides and use the Taylor expansion of log(1+x).

Smallest Number in Python

PROBLEM STATEMENT: Write a Python script to determine the smallest positive double number in Python.
Your code should produce a variable called smallest_num which is the smallest double number in Python.
Your script should determine this value in a systematic manner. You may NOT simply call a built-in function that returns this value or access a built-in variable that contains this information. This includes np.finfo() and other built-in functions or variables.
The setup code gives the following variables:
Your code snippet should define the following variables:
Name Type Description
smallest_num floating point The smallest number possible in Python
Attempted Solution
import numpy as np
import math
def machineEpsilon(func=float):
machine_epsilon = func(1)
while func(1)+func(machine_epsilon) != func(1):
machine_epsilon_last = machine_epsilon
machine_epsilon = func(machine_epsilon) / func(2)
return machine_epsilon_last
sum_f = machineEpsilon(np.float64)
smallest_sum = float(sum_f)
print(isinstance(smallest_sum, float))
print(smallest_sum)
Output
True
2.220446049250313e-16
However, I am unable to get the correct answer. As the true smallest number is much smaller than the printed value. I know this number will be underflow to zero and I might want to do some comparison here. But i am a bit stuck. Any thoughts?
Probably the most reasonable thing to do would be to directly compute the next double-precision float after 0.0:
smallest_num = np.nextafter(0, 1)
This does not simply call a built-in function that returns the smallest positive double-precision float, or access a variable pre-set to that value. However, people get weird when they see function call syntax in problems like this, so it risks being marked incorrect anyway.
Taking advantage of how IEEE754 floating-point representation and rounding works, we can start with 1.0 and divide by 2 until the next division would underflow:
smallest_num = 1.0
while smallest_num / 2:
smallest_num /= 2

Convert int to double Python [duplicate]

This question already has answers here:
How can I force division to be floating point? Division keeps rounding down to 0?
(11 answers)
Closed 7 years ago.
I can't seem to find the answer to this on this site, though it seems like it would be common enough. I am trying to output a double for the ratio of number of lines in two files.
#Number of lines in each file
inputLines = sum(1 for line in open(current_file))
outputLines = sum(1 for line in open(output_file))
Then get the ratio:
ratio = inputLines/outputLines
But the ratio always seems to be an int and rounds even if I initialize it like:
ratio = 1.0
Thanks.
In python 2, the result of a division of two integers is always a integer. To force a float division, you need to use at least one float in the division:
ratio = float(inputLines)/outputLines
Be careful not to do ratio = float(inputLines/outputLines): although that results in a float, it's one obtained after doing the integer division, so the result will be "wrong" (as in "not what you expect")
In python 3, the integer division behavior was changed, and a division of two integers results in a float. You can also use this functionality in python 2.7, by putting from __future__ import division in the begging of your files.
The reason ratio = 1.0 does not work is that types (in python) are a property of values, not variables - in other words, variables don't have types.
a= 1.0 # "a" is a float
a= 1 # "a" is now a integer
Are you using Python 2.x?
Try using
>>> from __future__ import division
>>> ratio = 2/5
0.4
to get a float from a division.
Initializing with ratio = 1.0 doesn't work because with ratio = inputLines/outputLines you are re-assigning the variable to int, no matter what it was before.
Indeed, Python 2 returns an integer when you divide an integer. You can override this behaviour to work like in Python 3, where int / int = float by placing this at the top of your file:
from __future__ import division
Or better yet, just stop using Python 2 :)
You need to cast one of the terms to a floating point value. Either explicitly by using float (that is ratio = float(a)/b or ratio=a/float(b)) or implicitly by adding 0.0: ratio = (a+0.0)/b.
If using Python 2 you can from __future__ import division to make division not be the integral one but the float one.

Use of Inf on Matlab

I am currently translating a MATLAB program into Python. I successfully ported all the previous vector operations using numpy. However I am stuck in the following bit of code which is a cosine similarity measure.
% W and ind are different sized matrices
dist = full(W * (W(ind2(range),:)' - W(ind1(range),:)' + W(ind3(range),:)'));
for i=1:length(range)
dist(ind1(range(i)),i) = -Inf;
dist(ind2(range(i)),i) = -Inf;
dist(ind3(range(i)),i) = -Inf;
end
disp(dist)
[~, mx(range)] = max(dist);
I did not understand the following part.
dist(indx(range(i)),i) = -Inf;
What actuality is happening when you use
= -Inf;
on the right side?
In Matlab (see: Inf):
Inf returns the IEEE® arithmetic representation for positive infinity.
So Inf produces a value that is greater than all other numeric values. -Inf produces a value that is guaranteed to be less than any other numeric value. It's generally used when you want to iteratively find a maximum and need a first value to compare to that's always going to be less than your first comparison.
According to Wikipedia (see: IEEE 754 Inf):
Positive and negative infinity are represented thus:
sign = 0 for positive infinity, 1 for negative infinity.
biased exponent = all 1 bits.
fraction = all 0 bits.
Python has the same concept using '-inf' (see Note 6 here):
float also accepts the strings “nan” and “inf” with an optional prefix “+” or “-” for Not a Number (NaN) and positive or negative infinity.
>>> a=float('-inf')
>>> a
-inf
>>> b=-27983.444
>>> min(a,b)
-inf
It just assigns a minus infinity value to the left-hand side.
It may appear weird to assign that value, particularly because a distance cannot be negative. But it looks like it's used for effectively removing those entries from the max computation in the last line.
If Python doesn't have "infinity" (I don't know Python) and if dist is really a distance (hence nonnegative) , you could use any negative value instead of -inf to achieve the same effect, namely remove those entries from the max computation.
The -Inf is typically used to initialize a variable such that you later can use it to in a comparison in a loop.
For instance if I want to find the the maximum value in a function (and have forgotten the command max). Then I would have made something like:
function maxF = findMax(f,a,b)
maxF = -Inf;
x = a:0.001:b;
for i = 1:length(x)
if f(x) > maxF
maxF = f(x);
end
end
It is a method in matlab to make sure that any other value is larger than the current. So the comparison in Python would be -sys.maxint +1.
See for instance:
Maximum and Minimum values for ints

Categories

Resources