GithubHelp home page GithubHelp logo

maroba / findiff Goto Github PK

View Code? Open in Web Editor NEW
413.0 10.0 59.0 2.41 MB

Python package for numerical derivatives and partial differential equations in any number of dimensions.

License: MIT License

Python 100.00%
scientific-computing numerical-methods derivative finite-difference-coefficients finite-difference finite-differences pde partial-differential-equations

findiff's People

Contributors

diehlpk avatar dwierichs avatar js-808 avatar maroba avatar matthias-baer avatar tan2 avatar tnigon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

findiff's Issues

findiff xarray/dask compatible

Hi, any intentions to make findiff xarray/dask compatible? this would make it easier to distribute tasks on a cluster. Not sure how much work this involves of course...

ModuleNotFoundError: No module named 'findiff'

c:...\trendln_init_.py in get_extrema(h, extmethod, accuracy)
434 elif extmethod == METHOD_NUMDIFF:
435 #pip install findiff
--> 436 from findiff import FinDiff
437 dx = 1 #1 day interval
438 d_dx = FinDiff(0, dx, 1, acc=accuracy) #acc=3 #for 5-point stencil, currenly uses +/-1 day only

ModuleNotFoundError: No module named 'findiff'

package findiff is correctly installed, what can I do?

float instead of integer in coefs.py

Error message:
"coefs.py", line 126, in _build_matrix
A = [([1 for _ in range(-p, q+1)])]
TypeError: range() integer end argument expected, got float.

Solution that I am using:
I changed line 30, from:
num_central = (2 * math.floor((deriv + 1) / 2) - 1 + acc)
to this:
num_central = int (2 * math.floor((deriv + 1) / 2) - 1 + acc)

it seems it is working, my code is as follows:

import coefs
coefs0 = coefs.coefficients(deriv=2, acc=2)

How to Calculate the Backward Diff only?

Hi, my calculus is terrible. How would I calculate the backward diff only (1st order and 2nd order) between 2-3 points? I noticed the Findiff by default is calculating the center which relies on x+1. Just curious if there's a setting to calculate the diff a 0 using only 2-3 past values?

FinDiff class dosn't pass accuracy to Diff class

You can se the accuracy on instatiation of the FinDiff class and it is set as an attibute for the class but when Diff is called, this accuracy is not passed on:
lines 139, 141 and 151 of operators.py all read:
pd = Diff(axis, order)
Great package btw, really useful

Adding findiff to conda-forge

Hi! Great package. I have a package hs-process that has a dependency on findiff. I need to keep my package up to date on Anaconda, and that means all dependencies must be available there as well. I will go ahead and add the latest version of this package to conda-forge, but I would like to list you (@maroba) as a maintainer (as well as myself). Once I get the conda-forge recipe started, I will need you to comment saying you are willing to be a maintainer. I will add a comment here with a link to notify you of this.

Thanks, let me know if you have any questions!

Cannot get matrix representation of irregular spaced operator

First of all, thanks for a great library!

An example of the problem I'm having:

from findiff import FinDiff
import numpy as np

x = np.logspace(0, 2, 100)
operator = FinDiff(0, x)
f_test = x**2

assert np.max(np.abs((operator(f_test) - 2*x))) < 1e-12  # Works fine

m_op = operator.matrix(x.shape)  # fails

Traceback:

Traceback (most recent call last):
  File "/home/julius/.PyCharm2019.3/config/scratches/SH.py", line 10, in <module>
    m_op = operator.matrix(x.shape)
  File "/usr/local/lib/python3.6/dist-packages/findiff/operators.py", line 106, in matrix
    return self.pds.matrix(shape, h, acc)
  File "/usr/local/lib/python3.6/dist-packages/findiff/diff.py", line 415, in matrix
    v = c / h**order
TypeError: unsupported operand type(s) for ** or pow(): 'NoneType' and 'int'a

In principle there should be no reason to give the shape of x, since this is internally known, however, calling operator.matrix() throws missing argument exception.

Recent release does not accept Numpy integers as parameters

