Mac Dude

1566 Reputation

17 Badges

12 years, 348 days

MaplePrimes Activity


These are answers submitted by Mac Dude

To make this work I defined the fitting function:

func:=(a,b,x) -> a*exp(b*(x));

and specified the fit parameters and initial values:

regE := Statistics:-NonlinearFit(func(a,b,xx),year,population,xx,\
                                 parameternames=[a,b],\
                                 initialvalues=[a=6E-11,b=0.02]);
                                                        
   regE := 7.99391422845879 10^-15    exp(0.0237283441933794 xx)

You can see that your problem is quite ill-conditioned and in fact the fit has trouble getting there (my initial values are from the output of NonlinearFit when it ran out of iterations). Plotting fit & data show the fit being fairly bad. So I would not really trust it.

I append the worksheet I used. It's a bit clunky, but refining it (and making it work with your other function) is left as an exercise.

Mac Dude

NonlinFit.mw

In your assignment to Constraints you use x0(t).

Then you asign a solution to x0[1] in eq (3.2). So x0 has now become a table for Maple, and the next time you use x0 (even as x0(t)) Maple will use the table property of x0 and produce a somewhat nonsensical expression.

I don't know exactly what this should be but that is where it looks like the error is.

M.D.

 

The way you pose the question implies that you have a data set with pairs (like (x,y) ) representing each point.

First: interpolation and curve fitting are two different things. An interpolating function goes through each data point and "fills in the gaps." A fitted curve does in general not go through each data point.

If curve fitting is what you want, then you have to decide what function to use. In some cases the function is given as it represents some model of an underlying process that generated the data in the first place. If your 101 points come from such a process that is the direction you have to go: find the function describing the process and fit that. On the other hand, sometimes one just wants to parametrize trends in a data set with a convenient function. In this case you can either fit a polynomial with the minimum order needed to fit the features you want to be preserved, or some other function that represents the general trend of the data. Polynomials tend to get wiggly at high order so if the dependence requires a high order you are unlikely to get a nice result.

One trick to decide whether a function does what you want is to transform your data using the chosen function to new variables in which the data should be linear. This can be simpliy the inverse, e.g. log(y) vs x, if an exponential function is to be tested,  but can also a bit more complicated involving transforming both the dependent and the independent parts of the data. If you can linearize your data in this way, fitting the function should produce a decent result.

To go further you will need to upload a sheet with your attempts so far and the data set. I should say right away though that I may not have the time to do much work on this.

M.D.

You need to use := for the assignments inside the loop.

Also, I am not sure about "print*w". Looks wrong to me. I'd write print(w). Also, terminate the print with a ;

Last not least, without an explicit return the procedure returns the last evaluated ecpression. Seems to me that should be "i+1". Not sure that is what you want.

M.D.

Wrap the whole expression (Re(...)) in an evalc statement and you get the result without any of the assumptions.

M.D.

The impedance of a parallel RLC circuit is

