1

can I have something like

A=1:10;

A(1:2 && 5:6)=0;

meaning I want to zero out specific ranges within my vector index expression in one line

Is that possible?

And what if I wanted to zero out all the rest like

A(~[1:2]) = 0 

What's the way of logical NOT within vector indexing?

Thanks

Machavity
  • 30,841
  • 27
  • 92
  • 100
  • And what if I wanted to zero out all the rest like A(~[1:2]) = 0 ? What's the way of logical NOT within vector indexing? – user3374479 Mar 30 '15 at 19:20
  • I edited my answer to also zero the complement of the indices you provided. – eigenchris Mar 30 '15 at 19:25
  • thanks, works great, but isn't there something with logical expressions? Shouldn't it be faster that way? – user3374479 Mar 30 '15 at 19:32
  • The `~` operator can only work on logical/boolean arrays, not numeric arrays like `[1:2,5:6]`. The `ismembc` function is way of turning an index list `[1 2 5 6]` into the appropriate logical array `[1 1 0 0 1 1 0 0 0 0]` so we can operate on it with `~`. It should be pretty fast. Performing this operation 10,000 times takes `0.13` seconds on my computer. – eigenchris Mar 30 '15 at 19:36
  • Hi, I found a new one line way to do this, now I'll see if it's faster :) – user3374479 Apr 01 '15 at 19:28
  • @user3374479: Please refrain from changing the question title to *solved* or adding the solution to your question. I did a rollback to the previous version. You can add your solution as an answer to the question if you think you add something to the current answers. – knedlsepp Apr 01 '15 at 19:34
  • ok thanks and sorry :) – user3374479 Apr 01 '15 at 19:36
  • @user3374479 Feel free to add your own answer if you find something better or useful to know. However, I want to point out that the `~` operator is the **logical NOT** operator, not a set complement operator. The `~` treats any non-zero value as *true* and negates it to a *false*, so `~[1:2,5:6]` is really `[~1, ~2, ~5, ~6]`, which is `[0, 0, 0, 0]`. As far as I know, MATLAB does not have a set complement operator, and you will need to resort to functions like `setdiff` or `ismembc` to get a set compliment. So far`ismembc` is the fastest solution I've found. – eigenchris Apr 01 '15 at 19:56
  • You're right, I suppose I wanted it to be a set compliment, when used with ranges Oh well… thanks again for your clarification – user3374479 Apr 01 '15 at 20:05
  • But what about a point to point multiplication of the logical with it's numerical self? Could that be faster than setdiff or ismembc? – user3374479 Apr 01 '15 at 20:06

2 Answers2

1

The following should work:

idx = [1:2,5:6];
A(idx) = 0

If you want to zero the complement of the vector of indices:

idx = [1:2,5:6];
A(~ismembc(1:length(A),idx)) = 0

Where ismembc is a faster, lightweight version of ismember that assumes the array is sorted and non-sparse with no NaN elements. (Credit goes to this question.)

Community
  • 1
  • 1
eigenchris
  • 5,791
  • 2
  • 21
  • 30
1

Just do A([1:2 5:6]). I.e., just create a vector of the indices you want to zero out.

Lazarus
  • 358
  • 1
  • 8