It seems that you have added checks like assert isinstance(order, int) recently. This prevents using Numpy integers, such as np.int32 which the code was able to handle before.

I suggest using assert isinstance(order, numbers.Integral) instead, and casting to int afterwards if you truly need to use that type (probably not).

matrix representation doesn't work with order>2

Hi,

the matrix representation seems doesn't work when order larger than 2.
For instance, the below code will raise an error:
x = np.zeros((10))
d3_dx3 = FinDiff((0, 1, 3))
mat = d3_dx3.matrix(x.shape)
print(mat.astype(int))

Screen Shot 2020-04-30 at 2 25 35 AM

Possible interface improvements

Hi! I recently discovered your package and I think it is great. I have a few suggestions about the API. Consider this example:

d_dx = FinDiff(h=[dx, dy, dz, du], dims=[0])
df_dx = d_dx(f)

Do you really need [dy, dz, du] if dims is equal to [0]? Consider the following interface

diff_result = FinDiff(f, (dim1, delta1, count1), (dim2, delta2, count2), ...)

where the last count fields are optional with a default value of 1. For example,

df_dx = FinDiff(f, (0, dx))
df_dx2 = FinDiff(f, (0, dx, 2))
df_dxdy = FinDiff(f, (0, dx), (1, dy))

Also, if one needs a callable, it is always easy to use a lambda:

d_dx = lambda x: FinDiff(x, (0, dx))

Finally, to support non-uniform grids, you can check whether the delta field is a scalar or a vector.

I have a few other suggestions, but I'm curious to hear what you think of these first.

Again, thanks for publishing this package. I think it is weird that NumPy doesn't have this built-in, and this package fills an important gap. Maybe it will eventually find its way into NumPy.

coefficients: small offsets could raise `Cannot compute accuracy' error unexpectedly

Hi devs!
This repo looks cool 😎

When I try to calculate finite difference coefficients, I encountered exception `Cannot compute accuracy'.

raise Exception('Cannot compute accuracy.')

My offsets are somehow small:

import numpy as np
import findiff

offsets = np.array([-4, -2, -1, 0, 1, 2, 4]) * 0.0001
findiff.coefficients(deriv=3, offsets=list(offsets))

The following code may probably alleviate the problem.

def _calc_accuracy(offsets, coefs, deriv, symbolic=False):

    n = deriv + 1
    max_n = 999
    if symbolic:
        break_cond = lambda b: b != 0
        while True:
            b = 0
            for o, coef in zip(offsets, coefs):
                b += coef * o ** n
            if break_cond(b):
                break
            n += 1
            if n > max_n:
                raise Exception('Cannot compute accuracy.')
    else:
        break_cond = lambda b: abs(b) > 1.E-6
        coefs_array = np.array(coefs)
        offsets_scaled = np.array(offsets)
        offsets_scaled = offsets_scaled / np.abs(offsets_scaled).max()
        while True:
            l = coefs_array * offsets_scaled**n
            b = l.sum() / np.abs(l).sum()
            if break_cond(b):
                break
            n += 1
            if n > max_n:
                raise Exception('Cannot compute accuracy.')

    return round(n - deriv)

First Order Schemes

Hi,
in case I want to use findiff for educational purpose, showing the differences in accuracy for first, second and higher order schemes, how can I enforce the usage of pure forward/backward differencing? Furthermore, e.g. thinking of advection, is it possible to realize upwind or TVD schemes with findiff?
Any help is greatly appreciated, kind regards!

Two boundary conditions on the same boundary

Hi

How would you go about to set two boundary conditions on the same border?
For instance in you example with the 1D forced harmonic oscillator with friction to have both u(0)=0 and du/dx (0) = 0.

Petter

PDEs

Can this package solve partial differential equations(several interrelated differential equations)?

Problems with the stencil matrix

Hi, I've been trying to produce the stencil matrix for the Helmholtz operator

Helmholtz = Identity() - FinDiff(0, dx, 2)

I've noticed that general operators such as Minus does not have the stencil attribute to be produced. Would it be possible to include this in future version?

I've also found an error in the following code snippet of README:

import numpy as np
from findiff import FinDiff

