Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More stable algorithm to calculate zeros of spherical hankel function #152

Merged
merged 2 commits into from
Aug 14, 2017

Conversation

fietew
Copy link
Member

@fietew fietew commented Jun 23, 2017

Follow up on #71:

Based on the publication of @narahahn and @spors.

This is basically a port of a scipy routine.

@narahahn: Could you try out some parametrisation and check, if it is working as expected?

@fietew
Copy link
Member Author

fietew commented Jun 23, 2017

@hagenw: Is it okay to remove the other methods?

@hagenw
Copy link
Member

hagenw commented Jun 26, 2017

The old version of the function returned z and p both as column vectors. Your new implementation returns z as row vector and p as column vector. Is this desired or a bug?

If the new method works better than the old ones, I see no big deal in replacing them as all our methods we implemented so far were buggy.

@hagenw
Copy link
Member

hagenw commented Jul 6, 2017

Is the code ready for me to have a look at it?

It would be cool if you could add a test function for this, maybe doing something like the figures in #57 for example those two or Figure 3 in @narahahn publication

@fietew
Copy link
Member Author

fietew commented Jul 6, 2017

It is ready. I will add a test function.

@hagenw
Copy link
Member

hagenw commented Jul 6, 2017

The test function seems to work ok under Octave, but I had to disable the legend as it covered the whole figure. I guess you have split it to six different subplots in order to not have to many overlapping points, or are the subplots showing different things?
For me they looked very similar, here is the first one of them, I guess this is the desired result?
sphbessel_zeros

@hagenw
Copy link
Member

hagenw commented Jul 6, 2017

I was looking to update the reference as the Campos and Calderón paper was published in 2012, see http://doi.org/10.1155/2012/873078
The problem is that they reformulated some of their equations and I was not able to fit them easily to the ones in https://arxiv.org/pdf/1105.0957.pdf, which should be the paper you referenced. Could you have a look at it and propose if we should stay with the arxiv version or switch to the other one?
I would then do the update to the comments.

I'm also wondering if we should add a link to the scipy routine as you used it as a template.

Otherwise, I'm really happy that this seems to be finally solved as it bothered me since the first version that included NFC-HOA.

@fietew
Copy link
Member Author

fietew commented Jul 7, 2017

The test function seems to work ok under Octave, but I had to disable the legend as it covered the whole figure. I guess you have split it to six different subplots in order to not have to many overlapping points, or are the subplots showing different things?

Each subplot shows a subset of orders. Unfortunately the colors are missing in octave. The graphs shouldn't be all blue, but the automatic coloring is a MATLAB feature, I guess

For me they looked very similar, here is the first one of them, I guess this is the desired result?

Yes, the result is as expected.

I was looking to update the reference as the Campos and Calderón paper was published in 2012, see http://doi.org/10.1155/2012/873078
The problem is that they reformulated some of their equations and I was not able to fit them easily to the ones in https://arxiv.org/pdf/1105.0957.pdf, which should be the paper you referenced. Could you have a look at it and propose if we should stay with the arxiv version or switch to the other one?
I would then do the update to the comments.

Yes, I also had a look at the journal paper, which covers a more generalised problem and is harder to understand. I would stay with arxiv version since the formulas in the campos_zeros correspond directly to equations in the paper.

I'm also wondering if we should add a link to the scipy routine as you used it as a template.

Yes, that's a good idea.

@hagenw
Copy link
Member

hagenw commented Jul 7, 2017

Ok, I updated the references accordingly.

For the test function, could you maybe send me a screen shot of the Matlab result, that I can try to get the same with Octave.

% Zeros of nth-order ordinary Bessel polynomial are the same as for
% exp(1/x)*K_{n+0.5}(1/x), where K_v is the modified Bessel function of second
% kind. We, hence, define the target function and its first derivative as
f = @(x) besselk(order+0.5, 1./x, 1); % modified Bessel function scaled by exp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the comment % modified Bessel function scaled by exp as it my lead a user to expect the exp() function to be part of that line. In addition, I think the comment provided before is sufficient.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while, to figure out that besselk(nu, x, 1) is equal to besselk(nu,x)*exp(x). This is why I added this comment. But if it misleading, we can remove it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a little bit confused by it.
Maybe it helps if we state explicitly the equation in the first comment. Something like

% Zeros of nth-order ordinary Bessel polynomial ... are the same as for modified
% Bessel function of second kind K_v:
% exp(1/x) * K_{n+0.5}(1/x) = ...
% Hence, we define the target function and its first derivative as

Where you have to fill the ... part. Is it also second kind and then Y?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you help to fill the ... please.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://en.wikipedia.org/wiki/Bessel_polynomials#Definition_in_terms_of_Bessel_functions
the nth-order ordinary bessel polynomial is denoted by y_n, which is also the spherical Neumann function in our nomenclature. I would suggest:

% Zeros of nth-order ordinary Bessel polynomial y_n are the same as for 
% the exponentially scaled modified Bessel function of second kind K_v:
% \sqrt{2pi/x} * exp(1/x) * K_{n+0.5}(1/x) = y_n
% Hence, we define the target function and its first derivative as

@hagenw
Copy link
Member

hagenw commented Jul 7, 2017

