Как правильно рассчитать нелинейную функцию и построить ее график в октаве?

Цель: построить график с помощью нелинейной функции. Функция и график

Я впервые работаю в 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. Правильно ли я выбрал способ решения проблемы? Есть ли более изящные способы?
  2. Как исправить эту ошибку?

Спасибо!

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
Другие вопросы по тегам