Drop diagonal elements from array

General discussions on potential enhancements to the APL+Win system.

Drop diagonal elements from array

Postby Ajay Askoolum » August 26th, 2017, 2:18 pm

1. We have the ability to drop rows from the top and the bottom of arrays as well as columns from either end.
2. We have the ability to de-delect rows and columns from anywhere.

I would like a language supported feature that allows me to drop the diagonal elements from an array EITHER the top left to bottom right diagonal OR the top right to bottom left diagonal.
Ajay Askoolum
 
Posts: 654
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom

Re: Drop diagonal elements from array

Postby Eric.Lescasse » August 26th, 2017, 3:09 pm

For a square matrix, you can do:

Code: Select all
(¯1+⍴mat)⍴(,(⍳↑⍴mat)∘.≠⍳↑⍴mat)/,mat


or:

Code: Select all
(¯1+⍴mat)⍴(,⌽(⍳↑⍴mat)∘.≠⍳↑⍴mat)/,mat


for the other diagonal.
Is that what you wanted?

I assume you want something more general and simpler.
Eric.Lescasse
 
Posts: 46
Joined: February 8th, 2007, 7:55 pm
Location: Paris, France

Re: Drop diagonal elements from array

Postby Ajay Askoolum » August 26th, 2017, 3:31 pm

Thanks Eric.

I can find all sorts of ways to drop the diagonal elements but suggested that dropping the diagonal elements becomes a language feature.

It will probably need to operate on square matrices only (at least I cannot visualize what it might return for non-square matrices).
Ajay Askoolum
 
Posts: 654
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom

Re: Drop diagonal elements from array

Postby Davin Church » August 26th, 2017, 7:14 pm

Ajay Askoolum wrote:It will probably need to operate on square matrices only (at least I cannot visualize what it might return for non-square matrices).


See what
Code: Select all
1 1⍉array
gives you on a non-square matrix, at least if it's taller than it is wide. But then again, there could easily be two different definitions of "remove the diagonal" -- either it compresses missing elements to the left or it compresses them upwards. A non-square matrix could conceivably use whichever method would work, but I don't know if that would help you at all. Given the vagaries of the process, I don't see any reason why you'd want something like that built in.

FYI, what about using something like
Code: Select all
(-¯1+⍳↑⍴array)⌽0 1↓(¯1+⍳↑⍴array)⌽array
to remove a diagonal?
Davin Church
 
Posts: 407
Joined: February 24th, 2007, 1:46 am

Re: Drop diagonal elements from array

Postby Ajay Askoolum » August 26th, 2017, 10:40 pm

1. It does not have to be a square array.
2. Interpreter level support will probably be a lot faster.
3. It should work row-wise (as with relational data); shift-up (as in Excel) is a nasty aberration.

I had the same solution as yourself (mine is IO independent).

Code: Select all
    ∇ Z←RemoveLeftDiag;a
[1]   a←5 6⍴⍳10
[2]   (1 1⍉a)←0 ⍝ for visual verification
[3]   Z←a (((-¯1++\(↑⍴a)/1))⌽0 1↓(¯1++\(↑⍴a)/1)⌽a)
    ∇
      RemoveLeftDiag
  0  2 3  4 5  6    2  3  4 5  6
  7  0 9 10 1  2    7  9 10 1  2
  3  4 0  6 7  8    3  4  6 7  8
  9 10 1  0 3  4    9 10  1 3  4
  5  6 7  8 0 10    5  6  7 8 10


Code: Select all
    ∇ Z←RemoveRightDiag;a
[1]   a←5 6⍴⍳10
[2]   (1 1⍉⌽a)←0 ⍝ for visual verification
[3]   Z←a (((¯1++\(↑⍴a)/1))⌽0 ¯1↓(-¯1++\(↑⍴a)/1)⌽a )
    ∇
      RemoveRightDiag
  1  2 3  4 5  0    1  2 3  4  5
  7  8 9 10 0  2    7  8 9 10  2
  3  4 5  0 7  8    3  4 5  7  8
  9 10 0  2 3  4    9 10 2  3  4
  5  0 7  8 9 10    5  7 8  9 10

Ajay Askoolum
 
Posts: 654
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom

Re: Drop diagonal elements from array

Postby Davin Church » August 27th, 2017, 12:09 am

Ajay Askoolum wrote:1. It does not have to be a square array.
2. Interpreter level support will probably be a lot faster.
3. It should work row-wise (as with relational data); shift-up (as in Excel) is a nasty aberration.

Ok, tell me what you do if the array is 10x6 instead of 5x6.
Davin Church
 
Posts: 407
Joined: February 24th, 2007, 1:46 am

Re: Drop diagonal elements from array

Postby Ajay Askoolum » August 27th, 2017, 12:29 am

Well!
The objective was to remove the diagonal elements - so the second dimension of a 2D array should reduce by 1. This can happen only if the 2D array is square.

If the array is NOT square, neither dimension will decrease - that means that for , say, your 10x6, there will be a padding with 0 in the first six rows of the first or last column depending on whether you are removing the left- or right- diagonal. Almost certainly not what might be required.

However, there is no reason why interpreter level support for removing diagonal elements from square matrices cannot be provided: as with many other operators, this need only work when the arguments are conformable.
Ajay Askoolum
 
Posts: 654
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom

Re: Drop diagonal elements from array

Postby Davin Church » August 27th, 2017, 11:38 am

Ajay Askoolum wrote:The objective was to remove the diagonal elements - so the second dimension of a 2D array should reduce by 1. This can happen only if the 2D array is square.

