简体   繁体   中英

How to correctly calculate a nonlinear function and plot its graph in Octave?

Goal: Plot the graph using a non-linear function. Function and graph

在此处输入图像描述

在此处输入图像描述

This is my first time working at Octave. To plot the graph, I need to calculate a function in the range Fx (0.1... 10).

I tried to implement this by looping the function through the for loop, writing the results to an array (x-axis - Fn, y-axis - function value), then loading the arrays into the plot() function.

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);

As a result, I get an error about the format of the arrays.

>> 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

In addition to the error, I believe that these tasks are solved in more correct ways, but I did not quite understand what to look for.

Questions:

  1. Did I choose the right way to solve the problem? Are there any more elegant ways?
  2. How can I fix this error?

Thank you!

If I have correctly interpreted what you are trying to do, the following should work. Firstly, you need to use the term-by-term versions of all arithmetic operators that act on Fn. These are the same as the normal operators except preceded by a dot. Next, you need to put Fn equal to a vector containing the x-values of all the points you wish to plot and put Q equal to a vector containing the values of Q for which you want to draw curves. Use a for-loop to loop through the values of Q and plot a single curve in each iteration of the loop. You don't need a loop to plot each curve because Octave will apply your "test" function to the whole Fn vector and return the result as a vector of the same size. To plot the curves on a log axis, use the function "semilogx(x, y)" insetad of "plot(x, y)". To make the plots appear on the same figure, rather than separate ones put "hold on" before the loop and "hold off" afterwards. You used cell arrays instead of vectors in your for-loop, which the plotting functions don't accept. Also, you don't need an explicit return statement in an Octave function.

The following code produces a set of curves that look like the ones in the figure you pasted in your question:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM