<p>I thought a little bit about the problem, and I came up with the following quick hack, that seems to work.</p>
<p>Here is the piece of code that should do the job in principle with integers:</p>
<pre><code>function  [exch]=achange(p,coins)
s=size(coins);
c=zeros(1,s(2));
coins=sort(coins,'descend');
it=1:s(2);
isaninteger = @(x)isfinite(x) &amp; x==floor(x);
if p&lt;coins(end)
   return
end
if isaninteger(p)==0
   exch.coins=coins;
   exch.c=inf(1,s(2));
   exch.rest=inf;
   return
elseif any(isaninteger(coins)==0)
   exch.coins=coins;
   exch.c=inf(1,s(2));
   exch.rest=inf;
   return
end
rest=0;
while p&gt;0
    trQ=mod(p,coins)==0;
    idx=it(trQ);
    li=length(idx);
    if isempty(idx)
       rst=1;
       rest=rest+rst;
       p=p-rst;
    elseif li&gt;0 &amp;&amp; li&lt;s(2)
      ps=it(trQ)==0;
      idx2=idx;
      idx2(ps)=[];
      for k=1:li
          if p&gt;0
             p=p-coins(idx2(k));
             c(idx2(k))=c(idx2(k))+1;
          end
      end
    elseif li==s(2)
     for k=1:li
         if p&gt;0
            p=p-coins(idx(k));
            c(idx(k))=c(idx(k))+1;
         end
     end
    end
end
exch.coins=coins;
exch.c=c;
exch.rest=rest;
end
</code></pre>
<p>At least for the following example it works:</p>
<pre><code>&gt;&gt; exch=achange(57,[10 25])
exch = 
struct with fields:
  coins: [25 10]
      c: [1 2]
   rest: 12
 
&gt;&gt; exch.coins*exch.c' + exch.rest
ans =
57
</code></pre>
<p>or for:</p>
<pre><code>&gt;&gt; exch=achange(51,[10 25])
exch = 
struct with fields:
    coins: [25 10]
        c: [1 2]
     rest: 6

&gt;&gt; exch.coins*exch.c' + exch.rest
ans =
51
</code></pre>
<p>and finally my example from the comments:</p>
<pre><code>&gt;&gt; exch=achange(60,[1 2 5 10 20])
exch = 
    struct with fields:
    coins: [20 10 5 2 1]
        c: [1 1 3 4 7]
     rest: 0

&gt;&gt; exch.coins*exch.c'  
ans =
60
</code></pre>
<p>If any input is not an integer, we obtain</p>
<pre><code>&gt;&gt; exch=achange(57,[5 .10 25])
exch = 
    struct with fields:
    coins: [25 5 0.1000]
        c: [Inf Inf Inf]
    rest: Inf
</code></pre>
<p>or similar</p>
<pre><code>&gt;&gt; exch=achange(57.8,[5 10 25])
exch = 
   struct with fields:
     coins: [25 10 5]
         c: [Inf Inf Inf]
      rest: Inf
</code></pre>
<p><strong>UPDATE 21.11.2020</strong></p>
<p>Due to the fact that the allocation of the species is not optimal by the above code, which can be seen, for instance, by first example, where the residual amount can still be allocated to some coins, I provide a small amendment that should produce better results.</p>
<p>The residual amount of the mentioned example is <span class="math-container">$12$</span> indicating that the structure of problem is unchanged, which allows us to solve the problem recursively. That is, we should replace the lines of code after the While-loop by the following If-construct to invoke a recursive call whenever it is necessary.</p>
<pre><code>if any(rest&gt;coins)
   exch2=achange(rest,coins);
   exch.coins=coins;
   exch.c=c+exch2.c;
   exch.rest=exch2.rest;
else
   exch.coins=coins;
   exch.c=c;
   exch.rest=rest;
end   
</code></pre>
<p>Then we can reduce the residual amount of the first example from <span class="math-container">$12$</span> to <span class="math-container">$2$</span>, as we can see through</p>
<pre><code>&gt;&gt; exch=achange(57,[10 25])
exch = 
   struct with fields:
     coins: [25 10]
         c: [1 3]
      rest: 2
</code></pre>

CC BY-SA 4.0
2020-11-19T15:37:16.577Z
Thank you very much! This code is very nice. As a newbie I guess I wouldn't have figured it out. Probably, it will take me some time to even understand the code completely. So again, thanks a lot for your help!
Hokkaido21
CC BY-SA 4.0
2020-11-21T11:31:38.190Z
@Hokkaido21 I provided a code  amendment to optimize the allocation procedure of the coins. I hope this helps.
Holger I. Meinhardt
CC BY-SA 4.0
2020-11-19T12:28:44.010Z
2020-11-21T11:43:22.730Z
2020-11-21T11:43:22.730Z
Holger I. Meinhardt
<p>I am new to Matlab (&amp; also to stackexchange) and I need to learn it for a dynamic Macro class.</p>
<p>I have trouble using a while loop in a function. The function is supposed to calculate the amount of coins one needs to pay price p. My function, however, just provides a vector displaying which coins I need and not how much of which. I hope, someone jumps in and helps me out of my trouble. Here is my code:</p>
<pre><code>function[c] = achange(p,coins)
s=size(coins);  
c=zeros(1,s(2)); 

