whats wrong in this function?

72 views (last 30 days)
Muazma Ali
Muazma Ali on 9 Nov 2025 at 12:54
Edited: dpb about 18 hours ago
Hi:)
When I call the attached function with for instance best_salt_1='ZnBr2' and best_salt_2='MgCl2' and temperatur_1 = 40, I get this error saying:
Output argument "massetetthet_MgCl2" (and maybe others) not assigned during call to "beregn_massetetthet_mettetsaltlosning".
I dont understand I have set all the variables after each if block to something...and I know a similar function has worked for me earlier.
  4 Comments
Muazma Ali
Muazma Ali on 9 Nov 2025 at 14:18
@dpb do you think the error could possibly be that I havent used ( . ) in my operations...is it a big issue here?
dpb
dpb on 9 Nov 2025 at 14:42
I meant something like the following, not images and without all the superfluous blank lines and all so that one can't readily see what the code structure really is.
function [massetetthet_ZnBr2,massetetthet_MgCl2,massetethet_CaCl2, massetetthet_KCl, ...
massetetthet_MgBr2,massetetthet_NaCl, massetetthet_AlCl3,massetetthet_CH3CO2K, ...
massetetthet_HCOOK, massetetthet_HCOONa, massetetthet_CaBr2]= ...
beregn_massetetthet_mettetsaltlosning(best_salt_1, best_salt_2, temperatur_1)
if ~isempty(temperatur_1)
if strcmpi(best_salt_1,'ZnBr2')||strcmpi(best_salt_2,'ZnBr2')
masse_salt= ( 3E-05)*temperatur_1^4 - 0.0053*temperatur_1^3 + 0.3028*temperatur_1 - 0.5269*temperatur_1 + 386.79
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast ZnBr2
volum_salt= (masse_salt/4.2);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_ZnBr2= (masse_total./ Volum_losning);
elseif strcmpi(best_salt_1, 'MgCl2')||strmpci(best_salt_2,'MgCl2')
masse_salt= 0.0016*temperatur_1^2 + 0.0394*temperatur_1 + 53.066
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast ZnBr2
volum_salt= (masse_salt/2.316);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_MgCl2=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1, 'CaCl2')||strmcpi(best_salt_2, 'CaCl2')
masse_salt= (-2E-07)*temperatur_1^5 + (5E-05)*temperatur_1^4 - (0.0053)*temperatur_1^3 + 0.2307*temperatur_1^2 - 1.9318*temperatur_1 + 60.824
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast MgBr2
volum_salt= (masse_salt/2.15);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_CaCl2=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1, 'KCl')|| strcmpi(best_salt_2,'KCl')
masse_salt=0.2832*temperatur_1 + 28.468
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast KCl
volum_salt= (masse_salt/1.98);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_KCl=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1, 'MgBr2')|| strcmpi(best_salt_2,'MgBr2')
masse_salt=0.001*temperatur_1^2 + 0.1751*temperatur_1 + 97.542
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast KCl
volum_salt= (masse_salt/3.72);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_MgBr2=(masse_total./Volum_losning);
elseif strcmpi(best_salt_1,'NaCl')||strmcpi(best_salt_2,'NaCl')
masse_salt=0.0003*temperatur_1^2 + 0.0082*temperatur_1 + 35.629
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast MgBr2
volum_salt= (masse_salt/2.17);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_NaCl=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1,'AlCl3')||strcmpi(best_salt_2,'AlCl3')
masse_salt= (3E-06)*temperatur_1^3 - 0.001*temperatur_1^2 + 0.1175*temperatur_1 + 43.86
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast AlCl3
volum_salt= (masse_salt/2.48);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_AlCl3=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1,'CH3CO2K')||strcmpi(best_salt_2,'CH3CO2K')
masse_salt=(-2E-08)*temperatur_1^6 + (6E-06)*temperatur_1^5 - (0.0006)*temperatur_1^4+ 0.0234*temperatur_1^3 - 0.3943*temperatur_1^2 + 3.9427*temperatur_1 + 215.8
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast k-acetat
volum_salt= (masse_salt/1.57);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_CH3CO2K=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1,'HCOOK')||strmcpi(best_salt_2,'HCOOK')
masse_salt= (1E-05)*temperatur_1^4 - 0.0027*temperatur_1^3 + 0.1913*temperatur_1^2 - 2.5374*temperatur_1 + 326.45
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast k-acetat
volum_salt= (masse_salt/1.91);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_HCOOK=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1,'HCOONa')||strmcpi(best_salt_2,'HCOONa')
masse_salt= (2E-09)*temperatur_1^6 - (8E-07)*temperatur_1^5 + 0.0001*temperatur_1^4 - 0.0061*temperatur_1^3 + 0.1429*temperatur_1^2 + 0.8372*temperatur_1 + 44.057
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast k-acetat
volum_salt= (masse_salt/1.920);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_HCOONa=(masse_total./ Volum_losning);
elseif strcmpi(best_salt_1, 'CaBr2')||strmcpi(best_salt_2,'CaBr2')
masse_salt= (2E-05)*temperatur_1^4 - 0.0045*temperatur_1^3 + 0.3397*temperatur_1^2 - 6.3523*temperatur_1 + 166.33
masse_total=(100.0+masse_salt);
volum_vann=(100.0/0.998);
% volum av saltet er lik massen til saltet delt på massetetthetent
% til fast k-acetat
volum_salt= (masse_salt/3.41);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+ volum_salt)*0.80;
massetetthet_CaBr2=(masse_total./ Volum_losning);
else
massetetthet_ZnBr2=[];
massetetthet_MgCl2=[];
massetethet_CaCl2=[];
massetetthet_KCl=[];
massetetthet_MgBr2=[];
massetetthet_NaCl=[];
massetetthet_AlCl3=[];
massetetthet_CH3CO2K=[];
massetetthet_HCOOK=[];
massetetthet_HCOONa=[];
massetetthet_CaBr2 =[];
end
else
massetetthet_ZnBr2=[];
massetetthet_MgCl2=[];
massetethet_CaCl2=[];
massetetthet_KCl=[];
massetetthet_MgBr2=[];
massetetthet_NaCl=[];
massetetthet_AlCl3=[];
massetetthet_CH3CO2K=[];
massetetthet_HCOOK=[];
massetetthet_HCOONa=[];
massetetthet_CaBr2=[];
end
end

Sign in to comment.

Answers (2)

Steven Lord
Steven Lord on 9 Nov 2025 at 14:28
Let's look at the signature of your function (with some line breaks added to avoid scrolling.)
function [massetetthet_ZnBr2,massetetthet_MgCl2, massetethet_CaCl2,...
massetetthet_KCl,massetetthet_MgBr2, massetetthet_NaCl,...
massetetthet_AlCl3, massetetthet_CH3CO2K, massetetthet_HCOOK, ...
massetetthet_HCOONa, massetetthet_CaBr2] = ...
beregn_massetetthet_mettetsaltlosning(best_salt_1, best_salt_2, temperatur_1)
I suspect what you believe will happen is that only the massetetthet_* variables corresponding to the inputs you pass in for best_salt_1 and best_salt_2 will be returned from this function. That is not correct. Your function declares that it returns eleven variables in a particular order, so you have to call it with all eleven outputs even if you just wanted (as an example) massetetthet_HCOONa and massetetthet_CaBr2.
In addition, if / elseif / else statements don't "fall through". As soon as one of the if or elseif conditions are satisfied, MATLAB runs the body of that section of the statement then skips to the next line after the trailing end. It doesn't "check the next elseif check" or anything like that. So at best, unless neither best_salt_1 nor best_salt_2 are any of the salts you're looking for (only your else block defines all eleven variables) your code won't work.
Rather than defining eleven output variables, I would define two: massetetthet_salt1 and massetetthet_salt2. I would also write the code that does the if / elseif / else statement as a local function so I could call that local function twice, once with best_salt_1 as input and once with best_salt_2 as input. That would avoid duplicating the code.
  5 Comments
Muazma Ali
Muazma Ali on 10 Nov 2025 at 3:58

thank you Steven. I have now understood the basic thing that I didnt think of. I want my function to remain simple so I will continue using the procedure of " if blocks" but now just one block for each salt: if strcmpi( best_salt_1, 'MgCl2')||strcmpi(best_salt_2,' MgCl2') ...... massetetthet_MgCl2=..... end % and so on with the other salts

dpb
dpb on 10 Nov 2025 at 5:27
Edited: dpb on 10 Nov 2025 at 15:32
"...f. I want my function to remain simple"
What could be simpler than replacing all those if blocks with one generic function and all the data in a couple of arrays that can be edited at will? All the many if blocks go away with only a simple lookup of the specific salt name.
I finished the coefficients table for you as well.
This will fix the issue in at least one of the if clauses with ZnBr2 of the correlation missing an exponent on the quadratic term so it is going to return a bad value as is in your code. That's one of the problems with writing duplicated code instead of using generic routines with the data; it's easy to make an error and not catch it.
I would again urge you to look at the coefficients of the correlations carefully; it seems highly unlikely those higher order terms would be precisely integer-valued coefficients and small changes in those terms will almost certainly make a visible difference in the answers you will get.

Sign in to comment.


dpb
dpb on 9 Nov 2025 at 17:10
Edited: dpb about 3 hours ago
OK, try this...
function [massetetthet]=beregn_massetetthet_mettetsaltlosning(salt_1, salt_2, temperature)
% take care of possible missing input temp
assert(~isempty(temperature), "No temperature input. Aborting.")
% now do work...return as structure with salt names as fields and temperature for bookkeeping
massetetthet.(salt_1)=doSaltDensity(salt_1,temperature);
massetetthet.(salt_2)=doSaltDensity(salt_2,temperature);
massetetthet.T=temperature;
function massetetthet=doSaltDensity(salt,T)
SALTS={'ZnBr2','MgCl2' ,'CaCl2','KCl' ,'MgBr2','NaCl', ...
'AlCl3','CH3CO2K','HCOOK','HCOONa','CaBr2'};
COEFFS=[0, 0, 3E-05, -0.0053, 0.3028, -0.5269, 386.79;
0, 0, 0, 0, 0.0016, 0.0394, 53.066
0, -2E-07, 5E-05, -0.0053, 0.2307, -1.9318, 60.824
0, 0, 0, 0, 0, 0.2832, 28.468
0, 0, 0, 0, 0.001, 0.1751, 97.542
0, 0, 0, 0, 0.0003, 0.0082, 35.629
0, 0, 0, 3E-06, -0.001, 0.1175, 43.86
-2E-08, 6E-06, -0.0006, 0.0234, -0.3943, 3.9427, 215.8
0, 0, 1E-05, -0.0027, 0.1913, -2.5374, 326.45
2E-09, -8E-07, 0.0001, -0.0061, 0.1429, 0.8372, 44.057
0, 0, 2E-05, -0.0045, 0.3397, -6.3523, 166.33
];
DENS25=[4.22; 2.316; 2.15; 1.98; 3.72; 2.17; 2.48; 1.57; 1.91; 1.920; 3.41];
volum_vann=(100.0/0.998);
ixSalt=find(matches(SALTS,salt,'ignorecase',1)); % lookup which salt it is working on...
assert(~isempty(ixSalt),'Salt %s not found. Aborting.',salt) % make sure found one
masse_salt=polyval(COEFFS(ixSalt,:),T); % compute initial mass from correlation
masse_total=(100.0+masse_salt);
% volum av saltet er lik massen til saltet delt på massetetthetent til fast
volum_salt=masse_salt/DENS25(ixSalt);
% Volum av løsningen med ca 10% krympning
Volum_losning=(volum_vann+volum_salt)*0.80;
massetetthet=masse_total./Volum_losning;
end
end
beregn_massetetthet_mettetsaltlosning('MgCl2','ZnBr2',40)
ans = struct with fields:
MgCl2: 1.5733 ZnBr2: 3.5899 T: 40
Verify there aren't any unique things for any case I neglected to account for; I did make the assumption everything other than the numeric constants is the same without reading every line to ensure there wasn't something in one of the cases.
This way, you can add any number of additional salts that have similar behavior simply by augmenting the data arrays.
As the above illustrates, the key to writing generic code is to separate the data from the code; write code to solve the physical problem for any set of data using variables for all constants that may need to change as well as the input data, then pass the data. Here it's complicated only slightly by the need to have the data values also dependent upon a given input, but as illustrated, that's generally solvable by use of lookup tables as shown.
  1 Comment
dpb
dpb on 9 Nov 2025 at 17:46
Edited: dpb on 9 Nov 2025 at 18:54
ADDENDUM
COEFFS=[0, 0, 3E-05, -0.0053, 0.3028, -0.5269, 386.79];
A word of caution would be to ensure you're using all the precision that is available for these polynomial constants -- a high order polynomial can be very sensitive to the higher power terms, even if they're small numerically. Here for example
T=40;
P4=3e-5*T^4
P4 = 76.8000
D=polyval(COEFFS,T)
D = 587.7940
P4/D*100
ans = 13.0658
It's 13% of the evaluated value.

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!