loop or other better solution for mixing?

Hello, I am new to Matlab and want to do some mixing, and wonder if there is any better solution other than looping.
Basically, I want to mix any number of ingredients to make one solution. The percentage of the ingredients added up should equal to 100%. The percentage of each ingredient can be from 0% to 100%. I need to go through and save all the possible compositions with distinct names, and do calculations in order to find out the best composition.
Starting with two databases A and B, each with 4 columns of numerical data. I will need to produce and save all the mixed combination. For example, 10% of each column in A add 90% of the corresponding column in B, and save the result. The total percentage is 100%. This could be done with loop. x=0:0.1:1, C=x*A+(1-x)*b. This seems straightforward, if I only have two databases A and B.
If I have three databases, A, B and C, to produce D. So I need two loops?
If I have A, B, C and D, to produce E, so I need to have three loops?
If I want to mix more, do I have to create another loop again?
As the number of the databases I want to mix increase, this looping solution seems inefficient. Because everytime the numer of database changes, I need to rewrite my code again.
I was wondering if there is any better solution for this problem. So it does not need me to redo the coding even if I change the number of databases to be mixed. I hope I only need one code to run whatever number of databases that I want to mix.
Thank you very much.

2 件のコメント

Steven Lord
Steven Lord 2020 年 7 月 13 日
Are the ingredients able to be continuously measured (i.e. 1.2345 mL of water) or are they discrete (1 egg, 2 eggs, but not 1.2345 eggs)?
Do you need the values of all possible combinations or do you need to find an optimal (according to some objective) combination?
Some of the functions in Optimization Toolbox or Global Optimization Toolbox may help particularly if your measurements are continuous.
addy fang
addy fang 2020 年 7 月 13 日
Hi Steven, yes, the ingredients can be continuously measured (i.e., 1.2345678...mL of water). Ideally, I need all the possible combinations (compositions) to perform calculations in the next step, to eventually find the best values.

サインインしてコメントする。

回答 (1 件)

Walter Roberson
Walter Roberson 2020 年 7 月 13 日

0 投票

nd = 4; %number of databases, adjust as needed
vec = 0 : 0.1 : 1;
[P{1:nd}] = ndgrid(vec);
total = sum(cat(nd+1, P{:}), nd+1);
match = ismembertol(total, 1);
mixtable = cell2mat(cellfun(@(C) C(match), P, 'uniform', 0));
Each column of mixtable is now a percentage of the corresponding database to use.

10 件のコメント

addy fang
addy fang 2020 年 7 月 13 日
編集済み: addy fang 2020 年 7 月 13 日
Hi Walter, thank you very much. These are beautiful codes, but I don't know how to use those functions yet, as those are far beyond what I know. Is it possible to ask some notations on each row of them? How can I use them?
Also, in this case, how do I read in database?
data1=importdata('data1.txt');
data2=importdata('data2.txt');
data3=importdata('data3.txt');
data4=importdata('data4.txt');
How do I save the new database with tracking (percentage of each ingredient) in the file's name?
Walter Roberson
Walter Roberson 2020 年 7 月 13 日
編集済み: Walter Roberson 2020 年 7 月 13 日
nd = 4;
data = cell(nd, 1);
for K = 1 : nd
filename = sprintf('data%d.txt', K);
data{K} = readmatrix(filename);
end
vec = 0 : 0.1 : 1;
[P{1:nd}] = ndgrid(vec);
total = sum(cat(nd+1, P{:}), nd+1);
match = ismembertol(total, 1);
mixtable = cell2mat(cellfun(@(C) C(match), P, 'uniform', 0));
NM = size(mixtable,1);
for K = 1 : NM
mix = mixtable(K,:);
mixture = sum(cell2mat(arrayfun(@(C, frac) C{1}*frac, reshape(mix,1,1,[]), 'uniform', 0)), 3);
filename = "mix" + strjoin(compose("%.1f", mix), "_") + ".txt";
save(filename, 'mixture', '-ascii');
end
An example filename that it would produce would be mix0.8_0.9_0.1_1.0_0.6.txt
madhan ravi
madhan ravi 2020 年 7 月 13 日
data = cell(nd, 1)
addy fang
addy fang 2020 年 7 月 13 日
編集済み: addy fang 2020 年 7 月 13 日
Walter and Madhan, Great. Thank you so much. Love you guys!!!
I tried, there was one error message as follows:
Conversion to cell from double is not possible.
Thank you.
Walter Roberson
Walter Roberson 2020 年 7 月 13 日
Which line was the error on?
addy fang
addy fang 2020 年 7 月 13 日
編集済み: Walter Roberson 2020 年 7 月 13 日
Don't know, as it did not point out the line number. Thank you very much.
I copied the entire code over and changed some of the {} into (), as it said it did not like {}. The codes are like the following now.
nd = 4;
data = cell(nd, 1);
for K = 1 : nd
filename = sprintf('data%d.txt', K);
data(K) = readmatrix(filename);
end
vec = 0 : 0.1 : 1;
[P(1:nd)] = ndgrid(vec);
total = sum(cat(nd+1, P(:)), nd+1);
match = ismembertol(total, 1);
mixtable = cell2mat(cellfun(@(C) C(match), P, 'uniform', 0));
NM = size(mixtable,1);
for K = 1 : NM
mix = mixtable(K,:);
mixture = sum(cell2mat(arrayfun(@(C, frac) C(1)*frac, reshape(mix,1,1,[]), 'uniform', 0)), 3);
filename = "mix" + strjoin(compose("%.1f", mix), "_") + ".txt";
save(filename, 'mixture', '-ascii');
end
Walter Roberson
Walter Roberson 2020 年 7 月 13 日
That code is wrong. You need to go back to the version I posted and work with that.
addy fang
addy fang 2020 年 7 月 13 日
編集済み: addy fang 2020 年 7 月 13 日
I used the code you gave first. It got some error message.
Brace indexing is not supported for variables of this type.
Error in @(C,frac)C{1}*frac
Walter Roberson
Walter Roberson 2020 年 7 月 13 日
Ah... I will need to reconstruct my thoughts about that line; it is certainly wrong...
addy fang
addy fang 2020 年 7 月 14 日
Ok, I will wait for your help again. Thank you.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeProgramming についてさらに検索

質問済み:

2020 年 7 月 12 日

コメント済み:

2020 年 7 月 14 日

Community Treasure Hunt

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

Start Hunting!

Translated by