## I have multiple equations that depend on a specific value and would like matlab to ask the user which equation to use and what the specific value is and then print that value but it's giving me trouble.

Asked by Gaëtan Poirier

### Gaëtan Poirier (view profile)

on 16 Aug 2019
Latest activity Edited by Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 16 Aug 2019
I would like to start by saying I am utterly miserable at coding (somewhat of a beginner) and the following might be the worst thing you lay your eyes on today, but please bear with me.
I am trying to write a program that, when a specific material is inputed by the user as well as a wavelength (lambda), the refractive index for that material at that wavelength is provided.
I have a couple equations that represent the functions required to determine the refractive index of said materials dependent on the value given for the wavelength. I would like to have the program prompt the user to provide the material for which they would like the refractive index to be determined, followed by a prompt to provide the specific wavelength that will be used to generate the refractive index for the specified material at the specified wavelength.
So far, I have the following code:
BK7=@(lambda) sqrt((((1.03961212).*(lambda).^2)./((lambda).^2 - (0.0060069867))) + (((0.231792344).*(lambda).^2)./((lambda).^2 - 0.0200179144)) + 1); %BK7 (N-BK7 schoot at 20C)%
FusedSilica=@(lambda) sqrt((((0.6961663).*(lambda).^2)./((lambda).^2 - (0.0684043).^2)) + (((0.4079426).*(lambda).^2)./((lambda).^2 - (0.1162414).^2)) + (((0.8974794).*(lambda).^2)./((lambda).^2 - (9.896161).^2)) + 1); %Fused Silica (Malitson 1965: n 0.21 - 3.71 micrometer at 20C)
SodaLime=@(lambda) 1.5130 - 0.003169.*(lambda).^2 + 0.003962.*(lambda).^-2; %Soda Lime glass (Rubin 1985: Clear; n,k 0.31 - 4.6 micrometer at unspecified temperature)%
Borofloat=@(lambda) sqrt(((1.03961212.*(lambda).^2)./((lambda).^2 - 0.00600069867)) + ((0.231792344.*(lambda).^2)./((lambda).^2 - 0.0200179144)) + ((1.01046945.*(lambda).^2)./((lambda).^2 - 103.560653)) + 1); %Borasilicate Crown (Schott N-BK7 at 20C)%
Air=@(lambda) ((0.05792105)./(238.0195 - (lambda).^-2)) + ((0.00167917)./(57.362 - (lambda).^-2)) + 1; %Air (at 15C)%
NOA61=@(lambda) 1.5375 + ((8290.45)./(lambda).^2) - ((2.11046*10.^8)./(lambda).^4); %Norland Optical Adhesive 61 (at 25C)%
material(1) = input('What material are you looking for? '); %user is asked to provide which material they seek to find the refractive index for
lambda = input('What is the value of lambda? ', 's') %user is asked to provide the wavelength value
%required to determing the refractive index in each equation
%The 's' was needed to
%avoid an error
switch material(1) %the included (1) is also a means to avoid an error
case 'BK7'
solve(BK7) %if BK7 is inputed in the above prompt, we look to solve equation BK7=@(lambda)
disp('The refractive index is:'), disp solve(BK7); %once the equation is solved, the refractive index should be provided to the user
case 'Fused Silica'
solve(FusedSilica)
disp('The refractive index is:'), disp solve(FusedSilica);
case 'Soda Lime'
solve(SodaLime)
disp('The refractive index is:'), disp solve(SodaLime);
case 'Borofloat'
solve(Borofloat)
disp('The refractive index is:'), disp solve(Borofloat);
case 'Air'
solve(Air)
disp('The refractive index is:'), disp solve(Air);
case 'NOA61'
solve(NOA61)
disp('The refractive index is:'), disp solve(NOA61);
otherwise
disp('Type in the correct name or choose another material') %in the case the user does not provide the name for one of the
%materials given on the list of equations above, this statment is issued
end
At the moment I have the issue that the switch function is not dependent on the input of the 'material' but rather the input of the wavelength. For example, any value may be inputted into the material prompt and the program with continue to the wavelength prompt but the input of the wavelength prompt is restricted to the specific cases in the switch function. Therefore, I could input '12' into the material and everything would be fine, but when inputting '12' into the wavelength prompt I receive the statement "Type in the correct name or choose another material," which should be reserved for the material prompt.
Other than the fact that this is probably a convoluted way of generating the desired code, I assume this is an issue of the order of operations that the code runs through. Moreover, I cannot get any inputted wavelength (lambda) term to be included in the outputted refractive index value. At the moment, I cannot run the program to a point where the refractive index is displayed as "The refractive index is: "... I assume because I did not give a way for the value of lambda to be stored as a value (as of now the lambda term in stored as a 'char' so that might be an underlying culprit).
Any help would be greatly appreciated. Thank you in advance!

#### 1 Comment

Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 16 Aug 2019
Although you write "equation" many times in your text, at no point do you define any equations.
You define some functions (with independent variable lambda), but at no point do you define these to be equal to any value/s (or functions), which is required to define an equation (by definition).
Please clarify what function solve refers to.

### Tags ### Star Strider (view profile)

Answer by Star Strider

### Star Strider (view profile)

on 16 Aug 2019

The 's' indicates that input for ‘lambda’ should return a character vector, so it does.
If the materials are numbered, so the correct response to the material question is a number, the material input will work as you have specified it, although the switch ... case block will have to be re-written to accommodate the numbers rather than the strings. If ‘material’ is supposed to be a string, your code will not work, and will for example throw an error:
Error using input
Undefined function or variable 'BK7'.
Your input assignments may do what you want if you instead write them as:
lambda = input('What is the value of lambda? ')
material = input('What material are you looking for? ', 's')

