Group Abstract Group Abstract

Message Boards Message Boards

0
|
4.5K Views
|
12 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Module doesn't recognize function parameters

Posted 2 years ago
Attachments:
POSTED BY: Tomás Valencia
12 Replies
Posted 2 years ago

Ugh. I see an edit I need to make, but for some reason that post was attributed to "Updating Name" and so now I can't edit my own post! I was just going to fix the line that was truncated, but hopefully it's not too unclear as it stands.

POSTED BY: Eric Rimbey
Posted 2 years ago
POSTED BY: Updating Name
Posted 2 years ago

Based on my understanding of what OP wants, no, your code does not work with arbitrary functions. Let's say that we want to swap fC3 with a new function that takes two arguments. The way your code is written, hF1 needs to know that, and so it also needs to change. Or let's say we wanted to replace fC3 with a new function that takes 5 arguments. Now your code is broken completely, because hF1 explicitly expects all of the intermediate functions to take at most 4 arguments. Your code has fairly tightly coupled the "shape" of the hF1 function (or any alternative we might want to use) to the "shape" of the intermediate fA1 (et al) functions. Now, maybe that's suffient for the OPs case, but I got the impression that something more general was wanted.

POSTED BY: Eric Rimbey

My code works with arbitrary functions. I just showed it in its most simple form

fA1[w1_, w2_, w3_, w4_] := 10 + w1 + w2 + w3 + w4
fB2[r1_, r2_, r3_, r4_] := 1 + r1 + r2 + r3 + r4
fC3[t1_] := 5*t1
hF1[{fA1_, fB2_, fC3_}, {d1_, d2_, d3_, 
   d4_}] := (2*fA1[d1 + d2, d3, d1, d2])*(3*
    fB2[d1 + d2, d3, d1, d2])*(4*fC3[2*d1])

n = 100;
dom = {min, max} = {1, 10^6};
ranges = {{1, 2}, {1, 2}, {1, 2}, {1, 2}};

FindValue[{f_, fs_}, {min_, max_}, n_, ranges_] := {#, f[fs, #]} & /@ 
  Select[Transpose[RandomReal[#, n] & /@ ranges], 
   min < f[fs, #] < max &]

hF1[{fA1, fB2, fC3}, {d1, d2, d3, d4}]

FindValue[{hF1, {fA1, fB2, fC3}}, dom, n, ranges]

Or in the case the evaluation of your function takes a long time, your dont want to compute f[fs,#] twice so you can also use

FindValue2[{f_, fs_}, {min_, max_}, n_, ranges_] := 
 Block[{rand, val, sel},
  rand = Transpose[RandomReal[#, n] & /@ ranges];
  val = f[fs, #] & /@ rand;
  sel = min < # < max & /@ val;
  Pick[Thread[{rand, val}], sel, True]
  ]

Which is apparently faster even if the computation is short

FindValue[{hF1, {fA1, fB2, fC3}}, dom, n, ranges]; // AbsoluteTiming
FindValue2[{hF1, {fA1, fB2, fC3}}, dom, n, ranges]; // AbsoluteTiming

{0.0018419, Null}

{0.001193, Null}
POSTED BY: Martijn Froeling

Thank you so much. I will work on your solution and update this post.

POSTED BY: Tomás Valencia

Thanks for reviewing the code and providing your help. The problem is that the code must work for arbitrary functions.

POSTED BY: Tomás Valencia

not really sure that you are actually wanting to find the functions. The code looks for a vector of 4 random numbers that when evaluated by a function stay within a range.

The function you are evaluating is

fA1[w1_, w2_, w3_, w4_] := 10 + w1 + w2 + w3 + w4
fB2[r1_, r2_, r3_, r4_] := 1 + r1 + r2 + r3 + r4
fC3[t1_] := 5*t1
hF1[fA1_, fB2_, fC3_] := (2*fA1)*(3*fB2)*(4*fC3)

FullSimplify[
 hF1[fA1[d1 + d2, d3, d1, d2], fB2[d1 + d2, d3, d1, d2], fC3[2*d1]]]

which evaluates to

240 d1 (1 + 2 d1 + 2 d2 + d3) (2 (5 + d1 + d2) + d3)

so:

f[{d1_, d2_, d3_, d4_}] := 
 240 d1 (1 + 2 d1 + 2 d2 + d3) (2 (5 + d1 + d2) + d3)

the input parameters are

n = 100
{min, max} = {1, 10^6};
ranges = {{1, 2}, {1, 2}, {1, 2}, {1, 2}};

so this would solve the problem in one line.

Column[{#, f[#]} & /@ Select[Transpose[RandomReal[#, n] & /@ ranges], min < f[#] < max &]]

or step by step

(*gerenrate the random vectors where each row of ds = {d1, d2, d3, d4}*)
ds = Transpose[RandomReal[#, n] & /@ ranges]
(*select the values for which each row of ds remains in the limits*)
sel = Select[ds, min < f[#] < max &]
(*show the output show the output, where it recomputes f again, which is not needed*)
Column[{#, f[#]} & /@ sel]
POSTED BY: Martijn Froeling

Thank you very much for reviewing my code. Precisely, I want to use functions whose inputs will not always be like this fA1[x1 + x2, x3, x1, x2], fB2[x1 + x2, x3, x1, x2], fC3[2*x1] I've been able to get it to work by removing Module and adding Clear[x1,x2,x3,x4] to the end, but I think there must be a better way to solve it.

GT5[fA1_,fB2_,fC3_,x1_,x1min_,x1max_,x2_,x2min_,x2max_,x3_,x3min_,x3max_,x4_,x4min_,x4max_,NN_]:=
{
selectedData = {};
LowerLimit = 1;
UpperLimit = 10000000;
selectedData = {};
Do[
{
x1 = RandomReal[{x1min, x1max}];
x2 = RandomReal[{x2min, x2max}];
x3 = RandomReal[{x3min, x3max}];
x4 = RandomReal[{x4min, x4max}]; 
If[
LowerLimit <= hF1[fA1, fB2, fC3] <= UpperLimit,
selectedData = AppendTo[selectedData, {x1,x2,x3,x4,hF1[fA1, fB2, fC3]}], 
0]
}, {n, NN}
];
Print[selectedData];
Clear[x1,x2,x3,x4];
}
POSTED BY: Tomás Valencia
Posted 2 years ago
POSTED BY: Eric Rimbey

I want to find if the functions fA1, fB2, fC3 are within the range LowerLimit <= hF1[fA1, fB2, fC3] <= UpperLimit, using RandomReal and save the matching values into the list selectedData. But using x1,x2,x3,x4 throws error. In Module I used the relations p1=x1, p2=x2,p3=x3,p4=x4 but it does not evaluate with those assignments.

POSTED BY: Tomás Valencia
Posted 2 years ago

When you define this:

hF1[fA1_,fB2_,fC3_]:= (2*fA1)*(3*fB2)*(4*fC3)

Are you using the argument names fA1 and so forth as just a mnemonic device, or are you expecting some actual computational link to the functions fA1 etc that you previous defined?

POSTED BY: Eric Rimbey
Posted 2 years ago

You didn't assign any values to D1, D2, etc. What were you expecting? Maybe you can explain what you're trying to achieve.

POSTED BY: Eric Rimbey
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard