[Question]
  [
## Challenge:
Given an NxN matrix where \$N\geq2\$ and one of eight distinct 'folding options', output a 2D array/list with the subtracted values.
The eight folding options are: left-to-right; right-to-left; top-to-bottom; bottom-to-top; topleft-to-bottomright; topright-to-bottomleft; bottomleft-to-topright; bottomright-to-topleft.
**Step by step examples:**
Input matrix:
```
[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1],  (a'th row in the explanation below)
 [ 1,25, 0,75]]
```
With folding option top-to-bottom we output the following as result:
```
[[ 1,-7,-5,-3],
 [ 0,22,-5,68]]
```
Why? We fold from the top to the bottom. Since the matrix dimensions are even, we don't have a middle layer to preserve as is. The \$a\$'th row `[1, 1, 1, 1]` will be subtracted by the \$(a-1)\$'th row (would have been \$(a-2)\$'th row for odd dimension matrices); so `[1-0, 1-8, 1-6, 1-4]` becomes `[1, -7, -5, -3]`. The \$(a+1)\$'th row `[1, 25, 0, 75]` will then be subtracted by the \$(a-2)\$'th row (would have been \$(a-3)\$'th row for odd dimension matrices); so `[1-1, 25-3, 0-5, 75-7]` becomes `[0, 22, -5, 68]`.
With folding option bottomright-to-topleft instead (with the same input-matrix above) we output the following as result:
```
[[-74,  2,  1,  7],
 [  0,  7,  6],
 [-24,  1],
 [  1]]
```
With the following folding subtractions:
```
[[1-75,  3-1,  5-4,    7],
 [ 0-0,  8-1,    6],
 [1-25,    1],
 [   1]]
```
## Challenge rules:
* You can use any eight distinct letters `[A-Za-z]` or distinct numbers in the range \$[-99,99]\$ for the folding options. Numbers \$[1..8]\$ or \$[0..7]\$ are probably the most common options, but if you want to use different numbers within the range for some smart calculations, feel free to do so. **Please state which folding options you've used in your answer.**
* The input-matrix will always be a square NxN matrix, so you don't have to handle any rectangular NxM matrices. \$N\$ will also always be at least 2, since an empty or 1x1 matrix cannot be folded.
* The input of the matrix will always contain non-negative numbers in the range \$[0, 999]\$ (the numbers in the output will therefore be in the range \$[-999, 999]\$).
* With the (anti-)diagonal folding or odd-dimension vertical/horizontal folding, the middle 'layer' will remain unchanged.
* I/O is flexible. Can be a 2D array/list of integers; can be returned or printed as a space-and-newline delimited string; you can modify the input-matrix and replace the numbers that should be gone with `null` or a number outside of the `[-999, 999]` range to indicate they're gone; etc. etc.
## General rules:
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest answer in bytes wins.  
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
* [Standard rules apply](https://codegolf.meta.stackexchange.com/questions/2419/default-for-code-golf-program-function-or-snippet/2422#2422) for your answer with [default I/O rules](https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods/), so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
* [Default Loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden.
* If possible, please add a link with a test for your code (i.e. [TIO](https://tio.run/#)).
* Also, adding an explanation for your answer is highly recommended.
## Test cases:
Input-matrix 1:
```
Input-matrix (for the following eight test cases):
[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1],
 [ 1,25, 0,75]]
Input-folding option: left-to-right
Output: [[2,6],[-2,4],[0,0],[-25,74]]
Input-folding option: right-to-left
Output: [[-6,-2],[-4,2],[0,0],[-74,25]]
Input-folding option: top-to-bottom
Output: [[1,-7,-5,-3],[0,22,-5,68]]
Input-folding option: bottom-to-top
Output: [[0,-22,5,-68],[-1,7,5,3]]
Input-folding option: topleft-to-bottomright
Output: [[7],[6,-1],[1,-7,-2],[1,24,0,74]]
Input-folding option: topright-to-bottomleft
Output: [[1],[-3,8],[-4,-5,1],[-6,21,-1,75]]
Input-folding option: bottomleft-to-topright
Output: [[1,3,4,6],[8,5,-21],[1,1],[75]]
Input-folding option: bottomright-to-topleft
Output: [[-74,2,1,7],[0,7,6],[-24,1],[1]]
```
Input-matrix 2:
```
Input-matrix (for the following eight test cases):
[[17, 4, 3],
 [ 8, 1,11],
 [11, 9, 7]]
Input-folding option: left-to-right
Output: [[4,-14],[1,3],[9,-4]]
Input-folding option: right-to-left
Output: [[14,4],[-3,1],[4,9]]
Input-folding option: top-to-bottom
Output: [[8,1,11],[-6,5,4]]
Input-folding option: bottom-to-top
Output: [[6,-5,-4],[8,1,11]]
Input-folding option: topleft-to-bottomright
Output: [[3],[1,7],[11,1,-10]]
Input-folding option: topright-to-bottomleft
Output: [[17],[4,1],[8,-2,7]]
Input-folding option: bottomleft-to-topright
Output: [[17,-4,-8],[1,2],[7]]
Input-folding option: bottomright-to-topleft
Output: [[10,-7,3],[-1,1],[11]]
```
  
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~256~~ ~~248~~ ~~244~~ 248 bytes
```
m=d=x=@(a,b=1)rot90(a,b)
y=@(a,b=2)flip(a,b)
z=@(a,b=1)tril(a+1e3,-1)+a-x(y(tril(a)))+b*diag(diag(a))
f=@(a,b){m=((a-y(a))(:,1:(d=size(a,2)/2))),-y(m),m=y(x((a=x(a))-y(a)))(d+1:end,:),y(m,1),-y(z(a,-1)),x(z(x(a,2)),2),z(a=x(a,3)),x(z(x(a,2)),2)}{b}
```
[Try it online!](https://tio.run/##nY5Ba4QwEIXv@RW5CJk6oUbXdasEimdP4q30EKsWYe2WrZTosr/djuvSS08NJJnHe@9LcnobzXe7LINutNXPwmCtFZxP41OwamDT3QyhO/afmzf/FsdzfxTGV22EUoFvpBWT2EwA8OuHpjfv4naQwboNhMughTByWk2RokpFo7/6uaUwhMeQUKRwABz0JCxVtV2rGwCi8VXafjSYAlIL1a09E0x/ALQk7e0moI3zRmP0J7pe6uvSiReFPEIeI0@yAPkB@R75LiP3vlYZUhxgEmev9Bz7PxS6QJELtHOBYhdo7wIlLtABmFfKgnmFLJmXy4p5lcxJlbIityplTiMvZEXx8gM "Octave – Try It Online")
*-2 bytes (and a bity of tidying up) thanks to [Luis Mendo](https://codegolf.stackexchange.com/users/36398/luis-mendo)*
*+2 bytes due to the correction for T-B*
1-Indexed operations for values of b from 1-8:
```
R-L
L-R
B-T
T-B
BR-TL
TR-BL
BL-TR
TL-BR
```
This gave me a headache, I'll golf it properly later
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~39~~ 34 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
*There is possibly further golfing possible by combining some of the two "functions".*  
...yep: **-5** thanks to NickKennedy! 
```
ṃ“Z“Ṛ“U“ “ŒDṙL ZZṚ”ŒḄFḲj“ŒH_Ṛ}¥/”v
```
**[Try it online!](https://tio.run/##y0rNyan8///hzuZHDXOigPjhzllAMhSID209Oskj/uHOVUAhFZWHu/oObYWKujzcsSjcOh4kfmzTw52NXkcnPdzRA5KeC2K1uJX9///f0OB/dLSCoY6CsY6CqY6CeawOl0K0goGOgoWOgpmOggmED5SHIhjfCKjYQMfcNDYWAA "Jelly – Try It Online")**
A dyadic link accepting an integer (the instruction) and a list of lists of numbers (the matrix).
Uses the option to take the instruction as an integer in \$[-99,99]\$ to our advantage, and hence has the following seemingly bizarre mapping:
```
           Instruction  |  integer
------------------------+---------
         left-to-right  |     4
         right-to-left  |    14
         top-to-bottom  |     9
         bottom-to-top  |    39
topleft-to-bottomright  |    65
topright-to-bottomleft  |    15
bottomleft-to-topright  |    10
bottomright-to-topleft  |     0
```
### How?
The link creates Jelly code which is then evaluated using M as an input...
```
ṃ“Z“Ṛ“U“ “ŒDṙL ZZṚ”ŒḄFḲj“ŒH_Ṛ}¥/”v - Link: integer, I; matrix, M
 “Z“Ṛ“U“ “ŒDṙL ZZṚ”                - list of lists of characters = ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
ṃ                                  - base decompress (I) using those lists as the digits
                                   -  ...i.e. convert to base 5 and then convert the digits:
                                   -          [1,2,3,4,0] -> ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
                   ŒḄ              - bounce
                                   -  ...e.g. [a, b, c] -> [a, b, c, b, a]
                     F             - flatten to a list of characters
                      Ḳ            - split at spaces
                       j           - join with:
                        “ŒH_Ṛ}¥/”  -   list of characters = "ŒH_Ṛ}¥/"
                                 v - evaluate as Jelly code with an input of M
```
Each of the eight options are then:
```
left-to-right           (4): ŒH_Ṛ}¥/
right-to-left          (14): ṚŒH_Ṛ}¥/Ṛ
top-to-bottom           (9): ZŒH_Ṛ}¥/Z
bottom-to-top          (39): ZṚŒH_Ṛ}¥/ṚZ
topleft-to-bottomright (65): ṚUŒDṙLŒH_Ṛ}¥/ZZṚUṚ
topright-to-bottomleft (15): UŒDṙLŒH_Ṛ}¥/ZZṚU
bottomleft-to-topright (10): ṚŒDṙLŒH_Ṛ}¥/ZZṚṚ
bottomright-to-topleft  (0): ŒDṙLŒH_Ṛ}¥/ZZṚ
```
These each (except `0` and `4`) apply a transform to `M` using some of `Z` (transpose), `Ṛ` (reverse), and `U` (reverse each); then one of two functions (see below), then the inverse of the setup transformation (if there was one) implemented with the reverse of the code.
The two inner functions are:
```
ŒH_Ṛ}¥/ - Function A: Fold bottom-to-top: matrix, M
ŒH       - split M into two equal lists of rows (first half bigger by 1 if need be)
      / - reduce by:
     ¥  - last two links as a dyad:
    }   -  using the right argument (i.e. second half):
   Ṛ    -    reverse
  _     -  subtract
ŒDṙLŒH_Ṛ}¥/ZZṚ - Function B: Fold topright-to-bottomleft: matrix, M
ŒD             - diagonals of M
  ṙ            - rotate left by:
   L           -   length of M (puts them in order from bottom left most)
    ŒH_Ṛ}¥/    - same action as calling Function A on the diagonals
           Z   - transpose
            Z  - transpose
             Ṛ - reverse
```
[Answer]
# JavaScript (ES6), ~~149 ... 133~~ 128 bytes
Takes input as `(matrix)(d)` with \$0\le d\le7\$. Removed values are replaced with `NaN`.
Folding directions: \$0 =\;\rightarrow\$, \$1 =\;\downarrow\$, \$2 =\;\small\searrow\$, \$3 =\;\small\swarrow\$, \$4 =\;\leftarrow\$, \$5 =\;\uparrow\$, \$6 =\;\small\nwarrow\$, \$7 =\;\small\nearrow\$
```
m=>d=>m.map((r,y)=>r.map((v,x)=>v-=(w=m.length+~y)-(p=[x+x-y,y,x,q=w+y-x][d&3])&&[r[q],m[w][x],m[q][w],m[x][y]][d>3^p>w?d&3:m]))
```
[Try it online!](https://tio.run/##VU/LbsIwELznK3xAYCubiBBoaCunp34BR@OKCIeXsB2MlYdQ@@upHShSpZV2dzQ7O3Mq6uK6NcfKRkqLst/RXtJc0FzGsqgwNtARmpv7UkPrljqiuKEyPpdqbw/hT0ciXFHWhm3UQQctXGgTdlHLmRinnIzHzLALB8kazlrfL9yNrjtGxx0rT7@qvPlw7DfJCeltebWIIolojtgUUAJoBigFNAe0APQCKOPxTpvPYnvAwrEChLZaXfW5jM96jzcOQ6Ob@F6r0W2HJcGCDAGMV7xnqf1Yx1avrDmqPSZxVYiVLYzFc0Likz4qPJk8p7WaECe3IQF5DwJvEDP3lXlv6eAq4zAAzu9y8Dh/AAn81ROYOf4UsgUP@H@5JBtCpg/m0t8lj7vESbz6P/6o/wU "JavaScript (Node.js) – Try It Online")
### Commented
```
m => d =>                   // m[] = matrix; d = direction
  m.map((r, y) =>           // for each row r[] at position y in m[]:
    r.map((v, x) =>         //   for each value v at position x in r[]:
      v -=                  //     subtract from v:
        (                   //       define w as:
          w = m.length + ~y //         the width of input matrix - y - 1
        ) - (               //       and compare it with
          p = [             //       p defined as:
            x + x - y,      //         2 * x - y for vertical folding
            y,              //         y for horizontal folding
            x,              //         x for diagonal folding
            q = w + y - x   //         q = w + y - x for anti-diagonal folding
          ][d & 3]          //       using d MOD 4
        ) &&                //       if p is equal to w, leave v unchanged
        [                   //       otherwise, subtract:
          r[q],             //         r[q] for vertical folding
          m[w][x],          //         m[w][x] for horizontal folding
          m[q][w],          //         m[q][w] for diagonal folding
          m[x][y]           //         m[x][y] for anti-diagonal folding
        ][                  //       provided that we're located in the target area:
          d > 3 ^           //         test p < w if d > 3 
          p > w ? d & 3     //         or p > w if d <= 3
                : m         //         and yield either d MOD 4 or m[]
        ]                   //       (when using m[], we subtract 'undefined' from v,
                            //       which sets it to NaN instead)
    )                       //   end of inner map()
  )                         // end of outer map()
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~71~~ 34 bytes
```
ḃ2ŒḄ,UZṚŒDṙLƊŒH_Ṛ}¥/$ZZṚƊṚZ8ƭ$ị@¥ƒ
```
[Try it online!](https://tio.run/##y0rNyan8///hjmajo5Me7mjRCY16uHPW0UkuD3fO9DnWdXSSRzyQX3toqb5KFEjmWBeQiLI4tlbl4e5uh0NLj036/9/EREfBxEBHwdgMiI10FExBbKCYKRAbW/w3NvsfHa1gCGQDhXQUzGN1uBSiFYBqLHQUgDpMIHygPBTB@EZAxQY65qaxsQA "Jelly – Try It Online")
[Test Suite](https://tio.run/##y0rNyan8///hjmajo5Me7mjRCY16uHPW0UkuD3fO9DnWdXSSRzyQX3toqb5KFEjmWBeQiLI4tlbl4e5uh0NLj036X2FxePmjpjUPdyziMjHRMTHQMTbTMTbSMQUyTHRMTXSMIfJA43fOANKRXHCW9aOGOYe21RzaVnZo26OGudaH27kOtwMlsh417ju07dC2//@jo6MVDHUUjHUUTHUUzGN1uBSiFQx0FCx0FMx0FEwgfKA8FMH4RkDFBjrmprFAgehoQ3OgUqAZEFkLkFJDiFJDoCZLkLmxsQA "Jelly – Try It Online")
A full program. Right argument is the matrix. Left argument is the type of fold:
```
44 = L-R
40 = R-L
36 = T-B
32 = B-T
50 = TL-BR
34 = TR-BR
54 = BL-TR
38 = BR-TL
```
Rewritten to use 5-bit bijective binary as input. Note the program given above won’t work repeatedly for multiple folds.
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~482 bytes~~, 459 Bytes
The inputs for deciding folding directions are:  
1)left to right  
2)bottom to top  
3)right to left  
4)top to bottom  
5)tr to bl  
6)br to tl  
7)bl to tr  
8)tl to br  
Each call only generates the specified fold, rather than all of them (which would probably would take less bytes). Biggest problem is that for this case I can't figure out how to put folds 1-4 and 5-8 in the same loop. But at least octave has nice looking matrices.
```
    function[m]=f(n,o)
    k=length(n);m=NaN(k);if(o<5)
    if(mod(o,2)>0)n=n'end
    q=[0,0,k+1,k+1](o)
    for x=1:ceil(k/2)if(x*2>k)m(x,:)=n(x,:)else
    for a=1:k
    m(abs(q-x),a)=n(abs(q-x),a)-n(abs(q-(k+1-x)),a)end
    end
    end
    if(mod(o,2)>0)m=flipud(m')end
    else
    if(mod(o,2)>0)n=flip(n)end
    q=[0,0,k+1,k+1](o-4)
    for x=1:k
    for a=1:k+1-x
    if(a==k+1-x)m(x,a)=n(x,a)else
    m(abs(q-x),abs(q-a))=n(abs(q-x),abs(q-a))-n(abs(q-(k+1-a)),abs(q-(k+1-x)))end
    end
    end
    end
    if(mod(o,2)>0)m=flip(m)end
    end
```
[Try it online!](https://tio.run/##jY/fbsIgFIfv@xTcLMKGmdQ6nQ4fwRdoeoFatCl/tOLSt@84NI122RIuCHA4H7/z2YMT32XXybs5uMqaXBdcYkMtSWquSnNyZ2zIRvOd2OGabCqJ7deCJH7X9ogtTcl2Rgw3k9IckyvPZ3RG6zcGq8D@F2kb1HK2PpSVwvV7SjzZvqbbmmjc0jXhJmylupWhV/jeOtFY7G/4Om0JFdDydJsON@wjfAlqkD2s8WSaS1Vd7kesJ30X5PweHlq85Z8G0@zhUD8mhGj4R3DejwE2orcRvc2zQzgIMlYZimMjQYanQXCk958i1kNbJ3GesyVFGUXzYpOjFUWMMuaPjFH0SdGyKCgj6EWV0iFnUVOdzi6JwlKP7a1zVgPo7CUOm3sspAAFsXFY5jGfAVAfGoctAGsCpeKID9AKhIsklkCoQDRxxAqmCsS@6X4A "Octave – Try It Online")
Output suppression costs bytes, so ignore everything that isn't the return statement(ans = ).
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~78~~ 77 bytes
```
Ｆ⁴«ＵＭηＥ⮌η§μλ¿⁼ιθＵＭηＥκ⎇‹⊕⊗νＬη⁻μ§⮌κν⎇›⊕⊗νＬηωμ¿⁼ι﹪θ⁴ＵＭηＥκ⎇‹λν⁻μ§§ηνλ⎇›λνωμ»Ｅη⪫ι,
```
[Try it online!](https://tio.run/##jY9BS8NAEIXPza8YepqFEVpNrOBJVKTSgIi3kMOaTE3oZtfsJlURf3vcpA1F7KHsYWb27bz3bVZImxmpum5tLGAo4DuYxPL91lSV1DkWBH7CZ96ydYyFILhpljrnT6wIlBDiOpiUa8D7upXKYUlQCwH/HTYEL2y1tF@4YudwqTPLFeuGc7wz7avyVQtvv2L91hQ@yfdxqVvXB42ZI8fGi8Pr0fPBsmzYnmb7QVCJHTorx/CXPzZ5qwzWBKE46SuqZzkCO9Zip6tjvPvdA9FP8GRL3WAf5BcfTal7qClNe7nrkhkFSTKnC4pokVIA/uKKLikc@jkNZ9@fRzSjRZSmaXe2Vb8 "Charcoal – Try It Online") Link is to verbose version of code. Uses the following folding options:
```
0   top-to-bottom
1   left-to-right
2   bottom-to-top
3   right-to-left
4   bottomright-to-topleft
5   topright-to-bottomleft
6   topleft-to-bottomright
7   bottomleft-to-topright
```
Folded values are replaced by empty strings. Explanation:
```
Ｆ⁴«≔ＵＭηＥ⮌η§μλ
```
Rotate the array four times.
```
¿⁼ιθＵＭηＥκ⎇‹⊕⊗νＬη⁻μ§⮌κν⎇›⊕⊗νＬηωμ
```
Fold the array horizontally when appropriate.
```
¿⁼ι﹪θ⁴ＵＭηＥκ⎇‹λν⁻μ§§ηνλ⎇›λνωμ
```
Fold the array diagonally when appropriate.
```
»Ｅη⪫ι,
```
Output the array once it is rotated back to its original orientation.
]