(never mind the subscripts). Here I is the imaginary unit (Maple's convention) and omega is the angular frequency, omega=2*Pi*f. You can get amplitude and phase of that by using (note the evalc wrapped around the abs  and argument functions; needed to avoid Maple just echoing the input):

evalc(abs(Z);

 

and evalc(argument(Z));

Any questions?

Avoiding the restart and unwith have already been mentioned.

Personally, to avoid running into name-space issues (which is likely at the root of your problems) I often use the fully qualified names ("long form"); i.e. Student:-VectorCalculus:-Norm etc. Lots of typing but less debugging :-).

On occasion I have made my life easier by assigning the package name to a short variable, e.g. VC:=Student:-VectorCalculus and MC:=Student:-MultivariateCalculus, and then using MC:-AreParallel() and VC:-Norm(). I am fairly certain this avoids name-space pollution but you would have to test whether this works as intended in your case as the package does get loaded at first use.

I hope this helps,

M.D.

I wonder what you mean by VectorCalculus:-Jacobian() not accepting functions. The Jacobian of course is the matrix of differentials of a vectorfunction F against its arguments. But you know that.

If your arguments are themselves functions, however, then your comment is understandable. In that case you may want to consider freeze and thaw, as in

f:=x -> 1/x;
diff(f(g(y)),g(y)); # fails
thaw(diff(subs(g(y)=freeze(g(y)),f(g(y))),freeze(g(y)))); # succeeds

with obvious (if messy) extension to longer vectors. Reading the docs on freeze, thaw and the related frontend is worthwhile (albeit somethat tough reading).

Mac Dude

 

First, Maple's "else if" keyword is "elif". As written this looks to Maple as an endless nesting of if statements with too few end if statements.

Once you replace all your else if statements with elif, Maple complains about the "end do" in the "if" statements (twice). You need to replace these with "break". It is not good programming style to use "break", and you need to worry about which loop you are breaking out of.

At that time your procedure compiles without error. I did not check the numerics.

Mac Dude.

I'd use freeze and thaw:

f2 := (diff(y(a, b), a)-(-(1/2)*x-1/2+(1/2)*sqrt(-3*x^2-2*x-3))/x^2)*(diff(y(a, b), b)-(-(1/2)*x-1/2-(1/2)*sqrt(-3*x^2-2*x-3))/x^2);

thaw(collect(subs(diff(y(a,b),a)*diff(y(a,b),b)=freeze(diff(y(a,b),a)*diff(y(a,b),b)),expand(f2)),[diff(y(a,b),a),diff(y(a,b),b),freeze(diff(y(a,b),a)*diff(y(a,b),b))]));

What this does is to "freeze" the product of the differentials (i.e. make it appear like an atomic name to Maple), do the collecting including of the frozen variable, and then "thawing" the result meaning the frozen expression becomes a normal one again. Similar to acer's solution, but freeze/thaw are somewhat less error prone, IMHO. Do note that in general this works best all in one line as I did it; I have had trouble when splitting such a construct across several lines and using intermediate variables.

Clearly, rlopez' solution is the preferred way if/when it works. But if not, freeze/thaw have their place. Check the Help on this pair of Maple operations.

M.D.

 

Your second plot using Maple's plot command has many intermediate points that describe a linear line from point to point (at integer values of the horiz. axis). So the log plot puts them correctly; a linear straight line becomes a curved line when plotted on a log scale. You can see this by selecting the plot and then setting the point probe to "nearest datum" in the Plot:Probe Info menu item.

Your first plot only plots the 5 points given. Maple linearly interpolates even when plotting on a log scale. Personally I find that a bit of a questionable thing to do.

You use the very low level PLOT command for the first curve. If you use plots:-display you can use all the options available for 2-d plots. Check Help for plot/details and plot/options.

Mac Dude.

Joe Riel has written an elisp package for Emacs called maplev.el. It has very nice indentations and also syntax coloring. Google for maplev to find the latest version.

It does mean that you need to write your sheets in Emacs and then read them into Maple using read("..."). For maintaining large packages I find this much more convenient than using the Maple GUI.

I am not aware of any code indentation in Maple itself other than by hand.

M.D.

I did something similar a while back for a simulation code. I upload the code snippet that does this here. It is not exactly what you want to do, but maybe it gives you a starting point. Note that this is an extract from a much larger package so you will need to provide the necessary context. As a minimum you need to wrap the code into a module so the local declarations work. I don't necessarily think this code works for you but it should give you an idea what is involved.  Look at the comments in the code. M.D.

Colored_random_numbers.mw

Fitting the frequency of a sine or cosine function is a quite ill-defined problem. You can have success in a case like yours if you use Statistics:-NonlinearFit with a starting value (or guess) that is close to being right (like the one you show at the bottom of your post). I don't see where you use a starting point with Fit, so with no guidance it is probably getting stuck in a local minimum, or maybe it gets no useable gradient to find the optimum. Note that even with decent starting values extracting the right frequency is not always easy and successfull.

You can of course get a starting frequency from an FFT analysis of the data.

As for the phase, I'd fit cosine and sine components and get the phase from that.

I have had some success by expanding such problems to first order in frequency, thus refining the frequency getting from an FFT. A better approach may be using methods like NAFF to get a more accurate estimate of the frequency.

Mac Dude

 

The frequencies you will get from a Fourier analysis of the data with DiscreteTransforms[Fourier]. I did a quick analysis using your data set, here is the plot:

 

The low frequency is not resolved as you have not enough data for that; the peak around 15 presumably is your fast sinewave. I did not scale for the time units/data points as I am too lazy. And the X label does not look not quite right either... anyway, you 'll have to figure that yourself. Note that there are much more sophisticated and accurate methods to extract frequencies from data like yours, methods like NAFF and others. Read up on Fourier transforms and these methods if you are not famliar with them. Also note that the above is a power spectrum.

I have never had success in extracting phases from the FFT so I use a fitting procedure to get these:

First, fit the expression C*cos(2*Pi*nu*t) + S*sin(2*Pi*nu*t) to the data where nu is the low frequency (I'd say close to 1/1700). Since you know nu you can do this with a linear fit and solve for S and C. You may be able to fit nu as well if you start from a good estimate.

Once you have this you can subtract the wave thus parametrized from the data and now have a data set with the high frequency components dominating. You now repeat the procedure but with nu being the high frequency (near 1/100).

The sum of these should describe your time-domain data reasonably well.

If you have more frequencies they may reveal themselves in the spectrum (the Fourier analysis). But your data have some noise so you have to be careful not to latch on to spurious peaks in the spectrum.

Hope this helps,

M.D.

Edit: Added spectrum & slightly expanded the prose.

First 7 8 9 10 11 12 13 Last Page 9 of 20