x, y = np.linspace(0, 1, 100)  #Supposed to be x, y = np.linspace(0, 1, 100), np.linspace(0, 1, 100)?
X, Y = np.meshgrid(x, y, indexing='ij')
u = X**3 + Y**3
laplace_2d = FinDiff(0, x[1]-x[0], 2) + FinDiff(1, y[1]-y[0], 2)

stencil = laplace_2d.stencil(u.shape)

print(stencil)  #Supposed to be print(stencil.data)?

does not yield the desired result. Instead, I get:

{('L', 'L'): {(0, 0): 39203.99999999999, (0, 1): -49004.99999999999, (0, 2): 39203.99999999999, (0, 3): -9800.999999999998, (1, 0): -49004.99999999999, (2, 0): 39203.99999999999, (3, 0): -9800.999999999998}, ('L', 'C'): {(0, -1): 9800.999999999998, (0, 1): 9800.999999999998, (1, 0): -49004.99999999999, (2, 0): 39203.99999999999, (3, 0): -9800.999999999998}, ('L', 'H'): {(0, -3): -9800.999999999996, (0, -2): 39203.999999999985, (0, -1): -49004.99999999998, (0, 0): 39203.999999999985, (1, 0): -49004.99999999999, (2, 0): 39203.99999999999, (3, 0): -9800.999999999998}, ('C', 'L'): {(-1, 0): 9800.999999999998, (0, 1): -49004.99999999999, (0, 2): 39203.99999999999, (0, 3): -9800.999999999998, (1, 0): 9800.999999999998}, ('C', 'C'): {(-1, 0): 9800.999999999998, (0, -1): 9800.999999999998, (0, 0): -39203.99999999999, (0, 1): 9800.999999999998, (1, 0): 9800.999999999998}, ('C', 'H'): {(-1, 0): 9800.999999999998, (0, -3): -9800.999999999996, (0, -2): 39203.999999999985, (0, -1): -49004.99999999998, (0, 0): -3.637978807091713e-12, (1, 0): 9800.999999999998}, ('H', 'L'): {(-3, 0): -9800.999999999996, (-2, 0): 39203.999999999985, (-1, 0): -49004.99999999998, (0, 0): 39203.999999999985, (0, 1): -49004.99999999999, (0, 2): 39203.99999999999, (0, 3): -9800.999999999998}, ('H', 'C'): {(-3, 0): -9800.999999999996, (-2, 0): 39203.999999999985, (-1, 0): -49004.99999999998, (0, -1): 9800.999999999998, (0, 0): -3.637978807091713e-12, (0, 1): 9800.999999999998}, ('H', 'H'): {(-3, 0): -9800.999999999996, (-2, 0): 39203.999999999985, (-1, 0): -49004.99999999998, (0, -3): -9800.999999999996, (0, -2): 39203.999999999985, (0, -1): -49004.99999999998, (0, 0): 39203.999999999985}}

I believe x, y = np.linspace(0, 1, 100), np.linspace(0, 1, 100) should be x, y = np.linspace(0, 99, 100), np.linspace(0, 99, 100) to get the desired result.

Thank you for your time and for developing this nice package.

Update: I've edited this and now it is not so much a 'problem' with the stencil matrix but rather a feature request.

Custom Coefficients and Offsets

Is it possible, or could it be a feature, to different coefficients? I have some optimised coefficients for a given dataset and would to use these to get a more accurate result.

Accuracy not affecting stencil generation

It seems like when I generate a Stencil, the accuracy is being ignored.
Repro:
x = np.linspace(0, 10, 11)
y = np.linspace(0, 10, 11)
X, Y = np.meshgrid(x, y, indexing='ij')
u = X+Y
d1x = FinDiff(0, x[1] - x[0],1,acc=10)
stencil1 = d1x.stencil(u.shape)
print(stencil1)

