New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetSlice for 3D (possibly 4D) arrays. #700

Open
swatalla opened this Issue Sep 30, 2018 · 8 comments

Comments

Projects
None yet
4 participants
@swatalla

swatalla commented Sep 30, 2018

Extending multidimensional array types with a GetSlice method

This is my first suggestion (ever), so I apologize if this is not the correct method of suggesting such an implementation.

My current solution for implementing a GetSlice method on a 3D array is to use a type extension:

type ``[,,]``<'a> with
    member this.GetSlice(x: int, startY: int option, endY: int option, startZ: int option, endZ: int option) =
        let startY, endY = 
            Option.defaultValue (this.GetLowerBound 1) startY,
            Option.defaultValue (this.GetUpperBound 1) endY
        let startZ, endZ = 
            Option.defaultValue (this.GetLowerBound 2) startZ,
            Option.defaultValue (this.GetUpperBound 2) endZ
        let slice = Array2D.zeroCreate<'a> (this.GetLength 1) (this.GetLength 2)
        for y in startY..endY do
            for z in startZ..endZ do
               slice.[y-startY, z-startZ] <- this.[x,y,z]
        slice
    member this.GetSlice(startX: int option, endX: int option, y: int, startZ: int option, endZ: int option) =
        let startX, endX = 
            Option.defaultValue (this.GetLowerBound 1) startX,
            Option.defaultValue (this.GetUpperBound 1) endX
        let startZ, endZ = 
            Option.defaultValue (this.GetLowerBound 2) startZ,
            Option.defaultValue (this.GetUpperBound 2) endZ
        let slice = Array2D.zeroCreate<'a> (this.GetLength 1) (this.GetLength 2)
        for x in startX..endX do
            for z in startZ..endZ do
               slice.[x-startX, z-startZ] <- this.[x,y,z]
        slice
    member this.GetSlice(startX: int option, endX: int option, startY: int option, endY: int option, z: int) =
        let startX, endX = 
            Option.defaultValue (this.GetLowerBound 1) startX,
            Option.defaultValue (this.GetUpperBound 1) endX
        let startY, endY = 
            Option.defaultValue (this.GetLowerBound 2) startY,
            Option.defaultValue (this.GetUpperBound 2) endY
        let slice = Array2D.zeroCreate<'a> (this.GetLength 1) (this.GetLength 2)
        for x in startX..endX do
            for y in startY..endY do
               slice.[x-startX, y-startY] <- this.[x,y,z]
        slice

Currently, slicing syntax for a 3D array only supports the Item method, in which some3DArray.[i,j,k] is valid, but some3DArray.[*,*,k] is not.

I can't think of a reason as to why this method wouldn't exist in the core library, but it would be a welcome addition. For such basic functionality when working with an array, this could likely be implemented much more elegantly than my attempt.

Pros and Cons

The advantage of making this adjustment to F# is more flexibility when using multidimensional arrays, especially when trying to work on a volume slice-by-slice. Including this type extension in every project seems to introduce an unnecessary degree of boilerplate.

I can't think of any disadvantages.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): XS

Related suggestions: #662

Affidavit

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this (I am not a programmer, but I would be willing to share my implementations)
@cartermp

This comment has been minimized.

Show comment
Hide comment
@cartermp

cartermp Oct 4, 2018

Member

I think this would be perfectly reasonable.

Member

cartermp commented Oct 4, 2018

I think this would be perfectly reasonable.

@dsyme

This comment has been minimized.

Show comment
Hide comment
@dsyme

dsyme Oct 9, 2018

Collaborator

Yes, we may as well go ahead with this. There should be a SetSlice implemention too, correct?

Collaborator

dsyme commented Oct 9, 2018

Yes, we may as well go ahead with this. There should be a SetSlice implemention too, correct?

@cartermp

This comment has been minimized.

Show comment
Hide comment
@cartermp

cartermp Oct 9, 2018

Member

@swatalla Would you be interested in writing a draft RFC for this in https://github.com/fsharp/fslang-design ?

Member

cartermp commented Oct 9, 2018

@swatalla Would you be interested in writing a draft RFC for this in https://github.com/fsharp/fslang-design ?

@swatalla

This comment has been minimized.

Show comment
Hide comment
@swatalla

swatalla Oct 9, 2018

@Dysme Sure - I will extend this as necessary.
@cartermp I also have a 4D array GetSlice method, so I'll do a draft for that as well. This is going to be my first contribution ever though... is there a template to follow or should I just roughly go off of some of the current RFC submissions?

swatalla commented Oct 9, 2018

@Dysme Sure - I will extend this as necessary.
@cartermp I also have a 4D array GetSlice method, so I'll do a draft for that as well. This is going to be my first contribution ever though... is there a template to follow or should I just roughly go off of some of the current RFC submissions?

@cartermp

This comment has been minimized.

Show comment
Hide comment
@cartermp

cartermp Oct 9, 2018

Member

@swatalla Super, thanks!

Member

cartermp commented Oct 9, 2018

@swatalla Super, thanks!

@abelbraaksma

This comment has been minimized.

Show comment
Hide comment
@abelbraaksma

abelbraaksma Oct 11, 2018

Should we make this available for only multi dimensional arrays, or also for jagged arrays? Not sure what syntax issue or caveats that brings, just thinking out loud ;)

abelbraaksma commented Oct 11, 2018

Should we make this available for only multi dimensional arrays, or also for jagged arrays? Not sure what syntax issue or caveats that brings, just thinking out loud ;)

@swatalla

This comment has been minimized.

Show comment
Hide comment
@swatalla

swatalla Oct 13, 2018

I don't think there are any issues with jagged array slicing; you would just use single slice notation for however many levels deep you wish to traverse. If you can think of a scenario in which a jagged array can't be sliced, I would be happy to look into it.

swatalla commented Oct 13, 2018

I don't think there are any issues with jagged array slicing; you would just use single slice notation for however many levels deep you wish to traverse. If you can think of a scenario in which a jagged array can't be sliced, I would be happy to look into it.

@abelbraaksma

This comment has been minimized.

Show comment
Hide comment
@abelbraaksma

abelbraaksma Oct 13, 2018

The leaf arrays in jagged arrays are of different length, they aren't the same as full dimensions in rectangular arrays. Also, the syntax of creating and modifying them are different. Thinking of it a bit more, I'd guess your proposal should only apply to the true dimensions of arrays and not to the jagged leaves of jagged arrays.

Jagged arrays with each leaf of the same length can behave the same as true multidimensional arrays, and are sometimes preferred because in many cases their performance characteristics are superior to multidimensional arrays.

abelbraaksma commented Oct 13, 2018

The leaf arrays in jagged arrays are of different length, they aren't the same as full dimensions in rectangular arrays. Also, the syntax of creating and modifying them are different. Thinking of it a bit more, I'd guess your proposal should only apply to the true dimensions of arrays and not to the jagged leaves of jagged arrays.

Jagged arrays with each leaf of the same length can behave the same as true multidimensional arrays, and are sometimes preferred because in many cases their performance characteristics are superior to multidimensional arrays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment