2
$\begingroup$

I have the following Matlab program;

k=1:1:10;
a=[3,5,2];
for j=1:length(k)
for h =1:1:length(a)
    x=a(h);
    y1(h)=x^j-2;
end
minfind(j)=min(y1);
end
plot(k, minfind)

enter image description here

I tried to write Mathematica code that perform the same calculation. So far I wrote the following Mathematica code

a = ( { {3, 5, 2} } );
For[j = 1, j <= 10, j = j + 1,
 For[h = 1, h <= 3, h = h + 1,
  x = a [[1, h]];
  y22 = x^j-2;
  y1 = Append[y1, y22];
  ];
 ymin1 = Min[y1];
 minfind = Append[minfind, ymin1];
 ]

But the above code doesn't work.

Can anyone help in pointing what is wrong with the above code and what is the correct code?

$\endgroup$
3
  • 1
    $\begingroup$ ListLinePlot@Table[Min[{3, 5, 2}^j - 2], {j, 10}]?? But as written you can substitute Min[] for just 2^j-2... $\endgroup$
    – kale
    Commented Aug 19, 2015 at 23:19
  • 1
    $\begingroup$ the only thing preventing your revised code from working is you need to initialize minfind and y1 as empty lists. $\endgroup$
    – george2079
    Commented Aug 20, 2015 at 18:37
  • $\begingroup$ @george2079 That was useful. I revised the code, it is working now. $\endgroup$
    – sky-light
    Commented Aug 20, 2015 at 21:35

1 Answer 1

13
$\begingroup$

It's hard to know quite where to start with this, but I'd start with the answers to this question for some initial guidance.

As a general guide, nested For loops are almost never necessary and using list-based operations is much more efficient, as well as readable and less prone to error.

Let's take the inner loop first.

 For[h = 1, h <= 3, h = h + 1,
  x = a [[1, h]];
  y22 = x^j-2;
  y1 = Append[y1, y22]; ];

All you are really doing is constructing a vector of each element of a (respecifying a as a vector {3, 5, 2}) taken to the power j and then subtracting 2. By the way, is that what you want? or did you mean x^(j-2)?

So eliminate this loop by using the Listable property of arithmetic operations and writing

a^j - 2

You can eliminate most of the outer loop by changing this to

a^# - 2 & /@ Range[10]

Where Range[10] is what I think your definition of k in your Matlab code does. Evaluate that and check.

The result of the last line above is:

 {{1, 3, 0}, {7, 23, 2}, {25, 123, 6}, {79, 623, 14}, {241, 3123, 
  30}, {727, 15623, 62}, {2185, 78123, 126}, {6559, 390623, 
  254}, {19681, 1953123, 510}, {59047, 9765623, 1022}}

(Incidentally Outer[#2^#1 - 2 &, Range[10], a] gives the same output. You might want to experiment with some other list-based functions.)

You want the minimum of each row of that, so just use Map (shortcut notation /@) like this

Min /@ ( a^# - 2 & /@ Range[10])

And your result should be

{0, 2, 6, 14, 30, 62, 126, 254, 510, 1022}

Yes, all you need to replace that convoluted nested For loop is:

a =  {3, 5, 2};
Min /@ ( a^# - 2 & /@ Range[10])
$\endgroup$
1
  • 1
    $\begingroup$ @barznjy I'm afraid that the simple answer to your more complex question is essentially that you have to learn more about Mathematica if you want to use it. Trying to use Mathematica by translating Matlab code and practices won't take you very far. In addition to that, it is discouraged to have questions with "moving targets", where the OP keeps changing the nature of the problem... Verbeia gave you a thorough introduction to the concepts you need. Try and apply them on your own to the problem you mentioned in comments, but start from scratch rather than trying to adapt looping code! $\endgroup$
    – MarcoB
    Commented Aug 20, 2015 at 12:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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