Output (this is the same no matter when I change accuracy too):
('L', 'L'): {(0, 0): -1.5, (1, 0): 2.0, (2, 0): -0.5}
('L', 'C'): {(0, 0): -1.5, (1, 0): 2.0, (2, 0): -0.5}
('L', 'H'): {(0, 0): -1.5, (1, 0): 2.0, (2, 0): -0.5}
('C', 'L'): {(-1, 0): -0.5, (0, 0): 0.0, (1, 0): 0.5}
('C', 'C'): {(-1, 0): -0.5, (0, 0): 0.0, (1, 0): 0.5}
('C', 'H'): {(-1, 0): -0.5, (0, 0): 0.0, (1, 0): 0.5}
('H', 'L'): {(-2, 0): 0.5, (-1, 0): -2.0, (0, 0): 1.5}
('H', 'C'): {(-2, 0): 0.5, (-1, 0): -2.0, (0, 0): 1.5}
('H', 'H'): {(-2, 0): 0.5, (-1, 0): -2.0, (0, 0): 1.5}

Using findiff to solve the stationary Schrödinger equation

When trying to solve the stationary Schrödinger equation following the example at https://findiff.readthedocs.io/en/latest/source/examples-matrix.html, the code doesn't work.

x1_list=np.linspace(-8 * pi,8 * pi,201)
x2_list=np.linspace(-0.5 * pi,1.5 * pi,201)
dx=x1_list[1]-x1_list[0]
dy=x2_list[1]-x2_list[0]
x,y=np.meshgrid(x1_list,x2_list)

u=(-2 * 20 * np.cos(y) * np.cos(x-pi) + 0.03 * x**2)

Hm=(-15 * FinDiff(0,dx,2)-0.04 * FinDiff(1,dy,2)).matrix(u.shape)+u.reshape(-1)
energies, states = eigs(
Hm, k=5, which='SR'
)
bit0=states[:,0].reshape(201,201)

There is a memory error:
MemoryError: Unable to allocate 12.2 GiB for an array with shape (40401, 40401) and data type float64

Accuracy

Im trying to solve a nonlinear ODE with this package and encountered a problem with th accuracy parameter. Following simple example should demonstrate:

import findiff as fd
import numpy as np
import matplotlib.pyplot as plt

plt.figure('low res')
x = np.linspace(-np.pi*5,np.pi*5,100)
y = np.sin(x)
plt.plot(x,y,'r-')
plt.plot(x,y,'ro')
dx = x[1]-x[0]

#init differentiateoperators
d_dx = fd.FinDiff(0,dx,1,acc=2)
dw_dx = d_dx(y)
plt.plot(x, dw_dx, label='low res, low acc')
d_dx = fd.FinDiff(0,dx,1,acc=60)
dw_dx = d_dx(y)
plt.plot(x, dw_dx, label='low res, high acc')
plt.ylim((-1.1,2))
plt.legend()


plt.figure('high res')
x = np.linspace(-np.pi*5,np.pi*5,2500)
y = np.sin(x)
plt.plot(x,y,'r-')
plt.plot(x,y,'ro')
dx = x[1]-x[0]

#init differentiateoperators
d_dx = fd.FinDiff(0,dx,1,acc=2)
dw_dx = d_dx(y)
plt.plot(x, dw_dx, label='high res, low acc')
d_dx = fd.FinDiff(0,dx,1,acc=60)
dw_dx = d_dx(y)
plt.plot(x, dw_dx, label='high res, high acc')
plt.ylim((-1.1,2))
plt.legend()

Of Course a high accuracy at low resolution should lead to an unaccurate results since the stencil is to long for a good result. but i am stunned how inappropiate the result for the high accuracy high resolution is in the central part.

low_res

Even though the forward and backward schemes are pretty good, the central scheme is still far off obviously visible. Since the central scheme is mor sccurate as lomng as i understood FD, why isnt the result as prescise as it is at the border?

high_res

Do I missunderstand something? Or do i use it wrongly?

I hope i can get help. But it is a really nice and convienient package for Simulations ;-)
All the Best
trixxx3

Time-dependency

Hi! Thank you for the fantastic library!

I'm trying to simulate the wave equation using findiff, but I'm not getting the expected results even after changing the accuracy multiple times. The equation I'm trying to simulate is:
Screen Shot 2022-08-17 at 12 33 26 AM

