This is a problem that occurs when implementing the finite difference method (FDM).

Here is a toy example. Suppose we want to solve the boundary value problem (BVP).

$$ y & # 39; & # 39; (x) = sin (x), y (0) = 0, y (1) = 0 $$

```
eq = y & # 39; & # 39;[x] == Sin[x];
bc = {y[0] == 0, y[1] == 0};
```

With FDM we can then program as follows. First write down the corresponding difference formula:

```
Clear @ dx;
generalformula = (y[x + dx] - 2 years[x] + y[x - dx]) / dx ^ 2 == sin[x];
```

Then define the grid size and generate difference equations at each grid point:

```
Points = 25; domain = {0, 1};
dx = @@ domain / subtract (1 - points);
var = table[y[y[y[y[x], {x, ##, dx}]& @@ domain;
differenceeq = table[Generalformula{xDomäne[[Generalformula{xdomain[[allgemeineFormel{xDomäne[[generalformula{xdomain[[1]]+ dx, domain[[-1]]- dx, dx}]~ Join ~ bc;
```

Finally, solve the difference equations with z. `NSolve`

:

```
Solrule = NSolve[differenceeq, var][[[[[1]]; // Absolute timing
(* {0.00462427, zero} *)
```

Incidentally, a comparison with the analytical solution:

```
asol = DSolveValue[{eq, bc}, y, x]
plot[asol[asol[asol[asol[x], {x, ##}, PlotRange -> All]~ Show ~
ListPlot[solrule[[All, -1]], DataRange -> {##}]& @@ domain
```

Alternatively, we can extract the coefficient array `Differenzäq`

and solve it `LinearSolve`

as in the document of `CoefficientArrays`

, This approach is faster than the one used `NSolve`

:

```
{barray, marray} = CoefficientArrays[differenceeq, var]; // Absolute timing
(* {0,000614324, zero} *)
sol = LinearSolve[marray // N, -barray]; // Absolute timing
(* {0,000488251, zero} *)
```

However, this is not the end. As already mentioned, we have generated a difference equation **at every grid point** and then **extract** the coefficient array from the symbol system in the code above. This procedure can be quite memory intensive and slow if `Points`

is big. Is it possible to generate `Barray`

and `Marray`

directly from `general formula`

and `bc`

**programmatically**in a memorable and not so slow way?

If the above toy example is too simple to illustrate the underlying problem, the following is more complicated to solve the problem mentioned here:

```
r = 0.8; Glass = (1.45) 2; Air = 1; k = (2π) / 1.55;
n2 = (function[{x, y}, #] & @ (Simplify`PWToUnitStep @
PiecewiseExpand @ if[X^2+y^2[X^2+y^2[x^2+y^2[x^2+y^2<= r^2, glass, air]));
ClearAll[fw, bw, delta]
SetAttributes[#, HoldAll] & /@ {fw, bw};
fw@D[expr_, x_] :=
With[{Δ = delta@ToString@x},
Subtract @@ (expr /. {{x -> x + Δ}, {x -> x}}) / Δ]bw @ D[expr_, x_] : =
With[{Δ = delta@ToString@x},
Subtract @@ (expr /. {{x -> x}, {x -> x - Δ}})/Δ]
delta[a_ + b_] : = Delta @ a + Delta @ b
delta[k_. delta[_]]: = 0
degree = function[expr, fw@D[expr, #] & / @ {x, y}];
div = function[expr, Total@MapThread[bw@D@## &, {expr, {x, y}}]];
elst = e[#][x, y] & /@ Offer[2];
discretelhs =
With[{N2=n2[{N2=n2[{n2=n2[{n2=n2[x, y]},
div @ grad @ elst + (n2 k ^ 2) elst - grad[div@elst - 1/n2 div[n2 elst]]];
Points = 100; L = 2; domain = {-L, L}; grid = array[# &, points, domain];
del = #[[2 ;; -2]]&;
delta["x"] = Delta["y"] = -Subtract @@ domain / (points - 1);
vare = Outer[e[e[e[e[#][#2, #3] &, Area @ 2, del @ grid, del @ grid, 1]// flattening;
discretelhslst =
Flattening when transposing[
Block[{e}, e[i_][L | -L, _] = e[i_][_, L | -L] = 0;
table[discretelhs, {x, del@grid}, {y, del@grid}]], {2, 3, 1}]; // Absolute timing
{barray2, marray2} = CoefficientArrays[discretelhslst // N, vare // N]; // Absolute timing
{val, vec} =
Eigensystem[marray2, -6,
Method -> {"Arnoldi", "Shift" -> k^2 glass}]; // Absolute timing
mat = ArrayReshape[#, {2, points - 2, points - 2}] & / @ vec;
MapThread[ArrayPlot[#[[ArrayPlot[#[[ArrayPlot[#[[ArrayPlot[#[[1]], PlotLabel -> Sqrt @ # 2, PlotRange -> All,
ColorFunction -> "AvocadoColors"]&, {mat, val}]
```

```
ByteCount[marray2]/ 1024 ^ 2. "MB"
(* 2.76122 "MB" *)
ByteCount[discretelhslst]/ 1024 ^ 2. "MB"
(* 180,695 "MB" *)
```

The corresponding problem is how to arrive `marray2`

from `discreet`

and `e[i_][L | -L, _] = e[i_][_, L | -L] = 0;`

without generating `discreet`

efficient enough?