Sum MATLAB over all elements of the expressed value of the array

So I have been thinking about this for some time. Summing up some variable of array A is as simple as

 sum(A(:)) % or sum(...sum(sum(A,n),n-2)...,1) % where n is the dimension of A 

However, as soon as it receives expressions, (:) no longer works, for example

 sum((A-2*A)(:)) 

is not a valid matlab syntax, instead we need to write

 foo = A-2*A; sum(foo(:)) %or the one liner sum(sum(...sum(A-2*A,n)...,2),1) % n is the dimension of A 

One insert above will only work if the dimension A is fixed, which, depending on what you are doing, may not be necessary. The drawback of the two lines is that foo will remain in memory until you run clear foo or even be able to depend on the size of A and what else is in your workspace.

Is there a general way to get around this problem and summarize all elements of an expression with an array estimate in one line / without creating temporary variables? Something like sum(A-2*A,'-all') ?

Edit : it is different from How can I index the MATLAB array returned by a function without first assigning a local variable? , since this does not apply to the general (or specific) indexing of values ​​expressed in an array or return values, but rather to summation over each possible index.

While you can solve my problem with the answer provided in the link, Gnowitz tells himself that using subref is a rather ugly solution. Then Andras Dick posted a much cleaner way to do this in the comments below.

+5
source share
1 answer

Although the answers to the related duplicate can indeed be applied to your problem, the narrower scope of your question allows us to give a much simpler solution than the answers provided.

You can sum all the elements in the expression (including the return value of the function) by first changing your array to 1d:

 sum(reshape(A-2*A,1,[])) %or even sum(reshape(magic(3),1,[])) 

This converts your expression into an array of size [1, N] , where N is inferred from the size of the array, i.e. numel(A-2*A) (but the above reshape syntax will calculate the missing dimension for you, there is no need to evaluate your expression twice). Then, one call to sum will sum all the elements as needed.

The actual case when you need to resort to something like this is when a function returns an array with an unknown number of dimensions, and that you want to use your sum in an anonymous function (temporary variables are not available):

 fun = @() rand(2*ones(1,randi(10))); %function returning random 2 x 2 x ... x 2 array with randi(10) dimensions sumfun = @(A) sum(reshape(A,1,[])); sumfun(fun()) %use it 
+10
source

Source: https://habr.com/ru/post/1237172/


All Articles