Efficiently creating a tensor of diagonal matrices












1














Assume a map from scalars to matrices of a fixed dimension.
How would one efficiently create a vectorized version of this map?



More specifically assume there is a constant vector lamb with n entries.
Given a scalar t I'm interested in the diagonal matrix given by



np.diag(np.exp(lamb*t))


using numpy.
This will be an n times n matrix.
Now given a matrix T of size m_1 times m_2 I would like to calculate the tensor D of shape (m_1,m_2,n,n) given for 0 <= i < m_1, 0 <= j < m_2 by



D[i,j,:,:] = np.diag(np.exp(lamb*T[i,j]))


How would one efficiently get this tensor?










share|improve this question
























  • Could you add minimal representative sample data? What does t look like?
    – Divakar
    Nov 19 '18 at 16:21












  • There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
    – user447457
    Nov 19 '18 at 16:30












  • Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
    – Divakar
    Nov 19 '18 at 17:02












  • Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
    – user447457
    Nov 19 '18 at 17:35












  • We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
    – hpaulj
    Nov 19 '18 at 17:36
















1














Assume a map from scalars to matrices of a fixed dimension.
How would one efficiently create a vectorized version of this map?



More specifically assume there is a constant vector lamb with n entries.
Given a scalar t I'm interested in the diagonal matrix given by



np.diag(np.exp(lamb*t))


using numpy.
This will be an n times n matrix.
Now given a matrix T of size m_1 times m_2 I would like to calculate the tensor D of shape (m_1,m_2,n,n) given for 0 <= i < m_1, 0 <= j < m_2 by



D[i,j,:,:] = np.diag(np.exp(lamb*T[i,j]))


How would one efficiently get this tensor?










share|improve this question
























  • Could you add minimal representative sample data? What does t look like?
    – Divakar
    Nov 19 '18 at 16:21












  • There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
    – user447457
    Nov 19 '18 at 16:30












  • Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
    – Divakar
    Nov 19 '18 at 17:02












  • Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
    – user447457
    Nov 19 '18 at 17:35












  • We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
    – hpaulj
    Nov 19 '18 at 17:36














1












1








1







Assume a map from scalars to matrices of a fixed dimension.
How would one efficiently create a vectorized version of this map?



More specifically assume there is a constant vector lamb with n entries.
Given a scalar t I'm interested in the diagonal matrix given by



np.diag(np.exp(lamb*t))


using numpy.
This will be an n times n matrix.
Now given a matrix T of size m_1 times m_2 I would like to calculate the tensor D of shape (m_1,m_2,n,n) given for 0 <= i < m_1, 0 <= j < m_2 by



D[i,j,:,:] = np.diag(np.exp(lamb*T[i,j]))


How would one efficiently get this tensor?










share|improve this question















Assume a map from scalars to matrices of a fixed dimension.
How would one efficiently create a vectorized version of this map?



More specifically assume there is a constant vector lamb with n entries.
Given a scalar t I'm interested in the diagonal matrix given by



np.diag(np.exp(lamb*t))


using numpy.
This will be an n times n matrix.
Now given a matrix T of size m_1 times m_2 I would like to calculate the tensor D of shape (m_1,m_2,n,n) given for 0 <= i < m_1, 0 <= j < m_2 by



D[i,j,:,:] = np.diag(np.exp(lamb*T[i,j]))


How would one efficiently get this tensor?







python-3.x numpy vectorization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 17:40

























asked Nov 19 '18 at 16:20









user447457

62




62












  • Could you add minimal representative sample data? What does t look like?
    – Divakar
    Nov 19 '18 at 16:21












  • There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
    – user447457
    Nov 19 '18 at 16:30












  • Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
    – Divakar
    Nov 19 '18 at 17:02












  • Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
    – user447457
    Nov 19 '18 at 17:35












  • We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
    – hpaulj
    Nov 19 '18 at 17:36


















  • Could you add minimal representative sample data? What does t look like?
    – Divakar
    Nov 19 '18 at 16:21












  • There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
    – user447457
    Nov 19 '18 at 16:30












  • Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
    – Divakar
    Nov 19 '18 at 17:02












  • Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
    – user447457
    Nov 19 '18 at 17:35












  • We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
    – hpaulj
    Nov 19 '18 at 17:36
















Could you add minimal representative sample data? What does t look like?
– Divakar
Nov 19 '18 at 16:21