The results I'm getting are:
output

I'm expecting a wave that starts from the left and propagates all the way to the right of the domain, but this is not the case. Also, I noticed that the middle-time instances have unreasonable values for u(x,t). Normally, it should not be more than 1.0 or less than -1.0.

Please advise. Below is my code:


import numpy as np
import matplotlib.pyplot as plt

from findiff import Gradient, Divergence, Laplacian, Curl
from findiff import FinDiff, PDE, Coef, BoundaryConditions, Identity
from findiff.stencils import Stencil
from itertools import product


shape = (100, 100)
x, t = np.linspace(0, 1, shape[0]), np.linspace(0, 1, shape[1])
dx, dt = x[1]-x[0], t[1]-t[0]
X, T = np.meshgrid(x, t, indexing='ij')


freq = 2
c = 1
a = 10 # accuracy
L = FinDiff(1, dt, 2, acc=a) - Coef(c**2) * FinDiff(0, dx, 2, acc=a)
f = np.zeros(shape)

bc = BoundaryConditions(shape)

#IC
bc[:, 0] = 0.   # Dirichlet BC

#BC
bc[0, :] =  np.sin(2*np.pi*freq*t)  # Dirichlet BC, Left
bc[-1, :] = 0.   # Dirichlet BC, Right

pde = PDE(L, f, bc)
u = pde.solve()


fig = plt.figure(figsize=(8, 15), dpi=80)
gs = fig.add_gridspec(5, hspace=0.5)
ax = gs.subplots()
plt.xlim(x[0],x[-1])

ax[0].plot(x, u[:,0])
ax[0].set_title('t=0.0')

ax[1].plot(x, u[:,25])
ax[1].set_title('t=0.25')

ax[2].plot(x, u[:,50])
ax[2].set_title('t=0.5')

ax[3].plot(x, u[:,75])
ax[3].set_title('t=0.75')

ax[4].plot(x, u[:,99])
ax[4].set_title('t=1.0')

Generating a high accuracy results in TypeError