Gaëtan Poirier

### Gaëtan Poirier (view profile)

on 16 Aug 2019
Thank you for the insightful response!
This definitely makes sense. I should ask, without making any dramatic changes to the current code, is there anyway to make it so the wavelength is prompted after the material? I understand that it works better the way you suggested, however the material seems like something to ask first (just me being nitpicky I guess).
Moreover, I did the changes and it works better but my output is "solve(...)" instead of a value. Should I look to assign the "solve(...)" to a specific value or character and when I want to output the answer given by the equation I call that specified value or character?
I just rewrote the final display to have the "solve(...)" in parentheses.
switch material(1) %the included (1) is also a means to avoid an error
case 'BK7'
solve(BK7) %if BK7 is inputed in the above prompt, we look to solve equation BK7=@(lambda)
disp('The refractive index is:'), disp (solve(BK7)); %once the equation is solved, the refractive index should be provided to the user
The above seems to give a both a positive and a negative root (which I assume is a good sign) although they are far from simplified.
Star Strider

### Star Strider (view profile)

on 16 Aug 2019
My pleasure.
With respect to the order, just reverse the input assignments:
material = input('What material are you looking for? ', 's')
lambda = input('What is the value of lambda? ')
I saw the solve calls, however your code is not obvious in that respect (for example, there is no syms call) so I assume you conld have intended fsolve. In any event, if you want to use symbolic variables, vpasolve might be a better choice, perhaps combined with double. Those will return numeric results (ideally) that you can use in other parts of your code. You can then choose the positive root (since that is what I believe you would want) with straightforward logic, for example:
rt = solve(BK7);
disp('The refractive index is:')
disp(rt(rt > 0))
although it would likely be more efficient to do something like:
fprintf('The refractive index for %s at lambda = %.2f is: %.2f\n', material, lambda, rt(rt>0))
instead of the disp calls.
I did not test any of this, so I am listing it as UNTESTED CODE. It should work, although minor modifications may be necessary.

### dpb (view profile)

on 16 Aug 2019

Do something more like:
materials={'BK7','Fused Silica','Soda Lime','Borofloat','Air','NOA61'};
[material,ok] = listdlg('PromptString','Select a material:',...
'SelectionMode','single',...
'ListString',materials)
if ~ok, return, end % bail out if user didn't select a material...
lambdastr=input('What is the value of lambda? ', 's') %user is asked to provide the wavelength value
try
lambda=str2double(lambdastr);
catch
error("Must enter valid number, sorry...")
end
...
You can be a little more user friendly with the numeric input by wrapping in a while...end loop until get a valid response and/or use a text dialog box for prettier interface...there are examples if search Answers.
With the listbox dialog, the selection is the numeric order of the options in the list so you change you switch block case values to the appropriate integer instead of strings. ### Stephen Cobeldick (view profile)

Answer by Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 16 Aug 2019
Edited by Stephen Cobeldick

### Stephen Cobeldick (view profile)

on 16 Aug 2019

Your code is mixed up with the (meta-)data (i.e. the variable names named as material types), which is a very bad practice and should be avoided. You can easily use a non-scalar structure to hold your data, which makes the rest of your task trivial (i.e. better data design makes code simpler and more efficient):
S(1).typ = 'BK7';
S(1).txt = 'BK7 (N-BK7 schoot at 20C)';
S(1).fun = @(lambda) sqrt((((1.03961212).*(lambda).^2)./((lambda).^2 - (0.0060069867))) + (((0.231792344).*(lambda).^2)./((lambda).^2 - 0.0200179144)) + 1);
S(2).typ = 'FusedSilica';
S(2).txt = 'Fused Silica (Malitson 1965: n 0.21 - 3.71 micrometer at 20C)';
S(2).fun = @(lambda) sqrt((((0.6961663).*(lambda).^2)./((lambda).^2 - (0.0684043).^2)) + (((0.4079426).*(lambda).^2)./((lambda).^2 - (0.1162414).^2)) + (((0.8974794).*(lambda).^2)./((lambda).^2 - (9.896161).^2)) + 1);
S(3).typ = 'SodaLime';
S(3).txt = 'Soda Lime glass (Rubin 1985: Clear; n,k 0.31 - 4.6 micrometer at unspecified temperature)';
S(3).fun = @(lambda) 1.5130 - 0.003169.*(lambda).^2 + 0.003962.*(lambda).^-2;
S(4).typ = 'Borofloat';
S(4).txt = 'Borasilicate Crown (Schott N-BK7 at 20C)'
S(4).fun = @(lambda) sqrt(((1.03961212.*(lambda).^2)./((lambda).^2 - 0.00600069867)) + ((0.231792344.*(lambda).^2)./((lambda).^2 - 0.0200179144)) + ((1.01046945.*(lambda).^2)./((lambda).^2 - 103.560653)) + 1);
S(5).typ = 'Air';
S(5).txt = 'Air (at 15C)';
S(5).fun = @(lambda) ((0.05792105)./(238.0195 - (lambda).^-2)) + ((0.00167917)./(57.362 - (lambda).^-2)) + 1;
S(6).typ = 'NOA61';
S(6).txt = 'Norland Optical Adhesive 61 (at 25C)';
S(6).fun = @(lambda) 1.5375 + ((8290.45)./(lambda).^2) - ((2.11046*10.^8)./(lambda).^4);
[X,B] = listdlg('ListString',{S.typ}, 'SelectionMode','single')
L = str2double(inputdlg('Lambda'))
V = S(X).fun(L);
fprintf('The refractive index of %s is %g\n',S(X).typ,V);