I added a numerical test case as well for the order 1, 10, and 100 comparing to the results from the python code. This is not perfect as the outcome depends on the ordering of the zeros in the resulting vector, which can differ for different calculation methods, but I thought it is still better than nothing.

B(n+1) = factorial(2*order-n)/(factorial(order-n)*factorial(n)*2^(order-n));

function x = newton(f,fp,x0,TOL,MAXITER)
% Newton-Rapheson method for approximation of a single root
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where comes this implementation from?
When I'm looking at scipy's newton implementation it looks a lot more complicated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scipy implementation does handle many special cases and has some extensions. Here, the most simple version of the Newton-Rapheson method is implemented.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, I found also in the scipy version. Then maybe the easiest thing is to add not a link to the function header, but simply go with the current help text for newton().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't follow you. What do you want me to do?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing :)
Just a confirmation that it is fine to not add a reference link to the scipy code for the Newton method.

@hagenw
Copy link
Member

hagenw commented Jul 7, 2017

I also did a NFC-HOA calculation in order to compare with Hahn and Spors (2017) Fig. 8:

conf = SFS_config;
conf.nfchoa.order = 30;
sound_field_imp_nfchoa([-2 2],[-2 2],0,[1.5 1.5 0],'ps',1/conf.c,conf)

nfchoa_n30

conf.nfchoa.order = 120;
sound_field_imp_nfchoa([-2 2],[-2 2],0,[1.5 1.5 0],'ps',1/conf.c,conf)

nfchoa_n120

It looks very similar, but we have the different of that prominent circular contribution which is not part of the plot in the paper. If I remember correctly we had that discussion already somewhere else, hadn't we?
Is this due to the inclusion/exclusion of the lowest order?

@fietew
Copy link
Member Author

fietew commented Jul 8, 2017

For the test function, could you maybe send me a screen shot of the Matlab result, that I can try to get the same with Octave.

I am pretty sure, that the coloring is not relevant, but I will explicitly define the colors in the script and send you a screen shot.

Is this due to the inclusion/exclusion of the lowest order?

What are you referring to? What is the lowest order? What is included/excluded?

@fietew
Copy link
Member Author

fietew commented Jul 10, 2017

The plot under MATLAB R2015a:
zeros

@hagenw
Copy link
Member

hagenw commented Jul 20, 2017

The colors in the plot work now also under Octave, but the legend was still far to big. I added a commit that replaces the legend with an updated title, indicating the shown orders for every plot.

@hagenw
Copy link
Member

hagenw commented Jul 20, 2017

Coming back to the computed figure and the comparison to Hahn and Spors (2017) Fig. 8. Forget what I have set about the order. But do you have an idea why we have the obvious difference between those plots (of course besides the difference in amplitude)?

@fietew
Copy link
Member Author

fietew commented Jul 20, 2017

Are you using normalisation for the plot? Also the range of the colormap in Hahn and Spors (2017) Fig. 8. is [-2,2].

@hagenw
Copy link
Member

hagenw commented Jul 20, 2017

I'm using normalisation, otherwise there is no energy in the plot. But you can do the following to get a very similar energy as in Hahn and Spors (2017) Fig. 8:

conf = SFS_config;
conf.nfchoa.order = 30;
conf.plot.caxis = [-0.3 0.3];
sound_field_imp_nfchoa([-2 2],[-2 2],0,[1.5 1.5 0],'ps',1/conf.c,conf)

will result in
nfchoa

This looks similar, but still we have a more pronounced visible circle as indicated by the arrow in the figure.

@fietew
Copy link
Member Author

fietew commented Jul 20, 2017

Was #56 the discussion you meant?

@fietew
Copy link
Member Author

fietew commented Jul 20, 2017

Is it possible, that you have chosen a different number of loudspeakers? In the paper, 60 has been chosen.
For 64 loudspeakers, one loudspeaker is exactly at 45 degrees, which is the virtual point source direction in your plots. For 60 loudspeakers, 45 degrees lies between two loudspeakers.

@hagenw
Copy link
Member

hagenw commented Jul 20, 2017

Ah, brilliant, that's it:

conf = SFS_config;
conf.nfchoa.order = 30;
conf.secondary_sources.number = 60;
conf.plot.caxis = [-0.3 0.3];
sound_field_imp_nfchoa([-2 2],[-2 2],0,[1.5 1.5 0],'ps',1/conf.c,conf)

and we will get the same result as in the paper.
nfchoa2

I would say this is then nearly ready. There is only this discussion on the Bessel polynomial left, @narahahn should give his go, and after a small commit clean up we could merge.

@hagenw
Copy link
Member

hagenw commented Jul 28, 2017

I made another test and tried to improve Fig. 3.14 from my thesis and it worked quite well.

Original NFC-HOA part of the figure:
nfchoa_old

New NFC-HOA part of the figure as calculated with this branch:
nfchoa_new

@fietew: From my side, I have no further change requests for this branch and would like to start cleaning the commit history up, if you agree.

@fietew
Copy link
Member Author

fietew commented Jul 29, 2017

I agree.

@hagenw hagenw merged commit cb3a7c1 into master Aug 14, 2017
@hagenw hagenw deleted the sphbesselh_zeros branch August 14, 2017 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants