Создать шаблон для производной I-го порядка в D-измерении

Я пытаюсь разработать код конечного элемента, где мне нужно вычислить частные производные в размерности d. В конечном элементе базисная функция N (x, y, z)=N(x)N(y)N (z), поэтому производные первого порядка:

N(x)'N(y)N(z) N(x)N(y)'N(z) N(x)N(y)N(z)'

производные второго порядка

N(x)''N(y)N(z) N(x)'N(y)'N(z) N(x)'N(y)N(z)' N(x)N(y)''N(z) N(x)N(y)N(z)' N(x)N(y)N(z)''

Я хочу иметь функции с input (i, d), чтобы сказать мне эти шаблоны в таблице ниже:

Введите описание изображения здесь

Я думаю, что должен быть простой алгоритм для реализации этой цели. Может кто-то мне поможет? тнх

3 ответа

  1. Рассмотрим шаблон для i‘ — й производной как базисные i+1целые числа. Появляются приятные последовательности. Например, в двумерном случае они

    0
    2, 1
    6, 4, 2
    12, 9, 6, 3
    20, 16, 12, 8, 4
    

    так далее.

  2. Это можно решить с помощью вложенных циклов:

    int * part_deriv(int i, int d){
        int *res;
        int *curr;
        int num_el = fact(i+d-1) / ( fact(i) * fact(d-1) ); //fact() is the factorial function
        int el_size = d*sizeof(int);
        int el;
    
        res = calloc(num_el,el_size);
        curr = calloc(d,sizeof(int));
        *curr = i;
        memcpy(res,curr,el_size); //put the first element in the array
    
        el = 0;
        while(el<num_el){
           if(*curr != 0){
               for( d_idx = 1 ; d_idx<d ; d_idx++, *cur++){
                  *curr--; // "move" one derivative from the first variable to 'd_idx' variable
                  *(curr+d_idx)++;
                  el++;
                  memcpy(res+(el*el_size),curr,el_size); //put the element in the array
               }
               *curr--;
           } else{
               break; //shouldn't be reached, but added to be sure
           }
        }
        return res;
    }
    

    Я не совсем понял, как вы хотите вывести результат, поэтому вы можете разобрать массив, который я вывел в блоках d.

  3. Я понял это рекурсивно, вызвав функцию.

    #include <vector>
    #include <iostream>
    using namespace std;
    
    
    void func (int d, int i, vector<int> &k, int n, int start, vector<vector<int>> &a){
        if (n==i)
        {
            vector<int> m;
            int it=0;
                for(int it1=0;it1<d;++it1){
                    int amount=0;
                    while(find(k.begin(),k.end(),it)!= k.end()){
                        amount++;
                        it++;
                    }
                    m.push_back(amount);
                    it++;
                }
            a.push_back(m);
        }
        else{
            for(int jj=start;jj<d+i-(i-n);++jj){
                k[n]=jj;
                func(d,i,k,n+1,jj+1, a
                     );
            }
        }
    }
    vector<vector<int>> test(int d, int i){
        vector<int> kk(i);
        vector<vector<int>> a;
        func(d,i,kk,0,0, a);
        return a;
    }
    int main(){
        auto f = test(4,2);
        for(auto it1=f.begin();it1!=f.end();++it1){
            for(auto it2= it1->begin();it2!=it1->end();++it2)
                cout<<*it2<<" ";
             cout<<endl;
        }
    
    }
    

    Вот мой результат для i=2, d=4:

    2 0 0 0 
    1 1 0 0 
    1 0 1 0 
    1 0 0 1 
    0 2 0 0 
    0 1 1 0 
    0 1 0 1 
    0 0 2 0 
    0 0 1 1 
    0 0 0 2