fortran-lang / stdlib

Fortran Standard Library
https://stdlib.fortran-lang.org
MIT License
1.07k stars 164 forks source link

In-place naming convention #177

Open certik opened 4 years ago

certik commented 4 years ago

We need to figure out a consistent naming convention for routines that return the result in-place, as many routines will have two versions: in-place (e.g., eig_inplace) and out-of-place (e.g. eig). I think a good idea is to have the out-of-place version the default (eig), and have special naming convention for in-place (eig_inplace or some of the other option from the list below).

This was originally discussed at https://github.com/fortran-lang/stdlib/issues/10#issuecomment-567567033. List of options for syntax (https://github.com/fortran-lang/stdlib/issues/10#issuecomment-567624863):

I'll update this list if more candidates are proposed.

A lot of people like eig_inplace. It's long, but presumably it won't be used as often as eig, and it is clear what it does.

Other languages:

I couldn't find any naming convention how NumPy and Matlab does it. Looks like only Julia has a naming convention for in-place?

Julia

out-of-place: svd in-place: svd!

ivan-pi commented 4 years ago

I couldn't find any naming convention how NumPy and Matlab does it. Looks like only Julia has a naming convention for in-place?

Certain functions in SciPy (perhaps also NumPy, but I couldn't find any) accept some logical arguments if they should overwrite the inputs or not. Take solve for instance:

 scipy.linalg.solve(a, b, sym_pos=False, lower=False, overwrite_a=False, overwrite_b=False, debug=None, check_finite=True, assume_a='gen', transposed=False)

For MATLAB I found this old blog post (https://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/#8) which says that some of the built-in functions already obey in-place semantics (e.g. A=max(A,B) will not create an intermediate variable). Users can take advantage of this in their own functions (hoping the MATLAB JIT will do the right thing):

function y = myfunc(x)
y = sin(2*x.^2+3*x+4);

function x = myfuncIP(x)
x = sin(2*x.^2+3*x+4); 

Calling y = myfuncIP(x) would result in an error.

In the Eigen C++ library for linear algebra, they provide both options via template mechanisms and overloaded constructors (see https://eigen.tuxfamily.org/dox/group__InplaceDecomposition.html for details) :

PartialPivLU<Ref<MatrixXd> > lu(A); // in-place
PartialPivLU<MatrixXd> lu(A); // preserve A