How to raise every element of a vector to the power of every element of another vector?
Asked Answered
P

5

5

I would like to raise a vector by ascending powers form 0 to 5:

import numpy as np

a = np.array([1, 2, 3]) # list of 11 components
b = np.array([0, 1, 2, 3, 4]) # power
c = np.power(a,b)

desired results are:

c = [[1**0, 1**1, 1**2, 1**3, 1**4], [2**0, 2**1, ...], ...]

I keep getting this error:

ValueError: operands could not be broadcast together with shapes (3,) (5,)
Pegu answered 17/2, 2021 at 13:3 Comment(3)
c = [[x**y for y in b] for x in a]Mariehamn
Are your powers always increasing like that? Sounds like you want a Vandermone matrixBaras
Yes Im looking for a Vandermone matrixPegu
T
2

Here's a solution:

num_of_powers = 5
num_of_components = 11

a = []
for i in range(1,num_of_components + 1):
    a.append(np.repeat(i,num_of_powers))
b = list(range(num_of_powers))
c = np.power(a,b)

The output c would look like:

array([[    1,     1,     1,     1,     1],
       [    1,     2,     4,     8,    16],
       [    1,     3,     9,    27,    81],
       [    1,     4,    16,    64,   256],
       [    1,     5,    25,   125,   625],
       [    1,     6,    36,   216,  1296],
       [    1,     7,    49,   343,  2401],
       [    1,     8,    64,   512,  4096],
       [    1,     9,    81,   729,  6561],
       [    1,    10,   100,  1000, 10000],
       [    1,    11,   121,  1331, 14641]], dtype=int32)

Your solution shows a broadcast error because as per the documentation:

If x1.shape != x2.shape, they must be broadcastable to a common shape (which becomes the shape of the output).

Thicket answered 17/2, 2021 at 13:13 Comment(1)
@Pegu You can accept the answer (tick mark below the voting section) if it worked for you, to acknowledge it as the solution.Thicket
V
5

One solution will be to add a new dimension to your array a

c = a[:,None]**b

# Using broadcasting : 
# (3,1)**(4,) --> (3,4)
#
#     [[1],
# c =  [2], ** [0,1,2,3,4]
#      [3]]

For more information check the numpy broadcasting documentation

Vitrescent answered 17/2, 2021 at 13:49 Comment(2)
Definitely the nicest/fastest solution!Namhoi
Amazing! I'm not that fluent with numpy and was looking for a way to duplicate the elements, but that's not even necessary!Lisk
T
2

Here's a solution:

num_of_powers = 5
num_of_components = 11

a = []
for i in range(1,num_of_components + 1):
    a.append(np.repeat(i,num_of_powers))
b = list(range(num_of_powers))
c = np.power(a,b)

The output c would look like:

array([[    1,     1,     1,     1,     1],
       [    1,     2,     4,     8,    16],
       [    1,     3,     9,    27,    81],
       [    1,     4,    16,    64,   256],
       [    1,     5,    25,   125,   625],
       [    1,     6,    36,   216,  1296],
       [    1,     7,    49,   343,  2401],
       [    1,     8,    64,   512,  4096],
       [    1,     9,    81,   729,  6561],
       [    1,    10,   100,  1000, 10000],
       [    1,    11,   121,  1331, 14641]], dtype=int32)

Your solution shows a broadcast error because as per the documentation:

If x1.shape != x2.shape, they must be broadcastable to a common shape (which becomes the shape of the output).

Thicket answered 17/2, 2021 at 13:13 Comment(1)
@Pegu You can accept the answer (tick mark below the voting section) if it worked for you, to acknowledge it as the solution.Thicket
M
1
c = [[x**y for y in b] for x in a]
Mariehamn answered 17/2, 2021 at 13:15 Comment(2)
.tolist() unnecessaryNamhoi
The edits were strong on this one haha: [[x**y for y in b] for x in a] would be sufficient :)Namhoi
C
0
c = np.asarray(list(map(lambda x: np.power(a,x), b))).transpose()
Cabriole answered 17/2, 2021 at 13:29 Comment(0)
L
0

You need to first create a matrix where the rows are repetitions of each number. This can be done with np.tile:

mat = np.tile(a, (len(b), 1)).transpose()

And then raise that to the power of b elementwise:

np.power(mat, b)

All together:

import numpy as np

nums = np.array([1, 2, 3]) # list of 11 components
powers = np.array([0, 1, 2, 3, 4]) # power

print(np.power(np.tile(nums, (len(powers), 1)).transpose(), powers))

Which will give:

[[ 1  1  1  1  1]   # == [1**0, 1**1, 1**2, 1**3, 1**4]
 [ 1  2  4  8 16]   # == [2**0, 2**1, 2**2, 2**3, 2**4]
 [ 1  3  9 27 81]]  # == [3**0, 3**1, 3**2, 3**3, 3**4]
Lisk answered 17/2, 2021 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.