merge sift descriptor matrix, numpyarray - python

I have sift descriptor matrix like this one:
a=[[ 0. 0. 0. ..., 0.01570028 0.11186453
0.03728818]
[ 0.19031648 0.18246838 0.0156962 ..., 0.06474684 0. 0. ]
[ 0. 0. 0.00392734 ..., 0.06480112 0.17083933
0.04909176]
...,
[ 0.09828723 0.0176917 0.00196574 ..., 0.16905404 0. 0. ]
[ 0.23960059 0.18657423 0.00589182 ..., 0.00392788 0. 0.01963939]
[ 0.00392924 0.09430183 0.15913433 ..., 0.00392924 0.01768159
0.00589386]]
[[ 0. 0. 0. ..., 0.01570028 0.11186453
0.03728818]
[ 0.19031648 0.18246838 0.0156962 ..., 0.06474684 0. 0. ]
[ 0. 0. 0.00392734 ..., 0.06480112 0.17083933
0.04909176]
...,
[ 0.09828723 0.0176917 0.00196574 ..., 0.16905404 0. 0. ]
[ 0.23960059 0.18657423 0.00589182 ..., 0.00392788 0. 0.01963939]
[ 0.00392924 0.09430183 0.15913433 ..., 0.00392924 0.01768159
0.00589386]]
and i want to merge a lot of them in the fastest way...how to make it ? Do a list of all of the array's and then with .dstack ? Thanks
edit: ok .dstack doesn't work because the matrix has different dimensions...
for e.g a=[[128 values]...[128 values]], len(a)=300 and b=[[128 values]...[128 values]] len(b)=1000 result should be c=[[128 values]...[128 values]] len(c)=1300

Numpy convention for 2D arrays: first number is number of rows, second number is number of columns.
>>> import numpy as np
>>> a=np.zeros((2,5))
>>> a
array([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.]])
>>> a.shape
(2, 5)
Use vstack to stack row wise.
>>> a=np.zeros((300,128))
>>> b=np.zeros((1000,128))
>>> a.shape
(300, 128)
>>> b.shape
(1000, 128)
>>> c=np.vstack((a,b))
>>> c.shape
(1300, 128)
>>> len(c)
1300
Dstack is really a depth stack:
>>> np.dstack((a,a)).shape
(300, 128, 2)
If you have a list of arrays:
a=[array1,array2,...,arrayn]
c=np.vstack(a)

Related

Inserting complex functions in a python code

I have been trying to insert $e^ix$ as matrix element.
The main aim is to find the eigenvalue of a matrix which has many complex functions as elements. Can anyone help me how to insert it? My failed attempt is below:
for i in range(0,size):
H[i,i]=-2*(cmath.exp((i+1)*aj))
H[i,i+1]=1.0
H[i,i-1]=1.0
'a' is defined earlier in the program. The error flagged shows that aj is not defined. Using cmath I thought a complex number can be expontiated as (x+yj). Unfortunately, I couldn't figure out the right way to use it. Any help would be appreciated
Define a small float array:
In [214]: H = np.eye(3)
In [215]: H
Out[215]:
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
Create a complex number:
In [216]: 1+3j
Out[216]: (1+3j)
In [217]: np.exp(1+3j)
Out[217]: (-2.6910786138197937+0.383603953541131j)
Trying to assign it to H:
In [218]: H[1,1]=np.exp(1+3j)
<ipython-input-218-6c0b228d2833>:1: ComplexWarning: Casting complex values to real discards the imaginary part
H[1,1]=np.exp(1+3j)
In [219]: H
Out[219]:
array([[ 1. , 0. , 0. ],
[ 0. , -2.69107861, 0. ],
[ 0. , 0. , 1. ]])
Now make an complex dtype array:
In [221]: H = np.eye(3).astype( complex)
In [222]: H[1,1]=np.exp(1+3j)
In [223]: H
Out[223]:
array([[ 1. +0.j , 0. +0.j ,
0. +0.j ],
[ 0. +0.j , -2.69107861+0.38360395j,
0. +0.j ],
[ 0. +0.j , 0. +0.j ,
1. +0.j ]])
edit
For an array of values:
In [225]: a = np.array([1,2,3])
In [226]: np.exp(a+1j*a)
Out[226]:
array([ 1.46869394+2.28735529j, -3.07493232+6.7188497j ,
-19.88453084+2.83447113j])
In [228]: H[:,0]=np.exp(a+1j*a)
In [229]: H
Out[229]:
array([[ 1.46869394+2.28735529j, 0. +0.j ,
0. +0.j ],
[ -3.07493232+6.7188497j , -2.69107861+0.38360395j,
0. +0.j ],
[-19.88453084+2.83447113j, 0. +0.j ,
1. +0.j ]])

how to put Multiple Matrices Together into a Single Matrix?

I need to put multiple matrices together into a single matrix, like so:
I have the values for the matrix, but I can't get it to appear like how it does in the image- instead, my values end up stacked on top of each other in an array. How can I go about getting my matrices to look like the image above?
My code:
import numpy as np
w_estimate = [0.656540, 7.192304, 2.749036]
F = [np.identity(3) * -w_estimate[1:4], -np.identity(3)], [np.identity(3)*0, np.identity(3)*0]
It's supposed to look like:
F = [[np.identity(3) * -w_estimate[1:4], -np.identity(3)]
[np.identity(3) * 0, np.identity(3) * 0]]
but instead it looks like:
[[np.identity(3) * -w_estimate[1:4]],
[-np.identity(3)],
[np.identity(3) * 0],
[np.identity(3) * 0]]
Help is very much appreciated.
The first correction to your code pertains to -w_estimate[1:4].
Since w_estimate is a plain pythonic list, you can not apply
minus operator to it.
You can however apply minus operator to a Numpy array.
Another correction is to avoid -0 in the result.
To get an array with diagonal elements filled from some other array,
and all other zeroes, you can use np.diagonal_fill, which fills
in-place diagonal elements of some (earlier) created array
(using np.zeros).
So to construct 2 "upper" blocks of your result, you can write:
a1 = np.zeros((3,3))
a2 = a1.copy()
np.fill_diagonal(a1, -np.array(w_estimate)[1:4])
np.fill_diagonal(a2, -1)
Note that -np.array(w_estimate)[1:4] returns last 2 elements of
w_estimate them, i.e. [7.192304, 2.749036]. Since the target array
is "3 by 3", the source sequence is repeated (in this case, for the
last diagonal element only).
If your intention is different, change -np.array(w_estimate)[1:4]
accordingly.
And to construct the whole intended array, run:
F = np.vstack((np.hstack((a1, a2)), np.zeros((3,6))))
The result is:
array([[-7.192304, 0. , 0. , -1. , 0. , 0. ],
[ 0. , -2.749036, 0. , 0. , -1. , 0. ],
[ 0. , 0. , -7.192304, 0. , 0. , -1. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. , 0. ]])
You shoud definitely take a look at numpy.block method.
>>> A = np.eye(2) * 2
>>> B = np.eye(3) * 3
>>> np.block([
... [A, np.zeros((2, 3))],
... [np.ones((3, 2)), B ]
... ])
array([[2., 0., 0., 0., 0.],
[0., 2., 0., 0., 0.],
[1., 1., 3., 0., 0.],
[1., 1., 0., 3., 0.],
[1., 1., 0., 0., 3.]])

specific kind of slicing over tensor object in tensorflow

Summary of the question, Is this kind of slicing and then assignment supported in tensorflow?
out[tf_a2[y],x[:,None]] = tf_a1[tf_a2[y],x[:,None]]
final = out[:-1]
Lets give the example, I have a tensor like this:
tf_a1 = tf.Variable([ [9.968594, 8.655439, 0., 0. ],
[0., 8.3356, 0., 8.8974 ],
[0., 0., 6.103182, 7.330564 ],
[6.609862, 0., 3.0614321, 0. ],
[9.497023, 0., 3.8914037, 0. ],
[0., 8.457685, 8.602337, 0. ],
[0., 0., 5.826657, 8.283971 ],
[0., 0., 0., 0. ]])
and I have this one:
tf_a2 = tf.constant([[1, 2, 5],
[1, 4, 6],
[0, 7, 7],
[2, 3, 6],
[2, 4, 7]])
Now I want to keep the elements in tf_a1 in which the combination of n (here n is 2) of them (index of them) is in the value of tf_a2. What does it mean?
For example, in tf_a1, in the first column, indexes which has value are: (0,3,4). Is there any row in tf_a2 which contains any combination of these two indexes: (0,3), (0,4) or (3,4). Actually, there is no such row. So all the elements in that column became zero.
Indexes for the second column in tf_a1 is (0,1) (0,5) (1,5). As you see the record (1,5) is available in the tf_a2 in the first row. That's why we keep those in the tf_a1.
This is the correct numpy code:
y,x = np.where(np.count_nonzero(a1p[a2], axis=1) >= n)
out = np.zeros_like(tf_a1)
out[tf_a2[y],x[:,None]] = tf_a1[tf_a2[y],x[:,None]]
final = out[:-1]
This is the expected output of this numpy code (but I need this in tensorflow):
[[0. 0. 0. 0. ]
[0. 8.3356 0. 8.8974 ]
[0. 0. 6.103182 7.330564 ]
[0. 0. 3.0614321 0. ]
[0. 0. 3.8914037 0. ]
[0. 8.457685 8.602337 0. ]
[0. 0. 5.826657 8.283971 ]]
The tensorflow code should be something like this:
y, x = tf.where(tf.count_nonzero(tf.gather(tf_a1, tf_a2, axis=0), axis=1) >= n)
out = tf.zeros_like(tf_a1)
out[tf_a2[y],x[:,None]] = tf_a1[tf_a2[y],x[:,None]]
final = out[:-1]
This part of the code tf.gather(tf_a1, tf_a2, axis=0), axis=1) is doing the numpy like slicing tf_a1[tf_a2]
Update 1
The only line which does not work its:
out[tf_a2[y],x[:,None]] = tf_a1[tf_a2[y],x[:,None]]
final = out[:-1]
Any idea how can I accomplish this in tensorflow, is this kind of slicing is supported in tensor object at all?
Any help is appreciated:)

