NonLinearEquationsSolver icon indicating copy to clipboard operation
NonLinearEquationsSolver copied to clipboard

Reducing memory allocations

Open wo80 opened this issue 3 years ago • 5 comments

I played around with the ILinearSolver interface of the sparse-matrices branch. Here's an implemetation which comes with zero additional memory allocations (using a custom LU implementation):

class OptimizedLinearSolverForTesting : ILinearSolver
{
    private ReusableLU lu;
    private Vector<double> solution;

    public OptimizedLinearSolverForTesting(int dimension)
    {
        this.lu = new ReusableLU(dimension);
        this.solution = new DenseVector(dimension);
    }

    public void Update(DenseMatrix stiffness)
    {
        lu.Compute(stiffness);
    }

    public Vector<double> Solve(Vector<double> input)
    {
        lu.Solve(input.AsArray(), solution.AsArray());
        return solution;
    }
}

It would be used like this:

[Fact]
public void SolveQuadraticFunctionSmallIncrements()
{
    // ALLOCATE MEMORY
    var reaction = new DenseVector(2);
    var stiffness = new DenseMatrix(2, 2);

    var solver = new OptimizedLinearSolverForTesting(2);

    // ARRANGE
    Vector<double> Reaction(Vector<double> u)
    {
        reaction[0] = u[0] * u[0] + 2 * u[1] * u[1];
        reaction[1] = 2 * u[0] * u[0] + u[1] * u[1];
        return reaction;
    };

    ILinearSolver Stiffness(Vector<double> u)
    {
        stiffness[0, 0] = 2 * u[0];
        stiffness[0, 1] = 4 * u[1];
        stiffness[1, 0] = 4 * u[0];
        stiffness[1, 1] = 2 * u[1];

        solver.Update(stiffness);

        return solver;
    }

    DenseVector force = new DenseVector(2) { [0] = 3, [1] = 3 };
    NonLinearSolver Solver = NonLinearSolver.Builder
        .Solve(2, Reaction, Stiffness)
        .Under(force)
        .WithInitialConditions(0.1, DenseVector.Create(2, 0), DenseVector.Create(2, 1))
        .UsingStandardNewtonRaphsonScheme(0.01)
        .Build();

    // ACT
    List<LoadState> states = Solver.Broadcast().TakeWhile(x => x.Lambda <= 1).ToList();

    // ASSERT
    AssertSolutionsAreCorrect(Reaction, force, states);
}

As already mentioned in https://github.com/EduardBargues/NonLinearEquationsSolver/issues/2#issuecomment-667889790, there are a couple of places in the NonLinearEquationsSolver code, where further optimization can be done (memory allocations in an iterative process should always be reduced as much as possible).

That's also a point where CSparse.NET has to be improved, if it should be used efficiently with this library (at the moment, matrix factors cannot be reused).

wo80 avatar Aug 03 '20 21:08 wo80