GCC 10.1.1 20200507 (Red Hat 10.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import findiff
>>> coefs = findiff.coefficients(deriv=1, acc=15)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/diehlpk/.local/lib/python3.8/site-packages/findiff/coefs.py", line 42, in coefficients
    ret["forward"] = _calc_coef(0, num_coef - 1, deriv)
  File "/home/diehlpk/.local/lib/python3.8/site-packages/findiff/coefs.py", line 58, in _calc_coef
    "coefficients": np.linalg.solve(matrix, rhs),
  File "<__array_function__ internals>", line 5, in solve
  File "/home/diehlpk/.local/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 399, in solve
    r = gufunc(a, b, signature=signature, extobj=extobj)
TypeError: No loop matching the specified signature and casting was found for ufunc solve1

Future warning when using sequences for indexing

For the latest versions of Python 3 (tested in python 3.6.8), initializing a FinDiff class displays a FutureWarning due to the usage of sequences instead of tuples for array indexing. I found several examples of this in operators.py, most of them in the FinDiff class definition.

Minor refactoring enclosing sequences with tuple() should fix this warning (and possible silent error in future versions of Python).

The full warning reads:

/usr/local/lib/python3.6/site-packages/findiff/findiff.py:242: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use arr[tuple(seq)] instead of arr[seq]. In the future this will be interpreted as an array index, arr[np.array(seq)], which will result either in an error or a different result.
yd[ref_multi_slice] += w * y[off_multi_slice]

multi dimensional coordinates

Hi, is it possible to generate derivatives of multi dimensional coordinates, for example curvilinear (2d) latitude longitude grids? I have tried the following example which does not work:

lat = np.array(( ((50,60), (55,65), (60,70)) ),dtype=float)
lon = np.array(( ((0,180), (0,180), (0,180)) ),dtype=float)

print('lat.shape=',lat.shape)
print('lon.shape=',lon.shape)

d_dlon = FinDiff(1, lon, acc=2)

print(d_dlon)

time = np.array((1,3,5,7), dtype=float)

data = np.array(( (((3,5), (6,2), (4,3)), ((3,5), (6,2), (4,3)), ((3,5), (6,2), (4,3)), ((3,5), (6,2), (4,3))) ),dtype=float)

print('data.shape=',data.shape)

ddata_dlon = d_dlon(data)

print('ddata_dlon=',ddata_dlon)

Higher accuracy derivatives in 3D

I am trying to calculate higher accuracy derivatives in 3D, however it takes extremely long time. Is there any suggestions to solve this issue

offsets = list(product(range(-4,5), repeat=3))

stencil = Stencil(offsets, partials={(1, 0, 0): 1,}, spacings=(1, 1, 1))

print('Accuracy = ', stencil.accuracy)

print('Grad_x')

for i in stencil.values:
    if abs(stencil.values[i]) > 1e-10:
        print( round(stencil.values[i], 8), ' <--> ', i)

pip install error: missing LICENSE file

Hi,
On a clean ubuntu 20.04, python 3.8, I get:

> pip3 install findiff
Collecting findiff
  Downloading findiff-0.8.8.tar.gz (25 kB)
...
Building wheels for collected packages: findiff
  Building wheel for findiff (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /usr/bin/python3 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-ft6pl005/findiff/setup.py'"'"'; __file__='"'"'/tmp/pip-install-ft6pl005/findiff/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-z4hggas4
...
  copying build/lib/findiff/pde.py -> build/bdist.linux-x86_64/wheel/findiff
  copying build/lib/findiff/_version.py -> build/bdist.linux-x86_64/wheel/findiff
  running install_egg_info
  Copying findiff.egg-info to build/bdist.linux-x86_64/wheel/findiff-0.8.8.egg-info
  running install_scripts
  error: [Errno 2] No such file or directory: 'LICENSE'
  ----------------------------------------
  ERROR: Failed building wheel for findiff
  Running setup.py clean for findiff
Failed to build findiff

Reference for verifying coefficient computation algorithm

Given that computing coefficients for finite difference calculations is a mature subject with many different algorithms, is there a reference for where the algorithm used in FinDiff came from so that it can validated against the specification?

Allow the user to specify difference method

Instead of FinDiff using central coefficients whenever possible and switching to backward or forward coefficients if not enough points are available on either side, allow the user to specify a desired method.

Derivatives for a single point in a vector space

I have a vector problem with 5 components.

I would like to calculate a full set of derivatives for a given pair of points. Ideally up to order 4.

The function is numeric and not symbolic.

The step size that is appropriate, I can calculate using the standard h/x0 where h = x0 * sqrt (ulp)
where ulp is the unit of least precision.

For the 4th derivate order, it ties up if values are calculated at -2,-1,0,1 and 2 steps. Based off this https://en.wikipedia.org/wiki/Finite_difference_coefficient

I think I get 4 orders of accurace for first and second. 2 degrees of accuracy for the 3rd and 4th order. That could be changed but that is more than likely to be good enough for my purposes.

I need mixed partial derivatives too. This is to feed into a Taylor expansion. This is for set points in the vector space. A regular grid is not what is needed.

That gives quite a lot of FinDiff objects [780], but easy to create in a loop.

I'm not too worried about efficiency, since the function to be evaluated caches well with standard functools.cache

So here's a test function with just 3 components.

def ff(x, y, z) -> float:
result = x ** 2 + .1 * y * z
print(f"{x:0.4f} {y:0.4f} {z:0.4f} -> {result:0.4f}")
return result

This can be vectorised

fv = np.vectorize(ff, signature="(),(),()->()")

A bit of test code

x, y, z = [np.linspace(0, 1, 4)] * 3

res = fv(x,y,z)

print (res)

gives the right sort of answer

0.0000 0.0000 0.0000 -> 0.0000
0.3333 0.3333 0.3333 -> 0.1222
0.6667 0.6667 0.6667 -> 0.4889
1.0000 1.0000 1.0000 -> 1.1000
[0.0000 0.1222 0.4889 1.1000]

I'm not sure how to proceed.

How do I get a full set of derivatives up to order 4 for the point <1,1,1>?

Thanks

Analytic inversion of Vandermonde matrix

Hi, new fan of this package! :)

I was wondering: At least within the applications I'm looking at, the equation solving performed in L99 of coefs.py (or L89 for symbolic=True) can also be done analytically, because matrix is a Vandermonde matrix, and computing specific elements of its inverse is doable without any matrix inversion (see for example ProofWiki).
Would this be interesting to implement? I noticed that findiff.coefficients becomes unstable at some point (admittedly for quite large values of acc~25).

Thanks for the good work, kind regards!

Non-uniform grid (dim >1)

Hi, great work!

I have been trying the package and I cannot find how to use 'FindDiff' for non-uniforms grids with dimension 2 or higher.
I mean, I see that for FinDiff(i_cord, dcord_or_cord, acc=2), the second index is either d_cord (e.g. dx for 0th-cord, if float) or coordinates (eg. x-values, if array). Therefore in a non-uniform grid, this should be a N-dim array with the ith-coordinate of each cell. However, it only accepts a 1D array, allowing non-uniform grid only in 1 dimension.

Add tests for validating orders of accuracy

So far (v0.2.0) the tests only validate that the differentiation yields correct results for various accuracy orders. However, the scaling behavior, i.e. that the error gets smaller with the corresponding power of the grid spacing, still needs formal tests.

funtions with multiple arguments

I am trying to use this on a function with multiple arguments like:

from findiff import FinDiff
import numpy as np
def f(x, y):
    return 5*x**2 - 5*x + 10*y**2 -10*y

diff = .01
x = np.linspace(-10,0,11)
y = np.linspace(0,10,11)

d_dx = FinDiff(0, diff)

df_dx = d_dx(f)

This gives me "AttributeError: 'function' object has no attribute 'shape'"
Then I tried

df_dx = d_dx(f(x,y))

which produces the result

array([[-1150.],
       [ -850.],
       [ -550.],
       [ -250.],
       [   50.],
       [  350.],
       [  650.],
       [  950.],
       [ 1250.],
       [ 1550.],
       [ 1850.]])

but that is an incorrect result as the values should be from the actual partial derivative

array([[-105.],
       [ -95.],
       [ -85.],
       [ -75.],
       [ -65.],
       [ -55.],
       [ -45.],
       [ -35.],
       [ -25.],
       [ -15.],
       [  -5.]])

Can you help me understand how to use multiple arguments on the function?

Thanks

Coefficients for odd order

I just spent some time trying to figure out what was wrong when I asked findiff.coefficients(deriv=1, acc=...) for odd values of acc. The source code says "This module determines finite difference coefficients for uniform and
non-uniform grids for any desired accuracy order." but then later it it says that it's not for any accuracy order, it's only for even order. I didn't notice that second documentation at first, and there was no error message. Perhaps instead of rounding the integer to an even number, the code can return an error? I don't know what the use cases are for when you want the code to change an odd to an even, so maybe this would mess up established workflows, but as a very casual user, I'd prefer to get an error that tells me to use an even integer.

And out of curiosity, since these formulas do exist for odd order, is it just that there is no demand for them?

Recent release does not accept 0 order

As with in #32, the recent release has an assert checking that the order is positive. 0 order derivatives (that is, do not derive for that dimension) were accepted before.

My suggestion is to change the assert to check only that the order is nonnegative.

(doc) which scheme is chosen for which point

As the derivative of a given numpy array has the same size as the initial array, it could be worth mentioning how the differentiation switches between the backwards/forwards/centered scheme.

Looking at operators.diff() it uses "center" whenever it can apply it, "forward" at the left (low-index) boundary and "backward" at the right (high-index) boundary, but the source code is not that easy to read, and it is not written anywhere in the doc either.

Non-uniform grids in 0.6.0

I don't know how to use non-uniform grids in the new version (0.6.0). All examples (including in this repo) are still using the way 0.5.2 worked.

Also, in the readme, in the non-uniform section

# Define the partial derivative with respect to y, e.g.
d_dy = FinDiff(1, x)

Shouldn't it be FinDiff(1,y)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.