Russian Qt Forum

Программирование => Алгоритмы => Тема начата: kuzulis от Апрель 23, 2019, 14:24



Название: [Решено]Дискретный оператор Лапласа и числовой градиент.
Отправлено: kuzulis от Апрель 23, 2019, 14:24
Всем привет,

мож кто сталкивался... Видел/использовал кто какую-нить опен-сорс библиотеку в которой есть аналоги Matlab-овских ф-й:

* del2 (https://www.mathworks.com/help/matlab/ref/del2.html#bt1j9e4-2)
* gradient (https://www.mathworks.com/help/matlab/ref/gradient.html)

нужны преобразования в "реальном времени" для размерности 1-D.

Для дискретного лапласа "надыбал" эти  (https://people.sc.fsu.edu/~jburkardt/c_src/laplacian/laplacian.c)сорцы.

Код:
double *l1pp_apply ( int n, double h, double u[] )

/******************************************************************************/
/*
  Purpose:

    L1PP_APPLY applies the 1D PP Laplacian to a vector.

  Discussion:

    The N grid points are assumed to be evenly spaced by H.

    For N = 5, the discrete Laplacian with periodic boundary conditions
    on [0,6] has the matrix form L:

       2 -1  0  0 -1
      -1  2 -1  0  0
       0 -1  2 -1  0
       0  0 -1  2 -1
      -1  0  0 -1  2

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    30 October 2013

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of points.
    N must be at least 3.

    Input, double H, the spacing between points.

    Input, double U[N], the value at each point.

    Output, double L1PP_APPLY[N], the Laplacian evaluated at each point.
*/
{
  int i;
  double *lu;

  if ( n < 3 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "L1PP_APPLY - Fatal error!\n" );
    fprintf ( stderr, "  N < 3.\n" );
    exit ( 1 );
  }

  lu = ( double * ) malloc ( n * sizeof ( double ) );

  i = 0;
  lu[i] = ( - u[n-1] + 2.0 * u[i] - u[i+1] ) / h / h;
  for ( i = 1; i < n - 1; i++ )
  {
    lu[i] = ( - u[i-1] + 2.0 * u[i] - u[i+1] ) / h / h;
  }
  i = n - 1;
  lu[i] = ( - u[i-1] + 2.0 * u[i] - u[0] ) / h / h;

  return lu;
}
/******************************************************************************/

вроде это что-то похоже на то что нужно, судя по этой доке (https://people.sc.fsu.edu/~jburkardt/f_src/laplacian/laplacian.html).

Но непонятно одно: в качестве параметра u[] я должен "занести" весь исходный массив точек?
А что делать, если у меня эти точки добавляются по-очереди по одной штуке в "рантайме" (т.е. мне надо посчитать этот Лапласиан для каждой новой точки)?

ЗЫ: Я с высшей математикой уже давно не дружу и тяжко заново учиться с нуля...   Какая-то жесть...  :(


Название: Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: m_ax от Апрель 23, 2019, 15:24
Цитировать
Но непонятно одно: в качестве параметра u[] я должен "занести" весь исходный массив точек?
Необязательно. Лапласьян в 1D - это просто вторая производная. В дискретном случае вторая производная в точке i определяется также и значениеми функций в соседних ближайших точках:
f''(i) = (-f(i+dx) + 2*f(i) - f(i-dx))/(dx*dx)

Аналогично и с градиентом (градиент - это вектор)
grad f(i) = (f(i+dx) - f(i-dx))/(2*dx)


Название: Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: kuzulis от Апрель 23, 2019, 16:00
Оххх.. Спасибо тебе огромное...  :)

А минимальный dx для дискретных точек равен 1?


Название: Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: m_ax от Апрель 23, 2019, 17:32
Оххх.. Спасибо тебе огромное...  :)

А минимальный dx для дискретных точек равен 1?
Да. Это расстояние между двумя ближайшими точками)


Название: Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: kuzulis от Апрель 23, 2019, 17:59
Цитировать
Лапласьян в 1D - это просто вторая производная.

Что-то не пойму одну вещь: а почему в лапласиане и во второй производной тогда формулы немного разные? Например, знак '-' немного по-другому применяется.

Например, вторая производная считается так: y1'' = (y2 - 2*y1 + y0) / h^2 (взято отсюда  (http://portal.tpu.ru:7777/SHARED/l/LOPATKIN/Students/DG/7-Differentiation.pdf)и прочих других)

но, лапласиан считается так: y1'' = (-y2 + 2*y1 - y0) / h^2

в чем фишка то, если ты говоришь, что лапласиан - это вторая производная?


Название: Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: m_ax от Апрель 23, 2019, 18:27
Цитировать
но, лапласиан считается так: y1'' = (-y2 + 2*y1 - y0) / h^2
Да, ошибка в знаке.

Ниже приатачил вывод:


Название: [Решено]Re: Дискретный оператор Лапласа и числовой градиент.
Отправлено: kuzulis от Апрель 23, 2019, 18:51
Ахх. спасибо..