1
$\begingroup$

Here is an image for the Jacobi algorithm. I have almost no knowledge of Mathematica, the textbook does not help. Does not provide examples. The class average is 64%.

I just want to be able to complete my homework. I want to understand how one translate pseudocode properly into Mathematica. I have to use this pseudocode. Here is what I currently have based on my interpretation of the image. I'm following it as strictly as possible. It does not work for Steps 1-4 and I want to know why.

enter image description here

n = 50;
a = SparseArray[{{i_, i_} -> 0.5, {i_, j_} /; Abs[i - j] == 1 -> 0.25}, {50, 50}];
b = SparseArray[{{i_} -> 1/i}, {50}];
X0 = SparseArray[{{i_} -> 1}, {50}];
MaxN = 500;
TOL = 10^(-5);
k = 1
While[k <= MaxN, 
 For[i = 1, i <= n, i++, 
  XI = (1/a[[i, i]])*(b[[i]] - 
      Sum[If[j != i, a[[i, j], 0]*X0[[j]]], j = 1, n]);
  If [Norm[XI - X0] < TOL, Print[XI], Break[]]]]
$\endgroup$
  • 7
    $\begingroup$ Ooof. Look, you are not helping your case by deleting your previous question that had been downvoted and was probably going to be closed, then re-posting a new identical one, in which you proceed to blame it on your instructor. $\endgroup$ – MarcoB Jun 23 at 22:10
  • $\begingroup$ The person asked for me to place my code and be specific. $\endgroup$ – HeadAcheMath Jun 23 at 22:12
  • 4
    $\begingroup$ Have you tried to search this site for the keywords "Jacobi algorithm"? I know from a very reliable source that there is an implementation of the algorithm on this site... ;) General hint: You really don't want to use For loops in step 3 and 6. For example, step 3 is just XI = (b- a.X0)/diag, where diag = Normal[Diagonal[a]], and step 5 it just X0=XI. Btw., the pseudocode is maybe not ideal, but it is also not bad, either. So please, don't blame it on the instructor. $\endgroup$ – Henrik Schumacher Jun 23 at 22:21
  • 3
    $\begingroup$ As for the return value: You need to have the Break[] and the return in the same part of the If statement. So something like If [Norm[XI - X0] < TOL, return=XI; Break[];] would be more appropriate (note the ; instead of your ,). $\endgroup$ – Henrik Schumacher Jun 23 at 22:25
  • 1
    $\begingroup$ I'd suggest Return[XI, While] instead of Print[XI]. And look up the syntax of Sum in the docs. $\endgroup$ – Michael E2 Jun 24 at 2:17
4
$\begingroup$

As alluded to in the comments, you have several issues in your code, most of which are easily solved with some basic understanding of Mathematica's syntax and a sharp eye:

  • Your closing brackets are all in the end of your code, you should pay attention to where the for-loop should end and where it actually does end.
  • As Henrik mentioned: You need to check the syntax of the If statement:
 If[condition,
 action if condition is evaluated to true,
 action if condition is evaluated to false
 ]

As you can see, the comma is used to seperate between the condition, the action and the "else" action. The semicolon is used to seperate several commands within each action part.

  • As Michael mentioned, you need to check the syntax of Sum. (speaking from my own experience, the syntax of Mathematica takes some getting used to, especially when coming from a language like c++. )
  • You haven't coded steps 5 and 6, so of course you will not get the desired result.

Since I personally learn best from existing, working code - here is a corrected version of your attempt:

 n = 50; 
 a = SparseArray[{{i_, i_} -> 1, {i_, j_} /; 
 Abs[i - j] == 1 -> 0.25}, {n, n}]; 
 b = SparseArray[{{i_} -> 1/i}, {n}]; 
 X0 = SparseArray[{{i_} -> 1}, {n}]; 
 X = X0; MaxN = 50; TOL = 10^(-1); 
 k =1; 
 While[k <= MaxN, 
  (*Step 3*) 
  For[i = 1, i <= n, i++,
    X[[i]] =(1/a[[i, i]])*(b[[i]] - Sum[If[j != i, a[[i, j]] X0[[j]], 0], {j, 1, n}]);
  ];
  (*Step 4*)
  If[Norm[X - X0] <= TOL,
   Print[Normal[X]];   Break[],
   If[k == MaxN,
     Print["Maximum number of iterations exceeded"]]
   ];
  (*Step 5*)
  k++;
  (*Step 6*)
  X0 = X;
 ]

For comparison, I also implemented some of the suggestions above:

n = 50;
a = SparseArray[{{i_, i_} -> 1, {i_, j_} /; Abs[i - j] == 1 -> 
     0.25}, {n, n}];
b = SparseArray[{{i_} -> 1/i}, {n}];
X0 = SparseArray[{{i_} -> 1}, {n}];
diagSparse = Diagonal[a];
diag = Normal[Diagonal[a]];
X = X0;
MaxN = 50;
TOL = 10^(-1);
k = 1;
While[k <= MaxN,
 (*Step 3*)
 X = (b - a.X0 + diag X0)/diag;
 (*Step 4*)
 If[Norm[X - X0] <= TOL,
  Print[Normal[X]];
  Break[],
  If[k == MaxN, Print["Maximum number of iterations exceeded"]]
  ];
 (*Step 5*)
 k++;
 (*Step 6*)
 X0 = X;
 ]

The difference lies in the handling of the vectors and matrix, for which Mathematica has many useful functionalities. Again: Read the documentation, it explains these things really well.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you for the explanation and I also read the documentation. My issue is when I read the documentation, its has simplified examples and I'm still trying to get familiar. I'm going to try first writing notes on paper before coding. I'm going to keep this bookmarked so I can keep your tips for other formulas I will need to do. I notice that my issue was the matrix implementation. I'm still confused about the summation formula. $\endgroup$ – HeadAcheMath Jun 24 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.