while p&gt;0
    for i=1:s(2) 
    if coins(i) &lt;= p 
        p=p-coins(i); 
        c(i)=c(i)+1; 
    end
    end
end 
end
</code></pre>

CC BY-SA 4.0
2020-11-18T19:19:30.077Z
Okay, well you should know that the economics stackexchange is for economics questions, not Matlab questions.
Criticize SE actions means ban
CC BY-SA 4.0
2020-11-18T19:25:21.507Z
@user253751 no actually our help center explicitly states: "Software questions: Questions related to software used in economics and econometrics, are on-topic here." See [here](https://economics.stackexchange.com/help/on-topic). So this question is totally on topic because it is application of matlab to some econ question. Matlab is used in economics quite a lot for numerical modeling - I dont recognize the type of the problem above since it is not connected to anything I specialize in but it looks like an Econ problem
1muflon1
CC BY-SA 4.0
2020-11-18T20:48:01.467Z
Your function seems to be okay. Suppose that the good costs 60 cents, and you have the following vector of coins $(1,2,5,10,20)$, then the function returns $(4,3,2,2,1)$ telling you that you need 4 one cent coins, 3 two cents coins etc., adding up  to 60 cents, which is the price of the good.
Holger I. Meinhardt
CC BY-SA 4.0
2020-11-18T20:58:24.590Z
@BrianRomanchuk that is correct, it works only with integers. But this is a refinement that we should let to the author.
Holger I. Meinhardt
CC BY-SA 4.0
2020-11-18T21:01:37.310Z
The algorithm doesn’t diagnose an inability to get the requested amount, and can miss the correct solution. Let’s say we have p=50 and c=[25, 10]. It will return c=[1,2] to add up to 45, and not [2,0] which gives 50.
Brian Romanchuk
CC BY-SA 4.0
2020-11-18T21:03:34.050Z
@HolgerI.Meinhardt I deleted my comment since I misread the code.
Brian Romanchuk
CC BY-SA 4.0
2020-11-18T21:06:10.783Z
@BrianRomanchuk you are right, the code cannot handle your example, it enters in an infinite loop.
Holger I. Meinhardt
CC BY-SA 4.0
2020-11-18T21:14:59.230Z
Yes, I realised it won’t break after I posted that. The while loop could be broken if no changes are found, and it will terminate with the amount less than the target.
Brian Romanchuk
CC BY-SA 4.0
2020-11-19T07:08:24.797Z
@HolgerI.Meinhardt Thanks a lot! Now I understand, why Matlab doesn't give me a solution and I had to quit debugging. It's an infinite loop.
Hokkaido21
CC BY-SA 4.0
2020-11-19T07:08:37.567Z
@BrianRomanchuk But how could I break the while loop and let it terminate with the amount less than the target?
Hokkaido21
CC BY-SA 4.0
2020-11-19T13:10:19.887Z
@Hokkaido21 To break the loop, you need to add a check within the loop that any changes were made. E.g. set a boolean to false before the for loop, then if a coin is found, set it to true. If the Boolean is still false after the for, you break out of the while. It’s been years since I’ve worked with Matlab, so I am unsure about the syntax. The key point is that whenever you have a while loop, you always need to make sure that you have a terminating condition that must trigger.
Brian Romanchuk
CC BY-SA 4.0
2020-11-19T15:38:46.493Z
@BrianRomanchuk Ok, thank you! That makes perfectly sense.
Hokkaido21
<macroeconomics><matlab>
Matlab: While loop in function
Hokkaido21
# Matlab: While loop in function

(Asked by: username_0 on 2020-11-18)

I am new to Matlab (& also to stackexchange) and I need to learn it for a dynamic Macro class.
I have trouble using a while loop in a function. The function is supposed to calculate the amount of coins one needs to pay price p. My function, however, just provides a vector displaying which coins I need and not how much of which. I hope, someone jumps in and helps me out of my trouble. Here is my code:
function[c] = achange(p,coins)
s=size(coins);  
c=zeros(1,s(2)); 

while p>0
    for i=1:s(2) 
    if coins(i) <= p 
        p=p-coins(i); 
        c(i)=c(i)+1; 
    end
    end
end 
end

**Tags:** macroeconomics, matlab

> **Comments:**
> **username_1**: Okay, well you should know that the economics stackexchange is for economics questions, not Matlab questions.  
> **username_2**: @user253751 no actually our help center explicitly states: "Software questions: Questions related to software used in economics and econometrics, are on-topic here." See [here](https://economics.stackexchange.com/help/on-topic). So this question is totally on topic because it is application of matlab to some econ question. Matlab is used in economics quite a lot for numerical modeling - I dont recognize the type of the problem above since it is not connected to anything I specialize in but it looks like an Econ problem  
> **username_3**: Your function seems to be okay. Suppose that the good costs 60 cents, and you have the following vector of coins $(1,2,5,10,20)$, then the function returns $(4,3,2,2,1)$ telling you that you need 4 one cent coins, 3 two cents coins etc., adding up  to 60 cents, which is the price of the good.  
> **username_3**: @BrianRomanchuk that is correct, it works only with integers. But this is a refinement that we should let to the author.  
> **username_4**: The algorithm doesn’t diagnose an inability to get the requested amount, and can miss the correct solution. Let’s say we have p=50 and c=[25, 10]. It will return c=[1,2] to add up to 45, and not [2,0] which gives 50.  
> **username_4**: @HolgerI.Meinhardt I deleted my comment since I misread the code.  
> **username_3**: @BrianRomanchuk you are right, the code cannot handle your example, it enters in an infinite loop.  
> **username_4**: Yes, I realised it won’t break after I posted that. The while loop could be broken if no changes are found, and it will terminate with the amount less than the target.  
> **username_0**: @HolgerI.Meinhardt Thanks a lot! Now I understand, why Matlab doesn't give me a solution and I had to quit debugging. It's an infinite loop.  
> **username_0**: @BrianRomanchuk But how could I break the while loop and let it terminate with the amount less than the target?  
> **username_4**: @username_0 To break the loop, you need to add a check within the loop that any changes were made. E.g. set a boolean to false before the for loop, then if a coin is found, set it to true. If the Boolean is still false after the for, you break out of the while. It’s been years since I’ve worked with Matlab, so I am unsure about the syntax. The key point is that whenever you have a while loop, you always need to make sure that you have a terminating condition that must trigger.  
> **username_0**: @BrianRomanchuk Ok, thank you! That makes perfectly sense.  

---

## 1 answers

### Answer by username_3 on 2020-11-19. Score: 2 | Accepted answer

I thought a little bit about the problem, and I came up with the following quick hack, that seems to work.
Here is the piece of code that should do the job in principle with integers:
function  [exch]=achange(p,coins)
s=size(coins);
c=zeros(1,s(2));
coins=sort(coins,'descend');
it=1:s(2);
isaninteger = @(x)isfinite(x) & x==floor(x);
if p0
    trQ=mod(p,coins)==0;
    idx=it(trQ);
    li=length(idx);
    if isempty(idx)
       rst=1;
       rest=rest+rst;
       p=p-rst;
    elseif li>0 && li0
             p=p-coins(idx2(k));
             c(idx2(k))=c(idx2(k))+1;
          end
      end
    elseif li==s(2)
     for k=1:li
         if p>0
            p=p-coins(idx(k));
            c(idx(k))=c(idx(k))+1;
         end
     end
    end
end
exch.coins=coins;
exch.c=c;
exch.rest=rest;
end

At least for the following example it works:
>> exch=achange(57,[10 25])
exch = 
struct with fields:
  coins: [25 10]
      c: [1 2]
   rest: 12
 
>> exch.coins*exch.c' + exch.rest
ans =
57

or for:
>> exch=achange(51,[10 25])
exch = 
struct with fields:
    coins: [25 10]
        c: [1 2]
     rest: 6

>> exch.coins*exch.c' + exch.rest
ans =
51

and finally my example from the comments:
>> exch=achange(60,[1 2 5 10 20])
exch = 
    struct with fields:
    coins: [20 10 5 2 1]
        c: [1 1 3 4 7]
     rest: 0

>> exch.coins*exch.c'  
ans =
60

If any input is not an integer, we obtain
>> exch=achange(57,[5 .10 25])
exch = 
    struct with fields:
    coins: [25 5 0.1000]
        c: [Inf Inf Inf]
    rest: Inf

or similar
>> exch=achange(57.8,[5 10 25])
exch = 
   struct with fields:
     coins: [25 10 5]
         c: [Inf Inf Inf]
      rest: Inf

UPDATE 21.11.2020
Due to the fact that the allocation of the species is not optimal by the above code, which can be seen, for instance, by first example, where the residual amount can still be allocated to some coins, I provide a small amendment that should produce better results.
The residual amount of the mentioned example is $12$ indicating that the structure of problem is unchanged, which allows us to solve the problem recursively. That is, we should replace the lines of code after the While-loop by the following If-construct to invoke a recursive call whenever it is necessary.
if any(rest>coins)
   exch2=achange(rest,coins);
   exch.coins=coins;
   exch.c=c+exch2.c;
   exch.rest=exch2.rest;
else
   exch.coins=coins;
   exch.c=c;
   exch.rest=rest;
end   

Then we can reduce the residual amount of the first example from $12$ to $2$, as we can see through
>> exch=achange(57,[10 25])
exch = 
   struct with fields:
     coins: [25 10]
         c: [1 3]
      rest: 2

> **Comments:**
> **username_0**: Thank you very much! This code is very nice. As a newbie I guess I wouldn't have figured it out. Probably, it will take me some time to even understand the code completely. So again, thanks a lot for your help!  
> **username_3**: @username_0 I provided a code  amendment to optimize the allocation procedure of the coins. I hope this helps.  

---

