Я довольно новичок в Mathematica. Мне нужно создать 2d массив динамически. Я получил некоторый код на C ++ (Qt), и он выглядит так:
void Wave::getMatrix(int M, int N)
{
int k = -N;
while(k < N+1){
QVector<tsk_type> temp_vec;
for(int i = -N; i < N+1; i++){
tsk_type temp_sum0;
for(int ii = -M; ii < M+1; ii++ ){
temp_sum0 += (getI(i-ii, b)/getY(ii)) * getJ(ii-k,b1,b2);
}
temp_vec[temp_vec.size()-1] = temp_sum0;
if (k == i)
temp_vec[temp_vec.size()-1] -= l;
}
temp_vec.push_back(getD(S)*getI(S-k, b));
main_array.push_back(temp_vec);
k++;
}
}
/
В Mathematica, Я уже написал все функции, которые мне нужны, чтобы составить матрицу системы линейных уравнений, которую я могу решить. Поэтому я использую их, чтобы получить «список» «списков».
Когда я запускаю этот код, это похоже на выполнение чего-либо, но ничего не выводит. Нет даже ошибок.
В чем дело? И как правильно мне это перевести? Кроме того, я предполагаю, что существуют проблемы с переменными List [] и List [[]], так как же мне правильно объявлять динамические списки?
Вот формула
Вот как я перевел код.
(*all globlas definiton is somewhere here*)
k = -Nm;
mainmatrix = List[[]];
While[k < Nm + 1,
rowvalues = List[];
For[i = -Nm, i < Nm + 1, i++,
tempsum;For[j = -M, j < M + 1, j++,
tempsum = tempsum + (getI[i - j, a, b]/getGamma[j]) * getJ[j - k, a1, b1, a2, b]
]
AppendTo[rowvalues, tempsum];
If[k == i, AppendTo[rowvalues, -l], 0]
];AppendTo[rowvalues, getD[S]*getI[S - k, a, b]];
AppendTo[mainmatrix, rowvalues];
k++]
UPD:
все функции и данные
Clear[k, a, b, a1, b1, a2, b2, angle, rho, omega, lambda, u];
(*constants*)
rho = 1800; angle = 0.5; lambda = 3 * 10^9; omega = 1.5 * 10^6; u =
2*10^9;
BS = 1; DS = 1; T = 0.01; l = 0.01; S = 0;
a = 0.002; b = 0.008; a1 = 0.0; b1 = 0.002; a2 = 0.008; b2 = 1.0; M =
7; Nm = 7;
getI[k_ , a_, b_] = Integrate[E^(I ((2 Pi)/l) k t), {t, a, b}]
getJ[k_ , a1_, b1_, a2_, b2_] = getI[k, a1, b1] + getI[k, a2, b2]
getL[n_] = angle + (2 Pi n/l);
getK[j_] = If[j == 1,
answer = Sqrt[(rho*omega^2)/(lambda + 2*u)],
answer = Sqrt[(rho*omega^2)/(u)]
]; answergetBeta[j_, n_] = If[(getL[n] > getK[j]),
beta = 0 + i*(getL[n]* getL[n] * getK[j]*getK[j]),
beta = (getL[n]* getL[n] * getK[j]*getK[j]) + i*0]; betagetGamma[n_] = (((getL[n]*getL[n])/(getBeta[1, n])) + getBeta[2, n]);
getD[s_] = ((2 getL[s] * BS * getBeta[1, s] + DS) / (getL[s] * getL[s]
+ getBeta[1, s]*getBeta[2, s] ));
Я не знаю, все ли это правильно, но это намного ближе.
In[1]:= n = 2; M = 2; (*dummy values for this example code*)
getGamma[i_] := RandomReal[]; (* dummy functions for this example code*)
getI[i_, a_, b_] := RandomReal[];
getJ[j_, a1_, b1_, a2_, b_] := RandomReal[];
getD[S_] := RandomReal[];
k = -n;(*N is a predefined Mathematica function and can't be a variable name*)
mainmatrix = List[];
While[k < n+1,
rowvalues = List[];
For[i = -n, i < n+1, i++,
AppendTo[rowvalues, getGamma[i]];
tempsum = 0; (*I think you wanted this initialized here*)
For[j = -M, j < M+1, j++,
tempsum += getI[i-j, a, b]/getGamma[j]*getJ[j-k, a1, b1, a2, b]
];
AppendTo[rowvalues, tempsum];
If[k == i, AppendTo[rowvalues, -l]] (*no "else" needed if else does nothing*)
];
AppendTo[rowvalues, getD[S]*getI[S-k, a, b]];
AppendTo[mainmatrix, rowvalues];
k++
];
mainmatrix (*display result*)
Out[8]= {{0.135926, 0.894736, -l, 0.699663, 1.91913, 0.702762,
28.4151, 0.730135, 19.6996, 0.583233, 21.2716, 0.398302},
{0.572982, 3.18868, 0.495877, 1.50816, -l, 0.686158,
68.9278, 0.860748, 3.91516, 0.751198, 8.43028, 0.223722},
{0.931385, 3.16432, 0.931398, 5.10999, 0.241402, 4.54042,
-l, 0.825971, 2.99634, 0.280342, 3.20253, 0.0731139},
{0.294396, 7.99678, 0.456691, 4.74995, 0.308643, 1.72647,
0.883139, 5.64323, -l, 0.755833, 4.00285, 0.127718},
{0.790168, 0.751702, 0.744966, 2.40172, 0.537242, 3.08838,
0.105972, 1.09212, 0.412047, 12.2475, -l, 0.397379}}
Когда приходит время использовать матричный результат, понимают, что все матричные и векторные индексы Mathematica равны 1..n, а не 0..n-1 и не -n..n. Таким образом, вам придется добавить смещение к любым индексам матрицы при изменении кода, чтобы использовать полученную матрицу.
Вы можете, если это имеет значение для вас, заменить
tempsum = 0;(*I think you wanted this initialized here*)
For[j = -M, j < M + 1, j++,
tempsum += getI[i - j, a, b]/getGamma[j]*getJ[j - k, a1, b1, a2, b]];
AppendTo[rowvalues, tempsum];
с
AppendTo[rowvalues,Sum[getI[i-j,a,b]/getGamma[j]*getJ[j-k,a1,b1,a2,b],{j,-M,M}]];
Это могло бы, например, избежать исходной ошибки не инициализации tempsum.
Существуют и другие фрагменты кода, которые можно переписать для использования функций Mathematica, но вы должны решить, будет это хорошо или плохо.
здесь вы идете без всего грязного использования AppendTo
mainmatrix = Table[
Insert[
Append[
Flatten@Table[ {
getGamma[i],
Sum[getI[i - j, a, b]/getGamma[j] getJ[j - k, a1, b1, a2, b],
{j, -M, M}] },
{i, -n, n}] ,
getD[S]*getI[S - k, a, b]],
-l,2 (k + n + 1) + 1 ],
{k, -n, n}];
Редактировать:
при дальнейшем изучении кажется, что код C ++ на самом деле выбрасывает getY(i)
значение, которое он помещает в temp_vec, результат еще проще:
mainmatrix = Table[
Append[
Table[ Sum[getI[i - j, a, b]/
getGamma[j] getJ[j - k, a1, b1, a2, b]-l Boole[i == k],
{j, -M, M}] , {i, -n, n}] ,
getD[S]*getI[S - k, a, b]], {k, -n, n}];
еще одна форма, которая на самом деле начинает напоминать ваше уравнение ..
lhs = Table[Sum[getI[i - j, a, b]/
getGamma[j] getJ[j - k, a1, b1, a2, b], {j, -M, M}],
{k, -n, n}, {i, -n, n}] - l IdentityMatrix[2 n + 1];
rhs = Table[ getD[S]*getI[S - k, a, b] , {k, -n, n}];
mainmatrix= Join[lhs, Transpose[{rhs}], 2]