How to extract the BSpline basis from scipy.interpolate.BSpline

In this question I asked the community about how scipy.interpolate.splev calculates a spline basis.. My goal was to compute a spline faster then splev by pre-calculating a bspline basis and generate a curve by doing a basis to control point dot product.
Since then a new scipy.interpolate.BSpline interpolator was added to scipy. It comes with a basis_element function, which I presume could be used to return the basis used to calculate a spline.
So for example using the code from here with the inputs below:
import numpy as np
# Control points
cv = np.array([[ 50., 25., 0.],
[ 59., 12., 0.],
[ 50., 10., 0.],
[ 57., 2., 0.],
[ 40., 4., 0.],
[ 40., 14., 0.]])
kv = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3] # knot vector
n = 10 # 10 samples (keeping it simple)
degree = 3 # Curve degree
I can compute the following bspline basis:
[[ 1. 0. 0. 0. 0. 0. ]
[ 0.2962963 0.56481481 0.13271605 0.00617284 0. 0. ]
[ 0.03703704 0.51851852 0.39506173 0.04938272 0. 0. ]
[ 0. 0.25 0.58333333 0.16666667 0. 0. ]
[ 0. 0.07407407 0.54938272 0.36728395 0.00925926 0. ]
[ 0. 0.00925926 0.36728395 0.54938272 0.07407407 0. ]
[ 0. 0. 0.16666667 0.58333333 0.25 0. ]
[ 0. 0. 0.04938272 0.39506173 0.51851852 0.03703704]
[ 0. 0. 0.00617284 0.13271605 0.56481481 0.2962963 ]
[ 0. 0. 0. 0. 0. 1. ]]
Using np.dot with basis and control points returns 10 samples on curve:
[[ 50. 25. 0. ]
[ 55.12654321 15.52469136 0. ]
[ 55.01234568 11.19753086 0. ]
[ 53.41666667 9.16666667 0. ]
[ 53.14506173 7.15432099 0. ]
[ 53.1882716 5.17901235 0. ]
[ 51.58333333 3.83333333 0. ]
[ 47.20987654 3.87654321 0. ]
[ 42.31790123 6.7345679 0. ]
[ 40. 14. 0. ]]
Question : is it possible to extract the basis as described above out of scipy.interpolate.BSpline?
Obviously I must be using it wrong, because when I try I get something like this:
from scipy.interpolate import BSpline
b = BSpline.basis_element(kv)
print b(np.linspace(kv[0],kv[-1],n)) # i'm not sure what these values represent
[ 0. 0.00256299 0.04495618 0.16555213 0.28691315 0.28691315
0.16555213 0.04495618 0.00256299 0. ]
BSpline.basis_element takes as its arguments the internal knots.
In your example, you padded the knots, and that did not do what you thought it would:
In [3]: t = [0, 0, 0, 0, 1, 2, 3, 3, 3, 3]
In [4]: b = BSpline.basis_element(t)
In [5]: b.k
Out[5]: 8
So it's an 8th order spline.
If you wanted a quadratic spline, you would do
In [7]: b1 = BSpline.basis_element([0, 1, 2, 3])
In [8]: b1.k
Out[8]: 2
In [9]: b1.t
Out[9]: array([-1., -1., 0., 1., 2., 3., 4., 4.])
Confused? The method is quite simple: https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bsplines.py#L243-L302
The callable returned by BSpline.basis_element is really a b-spline function. The result of calling it with an array argument is then equivalent to directly running the example code in the BSpline docstring in a loop for each element of your array, https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.BSpline.html
EDIT: if you're after a variant of Cox-de Boor algorithm of calculating all non-zero splines at a given point, then you can look at a _bspl.evaluate_all_bsplines function, https://github.com/scipy/scipy/blob/v0.19.1/scipy/interpolate/_bspl.pyx#L161
(which itself is just a wrapper over a C routine which does all the heavy lifting; note that it's hard to beat that latter one performance wise.)
However, it's not a public function, so it's not guaranteed to be available in future versions. If you have a good use for it, and a suggestion for a user-facing API, bring the discussion over to the scipy bug tracker.

Why can't I change numpy's array?

My array is from a image whick like below:
[[[ 66.17041352 32.64576397 20.96214396]
[ 66.17041352 32.64576397 20.96214396]
[ 65.96318838 32.36065031 16.13857633]
...,
[ 69.04849876 28.06324166 26.57747623]
[ 63.7269604 32.96378326 25.94336956]
[ 53.96807994 39.33219382 23.9025511 ]]
...,
[[ 18.55833403 34.4104455 -9.75497344]
[ 18.55833403 34.4104455 -9.75497344]
[ 21.45103128 32.77919479 -3.84284208]
...,
[ 44.64859327 41.89617915 14.25196745]
[ 43.40291913 43.25109885 17.43372679]
[ 43.30009306 47.94315449 15.59464532]]
[[ 18.64249436 31.63054472 -7.56023249]
[ 18.64249436 31.63054472 -7.56023249]
[ 23.23099091 32.284216 -3.86411699]
...,
[ 44.98536772 45.0246078 17.92556564]
[ 45.53417128 45.42120428 17.50264622]
[ 46.7226915 45.42428651 19.21054283]]]
I want to change the array to zero like this:
[[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
...,
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
...,
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]
I know how to make it happen, but I just wonder why my origin code doesn't work.The print shows that nothing changed.
for row in image_arr:
for col in row:
col = [0,0,0]
print image_arr
In your loop, you are just reassigning the name col to the list [0,0,0], over and over and over again. Not at all what you want! To change your 3d array to all zeros, you simply do this.:
arr[:, :, :,] = 0
Bing bang boom, you're done.
This is because col is a copy not a reference. This is true for all of python:
CODE Example:
simple = [1,2,3,4,5,6]
print simple
for elem in simple:
elem = 0
print simple
OUTPUT:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
Try this instead:
rows,cols,lens = arr.shape
for r in range(rows):
for c in range(cols):
arr[r][c] = [0,0,0]
You change the value col in the loop but it's not related to the original variable image_arr.
You can use enumerate to access the index and modify image_arr variable directly. As in the following example:
import numpy as np
image_arr = np.arange(30).reshape(3, 5, 2)
print(image_arr)
for i,row in enumerate(image_arr):
for j,col in enumerate(row):
image_arr[i][j]=0
print(image_arr)
You are changing col to a new list, but col is not a reference to a sublist of row. Instead, if you change the elements of col, then you will get the result you want:
for row in image_arr:
for col in row:
for i in range(len(col))
col[i] = 0
Is because col is a value not a reference , see Python objects confusion: a=b, modify b and a changes!
try instead :
a=0
b=0
for row in image_arr:
for col in row:
image_arr[a][b] = [0,0,0]
a=a+1
b=b+1
print image_arr
col is a 1d array, a view of arr. To change its values you need to use slicing notation. col=[0,0,0] reassigns the variable without mutating the iteration variable. Mutability is a key concept here (and applicable to lists and dictionaries as well).
In [254]: arr = np.ones((2,3,4))
In [255]: for row in arr:
...: for col in row:
...: col[:] = 0 # or = [1,2,3,5]
...:
In [256]: arr
Out[256]:
array([[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]]])
And since you want to change all the values, col[:]=0 works just as well as col[:]=[0,0,0,0] (in my shape).
But while we are at it, any of these also work
In [257]: for row in arr:
...: row[:,:] = 1
...:
In [258]: arr
Out[258]:
array([[[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
...]]])
In [259]: arr[:,:,:]=2 # one : per dimension
In [260]: arr[...] = 3 # ... shorthand for multiple :
But why reset arr? Why not make a new array with the same shape (and throw away the 'original')?
arr1 = np.zeros_like(arr)

Categories