No, it also can work the same way when the array is "short" (as in your example above)

Ajay Askoolum wrote:If the array is NOT square, neither dimension will decrease - that means that for , say, your 10x6, there will be a padding with 0 in the first six rows of the first or last column depending on whether you are removing the left- or right- diagonal. Almost certainly not what might be required.

Well, no - if it's "short" then the last dimension can decrease (as in your example above). It's only for "long" arrays (or if you decide to compress in the other dimension) that you have a problem. And I agree that it makes no sense to fill some areas with zeros in any case.

Ajay Askoolum wrote:However, there is no reason why interpreter level support for removing diagonal elements from square matrices cannot be provided: as with many other operators, this need only work when the arguments are conformable.

I disagree. The interpreter should only do things that are well-consistent and well-defined and meaningful for a large range of inputs, or it's not a good candidate for a language improvement. In this case, a function that only works on square, two-dimensional matrices is not something that I think should be built into the language proper. That would seem to be a better candidate for a user-defined utility function at best, and I probably wouldn't even go that far.

Besides, how often do you need to use this feature - is it something that you use as often as "+"? Is it something that has a common mathematical purpose? Is it something that you can't easily do by writing your own function instead? I personally don't really see this as useful at all, much less as a function required by many applications in general, but perhaps you can correct my opinion on this.
Davin Church
 
Posts: 407
Joined: February 24th, 2007, 1:46 am

Re: Drop diagonal elements from array

Postby brent hildebrand » August 28th, 2017, 11:32 pm

I'm not sure what the application for removal of diagonals would be, but here is a one function which will remove diagonals from a rectangular matrix, starting from the upper left and working to the lower right where the left argument is the starting point of the diagonal along the longest axis.

Code: Select all
    ∇ ret←larg RemoveDiagonal rarg;i;n;rot
[1]   ⍝ remove diagonals from 2 dimensional arrays
[2]   ⍝ larg = index of start of diagonal on the longest dimention
[3]   
[4]   larg←⎕vget 'larg' ⎕io
[5]   :if larg>(⎕io+∣-/⍴rarg)
[6]       ⎕error 'INDEX ERROR'
[7]   :end
[8]   
[9]   :if ≤/⍴rarg
[10]      rot←(larg-⎕io)+(-⎕io)+⍳↑⍴rarg
[11]      ret←(-rot)⌽0 1↓rot⌽rarg
[12]  :else
[13]      rot←(larg-⎕io)+(-⎕io)+⍳¯1↑⍴rarg
[14]      ret←(-rot)⊖1 0↓rot⊖rarg
[15]  :end
    ∇


examples:
a←3 10⍴⍳100
a
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
RemoveDiagonal a
2 3 4 5 6 7 8 9 10
11 13 14 15 16 17 18 19 20
21 22 24 25 26 27 28 29 30
4 RemoveDiagonal a
1 2 3 5 6 7 8 9 10
11 12 13 14 16 17 18 19 20
21 22 23 24 25 27 28 29 30

a←⍉3 10⍴⍳100
a
1 11 21
2 12 22
3 13 23
4 14 24
5 15 25
6 16 26
7 17 27
8 18 28
9 19 29
10 20 30
RemoveDiagonal a
2 11 21
3 13 22
4 14 24
5 15 25
6 16 26
7 17 27
8 18 28
9 19 29
10 20 30
8 RemoveDiagonal a
1 11 21
2 12 22
3 13 23
4 14 24
5 15 25
6 16 26
7 17 27
9 18 28
10 20 29

a←5 6⍴⍳10
a
1 2 3 4 5 6
7 8 9 10 1 2
3 4 5 6 7 8
9 10 1 2 3 4
5 6 7 8 9 10
RemoveDiagonal a
2 3 4 5 6
7 9 10 1 2
3 4 6 7 8
9 10 1 3 4
5 6 7 8 10
brent hildebrand
 
Posts: 481
Joined: February 12th, 2007, 5:53 pm
Location: Loma Linda, CA

Re: Drop diagonal elements from array

Postby Garth Hutchinson » August 29th, 2017, 9:41 am

Not sure of its applicability but have dim remembrance of having to do this after a matrix multiplication operation.

Some other thoughts on arrays of higher order, first with equal dimensions. For a square the syntax
(minus or plus 1) Function array
the sign could differentiate between left & right diagonal removal. But this doesn't works so well for a cube (where there are 6 diagonal planes possible) or 4-dim-cube (where there are 24 diagonal oblique cubes possible) &c.

For rectangles, the sytax
(minus or plus n) Function array
could differentiate by sign between left & right diagonal removal as well as which diagonal. A diagonal which goes beyond the bounds of the array could give a NONCE error or wrap-around. (Wrap-around is also applicable to square array with non-unary left argument). For higher dimensions syntax might be (n m ...) Function array.

Don't see much point in having a function that only works on 2-dimensional square array. And have no idea of usefulness. But this i's all rather esoteric, and I have probably needed it only once in the past 30 or so years!
A corresponding problem is extracting diagonals; then you get into the question of the "width" of the diagonals to be extracted. :banana:
R. Garth Hutchinson, BTh, FCIA
In systems since 1962, APL-er since 1970's
Garth Hutchinson
 
Posts: 30
Joined: September 24th, 2008, 9:24 am
Location: Aurora, Ontario, Canada


Return to APL+Win Wish-List

Who is online

Users browsing this forum: No registered users and 1 guest

cron