Hi i have just started using python and coding in general. This is the last question of my assignment and i honestly have no clue as to how to even start this question.
I need to write a program to do basic vector calculations in 3 dimensions:
addition, dot product and normalization.
I have no clue what to do after this step or if this step is even right please help.
The expected result is:
Enter vector A:
1 3 2
Enter vector B:
2 3 0
A+B = [3, 6, 2]
A.B = 11
|A| = 3.74
|B| = 3.61
Using numpy:
import numpy as np
A = np.array([1,3,2])
B = np.array([2,3,0])
# sum
print(A+B) # -> array([3, 6, 2])
# dot product
print(np.dot(A)) # -> 11
#normalization
print(np.linalg.norm(A)) # -> 3.741...
print(np.linalg.norm(B)) # -> 3.605...
Without numpy:
A = [1,3,2]
B = [2,3,0]
# sum
print([i+j for i,j in zip(A,B)])
# dot product
print(sum(i*j for i, j in zip(A,B)))
#normalization
print(sum(i**2 for i in A)**(0.5))
print(sum(i**2 for i in B)**(0.5))
Related
I need some help regarding the coding using python.
Here is the problem.
Let say I have an array (size = (50,50)) containing float numbers. I would like to find the minimum value for every cluster of cells (size = (10,10)). So in total, I will have 25 values.
This is what I did so far, maybe there is another way to do it so that the program could run faster since I need it to handle a quite big array (let say 1 mil x 1 mill of cells).
import numpy as np
import random
def mini_cluster(z,y,x):
a = []
for i in range(y,y+10):
for j in range(x,x+10):
a.append(z[i,j])
return min(a)
z = np.zeros(shape=(50,50))
for i in range (len(z)):
for j in range(len(z)):
z[i,j] = random.uniform(10,12.5)
mini = []
for i in range(0,len(z),10):
for j in range(0,len(z),10):
mini.append(mini_cluster(z,i,j))
I am not sure of its speed but using numpy slicing should simplify your work.
you can avoid all those for loops.
here is some sample code
import numpy as np
arr=[[1,2,3,8],[4,5,6,7],[8,9,10,11],[0,3,5,9]]
arr_np = np.array(arr)
print(arr_np)
cluster= arr_np[:3,:3]
print('\n')
print(cluster)
print('\n')
print(np.amin(cluster))
[[ 1 2 3 8]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 3 5 9]]
[[ 1 2 3]
[ 4 5 6]
[ 8 9 10]]
1
you can also check this tutorial
The program I have here is simulating the velocity of a falling object.
The velocity is calculated by subtracting the y position from time_1 and time_2.
The problem that I have is that the dimensions of array v and array t don't match. Instead of shortening array t I would like to add 0 at the beginning of the v array. So that the graph will show v = 0 at t= 0. Yes, I know it is a small interval and that it does not really matter. But I want to know it for educational purpose.
I'm wondering if i can write the line v = (y[1:] - y[:-1])/0.1 in a from where i keep the dimension.
The ideal thing that would happen is that the array y will be substracted with an array y[:-1] and that this subtraction will happen at the end of the y array so the result will be an array of dimension 101 with a 0 as start value.
I would like to know your thoughts about this.
import matplotlib.pyplot as plt
t = linspace(0,10,101)
g = 9.80665
y = 0.5*g*t*t
v = (y[1:] - y[:-1])/0.1
plt.plot(t,v)
plt.show()
is there a function where i can add a certain value to the beginning of an array? np.append will add it to the end.
Maybe you could just pre-define the length of the result at the beginning and then fill up the values:
import numpy as np
dt = .1
g = 9.80665
t_end = 10
t = np.arange(0,t_end+dt,dt)
y = 0.5*g*t*t
v = np.zeros(t.shape[0])
v[1:] = (y[1:] - y[:-1])/dt
if you simply looking for the append at index function it would be this one:
np.insert([1,2,3,4,5,6], 2, 100)
>> array([ 1, 2, 100, 3, 4, 5, 6])
another possible solution to this would be to use np.append but inverse your order :
import numpy as np
v = np.random.rand(10)
value = 42 # value to append at the beginning of v
value_arr = np.array([value]) # dimensions should be adjust for multidimensional array
v = np.append(arr = value_arr, values = v, axis=0)
and the possible variants following the same idea, using np.concatenate or np.hstack ...
regarding your second question in comments, one solution may be :
t = np.arange(6)
condlist = [t <= 2, t >= 4]
choicelist = [1, 1]
t = np.select(condlist, choicelist, default=t)
In Python 3, I want to return the units place of an integer value, then tens, then hundreds and so on. Suppose I have an integer 456, first I want to return 6, then 5 then 4. Is there any way? I tried floor division and for loop but didn't work.
If you look at the list of basic operators from the documentation, for example here,
Operator Description Example
% Modulus Divides left hand operand by right hand operand and returns remainder b % a = 1
// Floor Division - The division of operands where the result is the quotient in which the digits after the decimal point are removed. But if one of the operands is negative, the result is floored, i.e., rounded away from zero (towards negative infinity): 9//2 = 4 and 9.0//2.0 = 4.0, -11//3 = -4, -11.0//3 = -4.0
With that knowledge, you can get what you want as follows:
In [1]: a = 456
In [2]: a % 10
Out[2]: 6
In [3]: (a % 100) // 10
Out[3]: 5
In [4]: a // 100
Out[4]: 4
Write a generator if you want to retrieve digits in different places of your code based on requirement as follows.
If you are not much familiar with Python's generator, have a quick look at https://www.programiz.com/python-programming/generator.
» Here get_digits() is a generator.
def get_digits(n):
while str(n):
yield n % 10
n = n // 10
if not n:
break
digit = get_digits(1729)
print(next(digit)) # 9
print(next(digit)) # 2
print(next(digit)) # 7
print(next(digit)) # 1
» If you wish to iterate over digits, you can also do so as follows.
for digit in get_digits(74831965):
print(digit)
# 5
# 6
# 9
# 1
# 3
# 8
# 4
# 7
» Quick overview about its usage (On Python3's Interactive terminal).
>>> def letter(name):
... for ch in name:
... yield ch
...
>>>
>>> char = letter("RISHIKESH")
>>>
>>> next(char)
'R'
>>>
>>> "Second letter is my name is: " + next(char)
'Second letter is my name is: I'
>>>
>>> "3rd one: " + next(char)
'3rd one: S'
>>>
>>> next(char)
'H'
>>>
I would like to to use theano.scan within pymc3. I run into problems when I add more than two variables as sequences. Here is a simple example:
import numpy as np
import pymc3 as pm
import theano
import theano.tensor as T
a = np.ones(5)
b = np.ones(5)
basic_model = pm.Model()
with basic_model:
a_plus_b, _ = theano.scan(fn=lambda a, b: a + b, sequences=[a, b])
results in the following error:
Traceback (most recent call last):
File "StackOverflowExample.py", line 23, in <module>
sequences=[a, b])
File "\Anaconda3\lib\site-packages\theano\scan_module\scan.py", line 586, in scan
scan_seqs = [seq[:actual_n_steps] for seq in scan_seqs]
File "\Anaconda3\lib\site-packages\theano\scan_module\scan.py", line 586, in <listcomp>
scan_seqs = [seq[:actual_n_steps] for seq in scan_seqs]
TypeError: slice indices must be integers or None or have an __index__ method
However, when I run the same theano.scan outside a pymc model block, everything works fine:
a = T.vector('a')
b = T.vector('b')
a_plus_b, update = theano.scan(fn=lambda a, b: a + b, sequences=[a, b])
a_plus_b_function = theano.function(inputs=[a, b], outputs=a_plus_b, updates=update)
a = np.ones(5)
b = np.ones(5)
print(a_plus_b_function(a, b))
prints [2. 2. 2. 2. 2.], like it should.
In addition, the problem seems to be specific to adding more than one sequences. Everything works just fine when there is one variable in sequences and one in non-sequences. The following code works:
a = np.ones(5)
c = 2
basic_model = pm.Model()
with basic_model:
a_plus_c, _ = theano.scan(fn=lambda a, c: a + c, sequences=[a], non_sequences=[c])
a_plus_c_print = T.printing.Print('a_plus_c')(a_plus_c)
prints a_plus_c __str__ = [ 3. 3. 3. 3. 3.], as expected.
Note: I can't just use a + b instead of theano.scan because my actual function is more complex. I actually want to have something like this:
rewards = np.array([1, 1, 1, 1]) # reward (1) or no reward (0)
choices = np.array([1, 0, 1, 0]) # action left (1) or right (0)
Q_old = 0 # initial Q-value
alpha = 0.1 # learning rate
def update_Q(reward, choice, Q_old, alpha):
return Q_old + choice * alpha * (reward - Q_old)
Q_left, _ = theano.scan(fn=update_Q,
sequences=[rewards, choices],
outputs_info=[Q_old],
non_sequences=[alpha])
Turns out it was a simple mistake! Everything is working as soon as I define a and b as tensor variables. Adding those two lines did the job:
a = T.as_tensor_variable(np.ones(5))
b = T.as_tensor_variable(np.ones(5))
Is there an easy way to modify this code which converts from base 2 into base 10 to work for converting base 16 into base 10? My objective is to build a dedicated function for conversion and not use any built-in Python features for the calculation. Thanks
BinaryVal = int(input('Enter:')
DecVal = 0
for n in range(len(str(BinaryVal))):
Power = len(str(BinX))-(n+1)
DecVal += int(str(BinaryVal)[n])*(2**Power)
print(DecVal)
Yikes.
int already can convert from any base to base 10 - just supply it as the second argument.
int('101010',2)
Out[64]: 42
int('2A',16)
Out[66]: 42
To convert hexadecimal string to int:
>>> hexstr = '101010'
>>> int(hexstr, 16)
1052688
The same -- without int constructor:
>>> import binascii
>>> int.from_bytes(binascii.unhexlify(hexstr), 'big')
1052688
The same -- similar to #SzieberthAdam's answer:
>>> hex2dec = {d: i for i, d in enumerate('0123456789abcdef')}
>>> sum(hex2dec[h] * 16**pos for pos, h in enumerate(reversed(hexstr.lower())))
1052688
or:
>>> from functools import reduce
>>> reduce(lambda n, h: n*16 + hex2dec[h], hexstr.lower(), 0)
1052688
that is equivalent to:
def hex2int(hexstr):
n = 0
for h in hexstr.lower():
n = n*16 + hex2dec[h]
return n
Example:
>>> hex2int('101010')
1052688
As an alternative, one could convert all digits to int first:
>>> reduce(lambda n, d: n*16 + d, map(hex2dec.get, hexstr.lower()))
1052688
It raises TypeError for empty strings.
Well, here you go then:
>>> binary_num = '101010'
>>> sum(int(b)*2**i for i, b in enumerate(reversed(binary_num)))
42