Как правильно рассчитать нелинейную функцию и построить ее график в октаве?
Цель: построить график с помощью нелинейной функции. Функция и график
Я впервые работаю в Octave. Чтобы построить график, мне нужно вычислить функцию в диапазоне Fx (0,1 ... 10).
Я попытался реализовать это, пропустив функцию через цикл for, записав результаты в массив (ось x- Fn, ось y- значение функции), а затем загрузив массивы в функцию plot().
Fn = 1
Ln = 5
Q = 0.5
function retval = test (Fn, Ln, Q)
# Fn squared (for common used)
Fn = Fn^2
# Node A + Node B
nodeA = Fn * (Ln - 1)
nodeB = (Ln * Fn - 1)^2 + Fn * (Fn - 1)^2 * (Ln - 1)^2 * Q^2
nodeB = sqrt(nodeB)
# Result
result = nodeA / nodeB
retval = result
return;
endfunction
frequencyArray = {}
gainArray = {}
fCount = 1
gCount = 1
for i = 0:0.5:5
# F
Fn = i
frequencyArray{fCount} = Fn
fCount = fCount + 1
# G
gainArray{gCount} = test(Fn, Ln, Q)
gCount = gCount + 1
end
plot(frequencyArray, gainArray);
В результате я получаю ошибку о формате массивов.
>> plot(frequencyArray, gainArray);
error: invalid value for array property "xdata"
error: __go_line__: unable to create graphics handle
error: called from
__plt__>__plt2vv__ at line 495 column 10
__plt__>__plt2__ at line 242 column 14
__plt__ at line 107 column 18
plot at line 223 column 10
Помимо ошибки, я считаю, что эти задачи решаются более правильными способами, но не совсем понимал, что искать.
Вопросов:
- Правильно ли я выбрал способ решения проблемы? Есть ли более изящные способы?
- Как исправить эту ошибку?
Спасибо!
1 ответ
Если я правильно истолковал то, что вы пытаетесь сделать, следующее должно работать. Во-первых, вам нужно использовать почленные версии всех арифметических операторов, которые действуют на Fn. Это то же самое, что и обычные операторы, за исключением того, что им предшествует точка. Затем вам нужно поставить Fn равным вектору, содержащему значения x всех точек, которые вы хотите построить, и поставить Q равным вектору, содержащему значения Q, для которых вы хотите нарисовать кривые. Используйте цикл for, чтобы перебирать значения Q и строить одну кривую в каждой итерации цикла. Вам не нужен цикл для построения каждой кривой, потому что Octave применит вашу «тестовую» функцию ко всему вектору Fn и вернет результат в виде вектора того же размера. Чтобы построить кривые на логарифмической оси, используйте функцию "semilogx(x, y)" вместо "plot(x, y)". Чтобы графики отображались на одной и той же фигуре, а не на отдельных, поставьте «удержание» перед циклом и «удержание» после него. Вы использовали массивы ячеек вместо векторов в цикле for, которые функции построения графиков не принимают. Кроме того, вам не нужен явный оператор возврата в функции Octave.
Следующий код создает набор кривых, которые выглядят так, как показано на рисунке, который вы вставили в свой вопрос:
Ln = 5
function result = test (Fn, Ln, Q)
# Fn squared (for common used)
Fn = Fn.^2;
# Node A + Node B
nodeA = Fn .* (Ln - 1);
nodeB = (Ln .* Fn .- 1).^2 + Fn .* (Fn .- 1).^2 .* (Ln - 1)^2 * Q^2;
nodeB = sqrt(nodeB);
# Result
result = nodeA ./ nodeB;
endfunction
Fn = linspace(0.1, 10, 500);
Q = [0.1 0.2 0.5 0.8 1 2 5 8 10];
hold on
for q = Q
K = test(Fn, Ln, q);
semilogx(Fn, K);
endfor
hold off