Could you add minimal representative sample data? What does t look like?
– Divakar
Nov 19 '18 at 16:21














There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
– user447457
Nov 19 '18 at 16:30






There aren't any restrictions for the scalar t and for the matrix T as well. Or what to you mean by "minimal representative sample"?
– user447457
Nov 19 '18 at 16:30














Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
– Divakar
Nov 19 '18 at 17:02






Well first off lambda*t doesn't seem like a valid syntax with t as scalar. Secondly, with minimal representative sample, I meant some sample data for tand a valid code (loopy code even) that could work on it.
– Divakar
Nov 19 '18 at 17:02














Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
– user447457
Nov 19 '18 at 17:35






Oh, I'm sorry. The word lambda is reserved in python. Locally I called the variable lamb instead of lambda which is of type ndarray. Thus multiplication by a scalar is defined as entrywise multiplication with t. The answer given by Paul Panzer produces the output I'm interested in.
– user447457
Nov 19 '18 at 17:35














We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
– hpaulj
Nov 19 '18 at 17:36




We are lazy. We don't like to make up test cases. And we don't like the potential ambiguity of word problems. Good answers include working examples. Good questions should as well.
– hpaulj
Nov 19 '18 at 17:36












1 Answer
1






active

oldest

votes


















0














One comparatively straight-forward way would be using einsum.



Example:



>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

[[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

[[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


[[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

[[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

[[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])


You can speed this up a little bit using the out keyword to avoid one copy:



np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))





share|improve this answer























  • Thank you! Something like this was exactly what I was looking for.
    – user447457
    Nov 19 '18 at 20:06











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378772%2fefficiently-creating-a-tensor-of-diagonal-matrices%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














One comparatively straight-forward way would be using einsum.



Example:



>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

[[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

[[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


[[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

[[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

[[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])


You can speed this up a little bit using the out keyword to avoid one copy:



np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))





share|improve this answer























  • Thank you! Something like this was exactly what I was looking for.
    – user447457
    Nov 19 '18 at 20:06
















0














One comparatively straight-forward way would be using einsum.



Example:



>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

[[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

[[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


[[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

[[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

[[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])


You can speed this up a little bit using the out keyword to avoid one copy:



np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))





share|improve this answer























  • Thank you! Something like this was exactly what I was looking for.
    – user447457
    Nov 19 '18 at 20:06














0












0








0






One comparatively straight-forward way would be using einsum.



Example:



>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

[[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

[[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


[[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

[[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

[[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])


You can speed this up a little bit using the out keyword to avoid one copy:



np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))





share|improve this answer














One comparatively straight-forward way would be using einsum.



Example:



>>> T = np.array([[1,2,3], [4,6,7]])
>>> lam = np.array([1,2,5])
>>> D = np.zeros((*T.shape, n, n))
>>> np.einsum('ijkk->ijk', D)[...] = np.exp(np.multiply.outer(T, lam))
>>> D
array([[[[2.71828183e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 7.38905610e+00, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.48413159e+02]],

[[7.38905610e+00, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 5.45981500e+01, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 2.20264658e+04]],

[[2.00855369e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 4.03428793e+02, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 3.26901737e+06]]],


[[[5.45981500e+01, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 2.98095799e+03, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 4.85165195e+08]],

[[4.03428793e+02, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.62754791e+05, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.06864746e+13]],

[[1.09663316e+03, 0.00000000e+00, 0.00000000e+00],
[0.00000000e+00, 1.20260428e+06, 0.00000000e+00],
[0.00000000e+00, 0.00000000e+00, 1.58601345e+15]]]])


You can speed this up a little bit using the out keyword to avoid one copy:



np.exp(np.multiply.outer(T, lam), out=np.einsum('ijkk->ijk', D))






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 19 '18 at 18:04

























answered Nov 19 '18 at 17:27









Paul Panzer

29.9k21240




29.9k21240












  • Thank you! Something like this was exactly what I was looking for.
    – user447457
    Nov 19 '18 at 20:06


















  • Thank you! Something like this was exactly what I was looking for.
    – user447457
    Nov 19 '18 at 20:06
















Thank you! Something like this was exactly what I was looking for.
– user447457
Nov 19 '18 at 20:06




Thank you! Something like this was exactly what I was looking for.
– user447457
Nov 19 '18 at 20:06


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378772%2fefficiently-creating-a-tensor-of-diagonal-matrices%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

ts Property 'filter' does not exist on type '{}'

mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window