필터 지우기
필터 지우기

how to solve the 12 equations in an effective way

조회 수: 3 (최근 30일)
dcydhb dcydhb
dcydhb dcydhb 2019년 1월 4일
댓글: Walter Roberson 2019년 1월 10일
i have tried but is there an effective way to solve the 12 equations with 12 variables?
function program are as this
function F = root2d(x)
%syms equa1sub equa2sub equa3sub equa4sub equa5sub equa6sub;
equa1sub =x(1)+484533722967603/281474976710656-(4154756651791824122955846205623/10141204801825835211973625643008+10968068365840776354319913193387/10141204801825835211973625643008*i)*x(7)+15954949269969134648023144147861/83076749736557242056487941267521536*x(8)-71813660819499486824121496911249/680564733841876926926749214863536422912*x(9)+68704458373558018815486967994675/1393796574908163946345982392040522594123776*x(10)-26218118780833903306440628355937/1427247692705959881058285969449495136382746624*x(11)+206796938269122258779026599337/91343852333181432387730302044767688728495783936*x(12);
equa2sub =x(2)+2179336774425063/9007199254740992+(37526423397676813332334898889027/855220629711474430592113990172672+49532669641878859065350990413901/427610314855737215296056995086336*i)*x(7)-7398539084151252801240731883817/7245856949184205584664105964273664*x(8)+9701869628173919811376223237191/75261204389257980309851363976180400128*x(9)-1277211448906621552448654388595/23860751773952951312363398400278311993344*x(10)+1362802704850279953288683880255/70907773931469299065694310054832901202116608*x(11)-8625402993825599933615303699537/3702438626946186324992873082646789575845217304576*x(12);
equa3sub =x(3)-2179336774425063/36028797018963968-(12508807799225604444111632963009/1048697196988140797536670555570176+49532669641878859065350990413901/1573045795482211196305005833355264*i)*x(7)-7398539084151252801240731883817/86588217623736540910447134758666240*x(8)-29105608884521759434128669711573/75649093851100752735482115538246696960*x(9)+1277211448906621552448654388595/17711241862742021199068701875804540239872*x(10)-1362802704850279953288683880255/61068558073531812431847844722400210020466688*x(11)+8625402993825599933615303699537/3380027201713290762974992106633635151204912726016*x(12);
equa4sub =x(4)+7748752975733557/288230376151711744+(33356820797934943209001720132433/6190408764194964734552061289431040+22014519840835049131921318329153/1547602191048741183638015322357760*i)*x(7)+26305916743648898510433925203569/863922993464667543602663285577482240*x(8)-51743304683594236328831377155201/310355742240037684763822436037613846528*x(9)-36329570102232795753818397281155/212254113490217598493003436507731431784448*x(10)+19382082913426203433050528326643/635304746339119300790994312862157102563459072*x(11)-2555674961133510611575096049613/842274022614853767674660051874414976259181248512*x(12);
equa5sub =x(5)-2179336774425063/144115188075855872-(37526423397676813332334898889027/12309575435976212511299345462591488+49532669641878859065350990413901/6154787717988106255649672731295744*i)*x(7)-7398539084151252801240731883817/461924515915419508444148023940874240*x(8)+29105608884521759434128669711573/524888983415592000040805790022931316736*x(9)-1277211448906621552448654388595/6886797782101713761219919597640643248128*x(10)-151422522761142217032075986695/2412410515753537353989004504838094190542848*x(11)+8625402993825599933615303699537/2090381500781707541347807227300837103175632683008*x(12);
equa6sub =x(6)+5579102142528161/576460752303423488+(37526423397676813332334898889027/19182188319735057694389731174907904+49532669641878859065350990413901/9591094159867528847194865587453952*i)*x(7)+7398539084151252801240731883817/743426739634181641860703322279772160*x(8)-29105608884521759434128669711573/975292541365611677959817308065299955712*x(9)+1277211448906621552448654388595/25335327515734513772510566088095356157952*x(10)-454267568283426651096227960085/2601984310676884475399766100960607803015168*x(11)-8625402993825599933615303699537/1123147225083019881738503323981193479786657218560*x(12);
equa7sub =x(7)+(2322028850419079/1125899906842624+2562706364895407/9007199254740992*i)*(-5318998413755481/4503599627370496-11316947028382809420225314005533/13362822339241787978001781096448*x(2)+47539893266487660052480027409623/49157681108819099884531432292352*x(3)-9653174320626376094416784221761/9672513694054632397737595764736*x(4)+48624853531325315583340957398461/48084279046782080122263068213248*x(5)-19076967537554081507840067761767/18732605780991267279677471850496*x(6));
equa8sub =x(8)+1828304033752709/70368744177664+12781645729332806833062081373649/13820375345581446809128009728*x(2)+41947465506445508270841202315/129026498829925866291593216*x(3)-106470105689011260713633181571/402295493271512698197114880*x(4)+143015982726173118919053113709/573600972587142771040583680*x(5)-21546008834667373653917509482703/88623373464844422562206187520*x(6);
equa9sub =x(9)-8744181223955479/549755813888-53428943499171695984835881591627/410697999846477507034349568*x(2)+56110677749960030092146867614297/34401225025749569220116480*x(3)+28483769964134474313932345620805/17641681452007428831838208*x(4)-14347810331846682779060483651413/14918242169858103808360448*x(5)+22516280630792217615492161016547/27719481220333695943049216*x(6);
equa10sub =x(10)+2143354288027763/268435456+76889959165422172751349313276095/1324537800215405753532416*x(2)-40374630662549725282540084069465/122896428192007114981376*x(3)+40991188782415858629190320752825/23012637096507873427456*x(4)+13765354859219285845701862029855/3982229928972283543552*x(5)-64806667879765933354102588502575/43949787413105820565504*x(6);
equa11sub =x(11)-1743625504902557/524288-683191558149789503090357463411/29326767937702191104*x(2)+22959445633915007586210679339785/202058909099976753152*x(3)-11655028849494739207651118904051/32844485577164910592*x(4)+652317456398320801335468445423/498874802037594112*x(5)+383885133922523724333435256089/67259717998721024*x(6);
equa12sub =x(12)+3878949580580463/8192+19055803659565858140764297628659/5841418173556017152*x(2)-10006131399781328118029811914599/666592829503797504*x(3)+20317868644705667433246067365239/498327785943072384*x(4)-5117246172621763207417567132397/51531882592622344*x(5)+16061175637909210839969990512723/55375433542216160*x(6);
F(1)=equa1sub;
F(2)=equa2sub;
F(3)=equa3sub;
F(4)=equa4sub;
F(5)=equa5sub;
F(6)=equa6sub;
F(7)=equa7sub;
F(8)=equa8sub;
F(9)=equa9sub;
F(10)=equa10sub;
F(11)=equa11sub;
F(12)=equa12sub;

