Message Boards Message Boards

LogLinearPlot for Bode too slow

Posted 10 years ago

Hi to everybody

I am trying to plot some bode plots, but want to use the LogLinearPlot command (the BodePlot is yet too obscure to me, sorry).

My impedance matrices are rather complex in the sense that they are based on 7x7 matrices and that it uses complex numbers. Once I get the impedance expressions and its corresponding admittance I define some (transfer) functions. But it takes age to plot them. And to plot the ARG of the function is even worse.

I have added dots after all the numbers to force the use of floating point numbers and I have the feeling that Mathematica makes too many recursions to plot the functions. I have added a limit to PlotPoints and MaxRecursion, but without too much success.

I have also tried to find the roots of the admittance function using NDSolve, but this take seven longer (not shown in the attached notebook).

I cannot believe that this is the normal speed of Mathematica, I am sure that I am doing something wrong.

I am new and will be probably doing a lot of mistakes.

Can somebody give me some useful hints?

Thank you very much.

Stefan

P.D. I have attached the notebook.

Attachments:
POSTED BY: Stefan S
9 Replies
Posted 10 years ago

Hi to everybody

I finally found a solution to make plots much faster.

First I try to use all four cores of my computer (Parallelize) and I try to not increase the numb rod points above a reasonable number (could there be a bug in the LogPlot commands of Mathematica?). I found out that Mathematica tries to count with step one when constructing a table although I wanted later on to represent it on a Log scale (this makes sense to me, as Mathematica does not know what I am going to do with the table). But this was very, very slow. Could this be bug in the LogPlot functions and that's why it is solo slow?

Any how, here is my proposal which fastens the BodePlot representation really a lot.

    ListLogLinearPlot[
     Parallelize[
      Table[{10^i,Part[20 Log10[Abs[function[2. PiN I 10^i]]], 1]}, {i, 2, 5,0.01}]], 
PlotLegends -> {"function"}, Joined -> True, GridLines -> Automatic, GridLinesStyle -> Directive[GrayLevel[0.8]], Frame -> True]
    ListLogLinearPlot[
     Parallelize[
      Table[{10^i, Part[DegN Arg[function[2. PiN I 10^i]], 1]}, {i, 2, 5, 0.01}]], 
PlotLegends -> {"function"}, PlotRange -> {Automatic, {-180, 180}}, Joined -> True, GridLines -> Automatic, GridLinesStyle -> Directive[GrayLevel[0.8]], Frame -> True]

The number of points can be increased with the step when constructing the table (here 0.01)

One ListPlot is for the magnitude and the other for the phase (the phase was even worse to plot with the normal LogLinearPlot.

Good luck and thank you to all for your help.

Stefan

POSTED BY: Stefan S

This requires some elaborated work. The basic idea is to make all function "algebraically-ready" before they are inserted into the plot function. Here is an example:

f[x] = Det[Inverse[{{1,2},{3,x}}]]
g[x] := Det[Inverse[{{1,2},{3,x}}]]
Plot[f[x],{x,100,200}]
Plot[g[x],{x,100,200}]

The first plot should be significantly faster than the second because f has the rhs evaluated already during definition while the g looks for the inversion first and compute the determination. Check the downvalues of f and g respectively:

downvalues

Use this idea to precompute functions. For example, Yiidealtotal is thus converted to a rational function before it is inserted into the plot funciton:

rational_YiidealTotal

Some notes about the optimization: Numeric computation may yield imaginary residues in coefficients, which are difficult for simplification. You want to take a look Simplify[Chop[#]]& function to knock down the complicated expressions.

To simplify a list of function, you can choose the parallel function to accelerate. For Yi[x]:

Yi[s_] = ParallelMap[Simplify[Chop[#]] &, nciM.Inverse[ZLRC[s]].nci];

Use the attached notebook to take a look at the details.

PS I use high precision numbers throughout the notebook to handle the large coefficients.

Attachments:
POSTED BY: Shenghui Yang
Posted 10 years ago

Thank your very much Shenghui!

I had the feeling that it has something to do with precomputing the function earlier instead of inverting at each point the plot takes place. I have a lot to learn!

I will go through your improved file and your examples immediately.

Thank you again for your help.

Stefan

POSTED BY: Stefan S
Posted 10 years ago

Hi Shenghui

I have been playing around and it looks very promising. The only drawback I have found is that the curves are different from the slow ones I got. It's probably a precision problem and/or the Chop function. I will continue researching on the item to see if I can improve the curves.

I will try also to force ListPlot to first substitute the f value and then compute the Inverse matrix. This could be faster, I hope.

Stefan

POSTED BY: Stefan S

Yiideal definitely takes huge amount time because it tries to inverse a matrix thousands of time across the plot domain.

Yiideal[s_] := nciM.Inverse[ZLRCideal[s]].nci

With improved code you can nailed the same plot in 0.08 sec:

improved

POSTED BY: Shenghui Yang
Posted 10 years ago

Dear Shenghui

I see that the code can be improved, but how?

Could you please explain how to do it? What should I take care off?

Thank you very much.

Stefan

POSTED BY: Stefan S
Posted 10 years ago

Without seeing exactly what you did that allowed that plot to be instantaneously changed it is impossible to respond. There is an enormous amount going on behind the curtain and perhaps with the example then someone better than I can see a way to speed your plotting up.

I suppose one alternative is to buy a PC that is (really literally) 100 times faster than the one you have, but that probably isn't practical.

POSTED BY: Bill Simpson
Posted 10 years ago

A count of the number of constants, operators and variables in just one of the items you want to plot

In[40]:= LeafCount[20 Log10[Abs[ Yiideal[2. Pi I f]]]]

Out[40]= 547063

I tried an assortment of simple things, like replacing 0.+0.I by 0, etc. and, while that removed a few tens of thousands of redundant terms, nothing made a significant dent in the half million items needed to be evaluated hundreds or likely thousands of times to make each plot.

When the function to plot is expensive I have sometimes been able to significantly speed things up by constructing a Table of equally spaced evaluations (Log spaced in this case) and then do a ListPlot with Joined->True to reduce the number of evaluations by sometimes an order of magnitude with modest reduction in the publication quality of the graph. Unfortunately with the appearance of your plots I don't think this will likely be acceptable.

POSTED BY: Bill Simpson
Posted 10 years ago

Thank you Bill. But very discouraging. So it seems that the problem is that the function is really very complex. The funny think is that I have been able to apply Manipulate to the Yiideal(s) function with good results and just moving the cursor changes the shape of the plot almost instantaneously.

Stefan

POSTED BY: Stefan S
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract