Converting result after substituting numerical values into symbolic expression not possible. Matlab creates new symbolic variables by complex symbolic expression.

조회 수: 3 (최근 30일)
I have 22 symbolic variables, which I create different subexpressions with. Then I mathematically combine all these subexpression in one big expression according to the calculation I have to perform. I do these steps to keep some readability. However, matlab automatically creates new variables in the final expression, whereby they are named sigmas. When I then substitute numerical values into the symbolic variables, I get a complex result, which I can convert into a double precision number. However, I need to compute the derivative first and then substitute numerical values and at that point I get the error that it is not possible to convert them because symbolic variabls remains in the expression. I suppose that's because of the new sigma variables. I tried vpa(), double(), simplify() but I do not get it solved. Does someone have an idea how I could handle that ? You can see that the derivative result is displayed with a D if you open the result and not sigma can be seen like it is displayed in the script.
syms T_NTC NTC_R NTC_B2585 R1509 R1510 R1507 S3V3S_A Ron LeakageCurrent GainError OffsetError VOLT_REF_3V INLError DNLError S3V3S_A_Ripple PSRR ResolutionADC
syms R1508 R1511 ADC2ADC_GainError ADC2ADC_OffsetError ADC2ADC_Isolation
%% Resistor network TEMP_DCB
R_NTC = NTC_R.*exp(NTC_B2585*(1./(T_NTC)-1/298.15));
Rs_TEMP_DCB = R1509 + 1./(1./R1510+1./R_NTC+1./R1507);
TEMP_DCB = S3V3S_A.*(R_NTC.*R1510./(R_NTC+R1510))./(R_NTC.*R1510./(R_NTC+R1510)+R1507) + (Rs_TEMP_DCB+Ron).*LeakageCurrent;
ADC_error_TEMP_DCB = GainError.*TEMP_DCB./VOLT_REF_3V + OffsetError + INLError + DNLError + S3V3S_A_Ripple*10.^(-PSRR/20).*2.^ResolutionADC./VOLT_REF_3V;
TEMP_DCB_ADCRawValue = round(TEMP_DCB.*2^ResolutionADC./VOLT_REF_3V + ADC_error_TEMP_DCB);
%% Resistor network 3V3S_A
Rs_VOLT_3V3S_A = R1508.*R1511./(R1508+R1511);
VOLT_3V3S_A = S3V3S_A.*R1511./(R1511+R1508) + (Rs_VOLT_3V3S_A+Ron).*LeakageCurrent;
ADC_error_3V3S_A = (GainError+ADC2ADC_GainError).*VOLT_3V3S_A./VOLT_REF_3V + OffsetError + ADC2ADC_OffsetError + ADC2ADC_Isolation + INLError + DNLError + S3V3S_A_Ripple*10.^(-PSRR/20).*2.^ResolutionADC./VOLT_REF_3V;
VOLT_3V3S_A_ADCRawValue = round(VOLT_3V3S_A.*2^ResolutionADC./VOLT_REF_3V + ADC_error_3V3S_A);
%% Ratio TEMP_DCB/VOLT_3V3S_A
y = TEMP_DCB_ADCRawValue./VOLT_3V3S_A_ADCRawValue
%% Derivatives
dy_dNTC_R = diff(y, NTC_R);
dy_dNTC_B2585 = diff(y, NTC_B2585);
dy_dR1509 = diff(y, R1509);
dy_dR1510 = diff(y, R1510);
dy_dR1507 = diff(y, R1507);
dy_dS3V3S_A = diff(y, S3V3S_A);
dy_dRon = diff(y, Ron);
dy_dLeakageCurrent = diff(y, LeakageCurrent);
dy_dGainError = diff(y, GainError);
dy_dVOLT_REF_3V = diff(y, VOLT_REF_3V);
dy_dOffsetError = diff(y, OffsetError);
dy_dINLError = diff(y, INLError);
dy_dDNLError = diff(y, DNLError);
dy_dS3V3S_A_Ripple = diff(y, S3V3S_A_Ripple);
dy_dPSRR = diff(y, PSRR);
dy_dResolutionADC = diff(y, ResolutionADC);
dy_dR1508 = diff(y, R1508);
dy_dR1511 = diff(y, R1511);
dy_dADC2ADC_GainError = diff(y, ADC2ADC_GainError);
dy_dADC2ADC_OffsetError = diff(y, ADC2ADC_OffsetError);
dy_dADC2ADC_Isolation = diff(y, ADC2ADC_Isolation);
%% Define working points
% Define your working point values
T_NTC_wp1 = 130 + 273.15;
NTC_R_wp1 = 5e3;
NTC_B2585_wp1 = 3420;
R1509_wp1 = 1e3;
R1510_wp1 = 20e3;
R1507_wp1 = 2e3;
S3V3S_A_wp1 = 3.33;
Ron_wp1 = 500;
LeakageCurrent_wp1 = 0;
GainError_wp1 = 0;
OffsetError_wp1 = 0;
VOLT_REF_3V_wp1 = 3;
INLError_wp1 = 0;
DNLError_wp1 = 0;
S3V3S_A_Ripple_wp1 = 10e-3;
PSRR_wp1 = 57;
ResolutionADC_wp1 = 12;
R1508_wp1 = 1e3;
R1511_wp1 = 1e3;
ADC2ADC_GainError_wp1 = 0;
ADC2ADC_OffsetError_wp1 = 0;
ADC2ADC_Isolation_wp1 = 0;
%% Combine working points into a vector
WP1 = [T_NTC_wp1 NTC_R_wp1 NTC_B2585_wp1 R1509_wp1 R1510_wp1 R1507_wp1 S3V3S_A_wp1 Ron_wp1 ...
LeakageCurrent_wp1 GainError_wp1 OffsetError_wp1 VOLT_REF_3V_wp1 INLError_wp1 ...
DNLError_wp1 S3V3S_A_Ripple_wp1 PSRR_wp1 ResolutionADC_wp1 R1508_wp1 R1511_wp1 ...
ADC2ADC_GainError_wp1 ADC2ADC_OffsetError_wp1 ADC2ADC_Isolation_wp1];
%% Calculate sensitivity
symbols = [T_NTC NTC_R NTC_B2585 R1509 R1510 R1507 S3V3S_A Ron LeakageCurrent GainError OffsetError ...
VOLT_REF_3V INLError DNLError S3V3S_A_Ripple PSRR ResolutionADC R1508 R1511 ADC2ADC_GainError ...
ADC2ADC_OffsetError ADC2ADC_Isolation];
S_NTC_R_wp1 = (subs(dy_dNTC_R, symbols, WP1) * NTC_R_wp1) / subs(y, symbols, WP1)
% S_NTC_R_wp1_num = double(S_NTC_R_wp1);
S_NTC_R_wp1_num = vpa(S_NTC_R_wp1);

채택된 답변

Star Strider
Star Strider 2024년 9월 26일
The σ are sub-expressions.
You can keep them from appearing by using:
sympref('AbbreviateOutput',false);
So here:
syms T_NTC NTC_R NTC_B2585 R1509 R1510 R1507 S3V3S_A Ron LeakageCurrent GainError OffsetError VOLT_REF_3V INLError DNLError S3V3S_A_Ripple PSRR ResolutionADC
syms R1508 R1511 ADC2ADC_GainError ADC2ADC_OffsetError ADC2ADC_Isolation
sympref('AbbreviateOutput',false); % <— ADDED
%% Resistor network TEMP_DCB
R_NTC = NTC_R.*exp(NTC_B2585*(1./(T_NTC)-1/298.15));
Rs_TEMP_DCB = R1509 + 1./(1./R1510+1./R_NTC+1./R1507);
TEMP_DCB = S3V3S_A.*(R_NTC.*R1510./(R_NTC+R1510))./(R_NTC.*R1510./(R_NTC+R1510)+R1507) + (Rs_TEMP_DCB+Ron).*LeakageCurrent;
ADC_error_TEMP_DCB = GainError.*TEMP_DCB./VOLT_REF_3V + OffsetError + INLError + DNLError + S3V3S_A_Ripple*10.^(-PSRR/20).*2.^ResolutionADC./VOLT_REF_3V;
TEMP_DCB_ADCRawValue = round(TEMP_DCB.*2^ResolutionADC./VOLT_REF_3V + ADC_error_TEMP_DCB);
%% Resistor network 3V3S_A
Rs_VOLT_3V3S_A = R1508.*R1511./(R1508+R1511);
VOLT_3V3S_A = S3V3S_A.*R1511./(R1511+R1508) + (Rs_VOLT_3V3S_A+Ron).*LeakageCurrent;
ADC_error_3V3S_A = (GainError+ADC2ADC_GainError).*VOLT_3V3S_A./VOLT_REF_3V + OffsetError + ADC2ADC_OffsetError + ADC2ADC_Isolation + INLError + DNLError + S3V3S_A_Ripple*10.^(-PSRR/20).*2.^ResolutionADC./VOLT_REF_3V;
VOLT_3V3S_A_ADCRawValue = round(VOLT_3V3S_A.*2^ResolutionADC./VOLT_REF_3V + ADC_error_3V3S_A);
%% Ratio TEMP_DCB/VOLT_3V3S_A
y = TEMP_DCB_ADCRawValue./VOLT_3V3S_A_ADCRawValue
%% Derivatives
dy_dNTC_R = diff(y, NTC_R);
dy_dNTC_B2585 = diff(y, NTC_B2585);
dy_dR1509 = diff(y, R1509);
dy_dR1510 = diff(y, R1510);
dy_dR1507 = diff(y, R1507);
dy_dS3V3S_A = diff(y, S3V3S_A);
dy_dRon = diff(y, Ron);
dy_dLeakageCurrent = diff(y, LeakageCurrent);
dy_dGainError = diff(y, GainError);
dy_dVOLT_REF_3V = diff(y, VOLT_REF_3V);
dy_dOffsetError = diff(y, OffsetError);
dy_dINLError = diff(y, INLError);
dy_dDNLError = diff(y, DNLError);
dy_dS3V3S_A_Ripple = diff(y, S3V3S_A_Ripple);
dy_dPSRR = diff(y, PSRR);
dy_dResolutionADC = diff(y, ResolutionADC);
dy_dR1508 = diff(y, R1508);
dy_dR1511 = diff(y, R1511);
dy_dADC2ADC_GainError = diff(y, ADC2ADC_GainError);
dy_dADC2ADC_OffsetError = diff(y, ADC2ADC_OffsetError);
dy_dADC2ADC_Isolation = diff(y, ADC2ADC_Isolation);
%% Define working points
% Define your working point values
T_NTC_wp1 = 130 + 273.15;
NTC_R_wp1 = 5e3;
NTC_B2585_wp1 = 3420;
R1509_wp1 = 1e3;
R1510_wp1 = 20e3;
R1507_wp1 = 2e3;
S3V3S_A_wp1 = 3.33;
Ron_wp1 = 500;
LeakageCurrent_wp1 = 0;
GainError_wp1 = 0;
OffsetError_wp1 = 0;
VOLT_REF_3V_wp1 = 3;
INLError_wp1 = 0;
DNLError_wp1 = 0;
S3V3S_A_Ripple_wp1 = 10e-3;
PSRR_wp1 = 57;
ResolutionADC_wp1 = 12;
R1508_wp1 = 1e3;
R1511_wp1 = 1e3;
ADC2ADC_GainError_wp1 = 0;
ADC2ADC_OffsetError_wp1 = 0;
ADC2ADC_Isolation_wp1 = 0;
%% Combine working points into a vector
WP1 = [T_NTC_wp1 NTC_R_wp1 NTC_B2585_wp1 R1509_wp1 R1510_wp1 R1507_wp1 S3V3S_A_wp1 Ron_wp1 ...
LeakageCurrent_wp1 GainError_wp1 OffsetError_wp1 VOLT_REF_3V_wp1 INLError_wp1 ...
DNLError_wp1 S3V3S_A_Ripple_wp1 PSRR_wp1 ResolutionADC_wp1 R1508_wp1 R1511_wp1 ...
ADC2ADC_GainError_wp1 ADC2ADC_OffsetError_wp1 ADC2ADC_Isolation_wp1];
%% Calculate sensitivity
symbols = [T_NTC NTC_R NTC_B2585 R1509 R1510 R1507 S3V3S_A Ron LeakageCurrent GainError OffsetError ...
VOLT_REF_3V INLError DNLError S3V3S_A_Ripple PSRR ResolutionADC R1508 R1511 ADC2ADC_GainError ...
ADC2ADC_OffsetError ADC2ADC_Isolation];
S_NTC_R_wp1 = (subs(dy_dNTC_R, symbols, WP1) * NTC_R_wp1) / subs(y, symbols, WP1)
% S_NTC_R_wp1_num = double(S_NTC_R_wp1);
S_NTC_R_wp1_num = vpa(S_NTC_R_wp1, 7)
S_NTC_R_wp1 = simplify(S_NTC_R_wp1, 500)
S_NTC_R_wp1_num = vpa(S_NTC_R_wp1, 7)
Also, ‘complex’ has multiple meanings (you may intend ‘complicated)’. All the values appear to me to be real, slthough I doubt that the round call is doing anything.
(MATLAB Answers has been having problems, so they LaTeX experessions may not show up here. They should if you run it on your computer.)
.
  댓글 수: 2
Antoine
Antoine 2024년 9월 27일
Thanks a lot ! It solved my problem. Additionally, I removed the round() function to make it work. Yes you're right, I did use the word "complex" whereupon I should have used "complicated" in such a mathematical context.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Symbolic Math Toolbox에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by