답변 (2개)

Walter Roberson
Walter Roberson 2019년 1월 4일
No. Your numeric constants cannot possibly be represented precisely. It is not possible to get correct solutions for those equations in the form written.
  댓글 수: 4
Walter Roberson
Walter Roberson 2019년 1월 5일
편집: Walter Roberson 2019년 1월 6일
It's a fraction, not a decimal. why can't be precisely solved?
When you have a integer or floating point number inside a regular MATLAB expression, MATLAB treats the number as being double precision and uses the double precision representation of it -- unless, that is, the number is one of the forms int8(N) uint8(N) int16(N) uint16(N) int32(N) uint32(N) int64(N) uint64(N), where N is a literal number. For example int16(12345) . In those special cases, then MATLAB recognizes the number as being the given type at parse time rather than at execution time. For example, uint64(12345678901234567) is the 64 bit integer that is exactly 12345678901234567 but uint64(0+12345678901234567) is not one of the magic forms, so this is handled at execution time, so the number 12345678901234567 is to be parsed as a floating point number, and 0 floating point is to be added to it, and the result is to be converted to uint64 -- which gives you the 64 bit integer 12345678901234568 . In practice the only time it makes a difference whether the number is handled at parsing time or at execution time is if the number exceeds 9007199254740992 which is the maximum double precision number representable exactly as an integer, after which the integers start being separated by 2 or more. uint64(1+9007199254740992) is uint64 9007199254740992 not uint64 9007199254740993 for example.
Now, whether the numbers are treated as double precision or not matters because you do have values that exceed 9007199254740992 . You also have values that exceed 18446744073709551615 which is the largest uin64 .
In your expression 4154756651791824122955846205623 / 10141204801825835211973625643008 neither are surrounded by uint64() or similar, so both of them will be translated into double precision floating point as they are encountered. The first of them is approximated as 4154756651791824311205918408704 . The second of them is approximated as itself, as it just happens to be exactly 2^103 . The result after floating point approximation is 0.4096906366631898332997252509812824428081512451171875 exactly, which is exactly equal to 1845082598613523 / 4503599627370496.
coding uint64(4154756651791824122955846205623) / uint64(10141204801825835211973625643008) is not going to help. Each of them overflows intmax('uint64') so each of them would "saturate" to be stored as intmax('uint64') . You would then be doing integer division of two values that have saturated to the same value, so you would get the uint64 result exactly equal to 1.
In order to use the full precision of 154756651791824122955846205623 / 10141204801825835211973625643008 you cannot code them in numeric form. You have to instead code them as symbolic numbers using sym() and quoted strings,
sym('154756651791824122955846205623') / sym('10141204801825835211973625643008')
However, we know from past discussions that this is not acceptable to you even though it is the only way to get accurate results from those inputs.
MATLAB (with the symbolic toolbox) can give you exact results if you are willing to code your constants in symbolic form. But you are not willing to do so.
I find it implausible in the extreme that you just happened to have physical constants known to over 108 bits of precision. I think you generated those constants out of other symbolic code, based upon constants that you had originally coded as floating point. I believe the expressions you present are output of some symbolic work -- and that being the case, you should be leaving them as symbolic instead of converting them to numeric code.
Walter Roberson
Walter Roberson 2019년 1월 5일
My tests suggest that it is not practical to solve in the general sense, with the (-1/2*sin(d*m3)/d*a*2^(1/2) etc. terms. You can reframe it as solving a 12 x 12 symbolic matrix for the general solution, and then substituting terms from the equations into the general solution, but it turns out not to be practical to solve 12 x 12 in the general case.

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


John D'Errico
John D'Errico 2019년 1월 4일
편집: John D'Errico 2019년 1월 4일
Without trying to read every one of those equations, are they not just 12 linear equations in 12 unknowns? I can't find anything that is not linear in the variables.
If so, then write them as a matrix problem of the form A*x = b. Then use backslash...
x = A\b;
If you need to convert the problem to a matrix form, then if they are linear, this will do it.
help equationsToMatrix
If the values m1, m2, etc. are not known, then you will need to do this in fully symbolic form. If they are known, then convert A to a double first. If you leave it fully symbolic however, expect the solution be fairly computationally intensive. That may be excluded by your desire for an "effective" solution. But you cannot always have everything you want.
  댓글 수: 17
dcydhb dcydhb
dcydhb dcydhb 2019년 1월 10일
double(max(abs(ans)))
what do it mean?
i posted it as
subs(equ, vars, x.')
subs(equ, vars, vpa(x.', 20))
subs(equ, vars, [alpha0, alpha1,alpha2, alpha3, alpha4,alpha5,alpha6, alpha7, alpha8,alpha9,a0,a1,a2 ,a3,a4,a5,a6,a7,a8,a9])
double(max(abs(ans)))
and got
ans =
6.6564e-04
i just want to konw why directly get it in the equation makes a great difference?
Walter Roberson
Walter Roberson 2019년 1월 10일
The last subs() effectively constructs the equa* values in vectorized form -- the first element of the output is equa1, the second is equa2, and so on.
ans after that third calculation is the vector [equa1, equa2, ....] . abs() of that gives the absolute magnitude, the distance from the entries to 0. max() gets the largest of the absolute magnitudes, and double() converts from symbolic to floating point. So double(max(abs(ans))) is calculated the upper bound on how "bad" the solutions are. You are now getting about 6.6E-4, but what you posted earlier where equa20 = -4.2950e+09 + 2.1475e+09i would have given a max absolute value at least 4.8E+9 .
So there is something wrong with the way you calculate your equa* values. The actual error limit of the calculation is much much smaller than what you are seeing with the equa* that you are calculating somehow. Your equa* values should be almost exactly the same as the result of that subs(equ, vars, vpa(x.', 20)) calculation.

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

Community Treasure Hunt

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

Start Hunting!

Translated by