Grasshopper

algorithmic modeling for Rhino

Retrieve a specific value from a list which is the closest to some value?

I want to retrieve a specific value from a list which is the closest to some value.

For example I have a range of numbers from 0 to 10, divided by 10 steps.

I want to retrieve the value from the list which is closest to 7.49 (which will be 7).

How can I do that?

Thank you.

Views: 8672

Replies to This Discussion

in the sets tab there is a find similar component

This topic is also related to this one:

http://www.grasshopper3d.com/forum/topics/creating-a-c-component-wi...

But I seem to be having a problem with this closest to some value thing: values in my list are too small, up too 1 x 10^-30. The closest value I want to search for in that list is 1.25 x 10^-9

But Grasshoppers "find similar" component recognizes all of the values from the list, to be similar to 1.25 x 10^-9, because all of those values are in range from 0.1 to 1 x 10^-30.

Is there a way some kind of tolerance can be made, when it comes to recognizing a similar value?

Why not subtract the list of values to search from the target vale and sort on the smallest difference. 

I am not sure I understood you.

I need to subtract the 1.25 x 10^-9 from all values in the list, and then search for the smallest value (rest)?

Yes.

Technically the nearest value could be positive or negative so it would have to be the absolute value

abs(T-S(i))

Thank you Danny.

But I have a problem with the list from which I need to substract the 1.25 x 10^-9.

I am getting a list from a C# component, and component outputs it as a single string. This is why after trying to subtract 1.25 x 10^-9, Subtraction component gets following error message: "String could not be evaluated as an expression".

Any idea, how can I sort this list in a way it can be subtractable?

Attachments:

If you're going to use the values of the generated table, you'd better not code them into a compact list.

Define output slots for index, f0,... etc. and send out each of the values as individual list.

Thank you for the tip Hannes.

The problem is that, I do not know how to do that. Some other person wrote the C code for me.

um, yeah.

You know how to add outputs? Just right click and browse or use the zoomable UI. Add one for each of your tables values and name them as you like. Make sure you don't use the same names  for internal variables and input/output parameters. ("#" probably isn't a valid name so call it "i" for index or whatever else you like)

make sure, you set the type hint correctly and the parameter acces to List.

This line did create the output:

output = output + f0.ToString() + " " + f.ToString() + " " + ((int) n21).ToString() + " " + ((int) n22).ToString() + "\n";

 

But that created just one long string of data and not even a list for each row. Now that you have separate output slots, you can assigne them individually. We will use list access to store a new entry for each iteration

double _f0; //<- renamed internal variable

[...] <- your loop and all

i.Add(index); // this repalces the above output = ... line

f0.Add(f0); // this too....

[...] <- for all the rest of your variables.

Now you will have several outputs with each containing a list of data, representig a column of your table.

Thank you for the reply Hannes. But I am not sure I understood you.

This is the current code:

    double f0;
    double n21, n22, f;

    output = "# f0, f, n21, n22 \n";

    for (f0 = 1.0e-10; f0 <= 0.1; f0 = f0 * Math.Pow(10.0, 0.02))
    {
      n21 = -2.0 + Math.Floor(1.29 * Math.Pow(f0, -0.25));
      n22 = -2.0 + Math.Floor(0.373 * Math.Pow(f0, -0.25) * (12.0) * Math.Sqrt((n21 + 2.0) / (11.0 * n21 + 43.0)));
      f = (27.0 / 2.0) * f0 * Math.Pow(n21 + 2.0, -2.0) * Math.Pow(n22 + 2.0, -2.0);

      output = output + f0.ToString() + " " + f.ToString() + " " + ((int) n21).ToString() + " " + ((int) n22).ToString() + "\n";
    }

I need to replace it with this one:

    double _f0; //<- renamed internal variable

    double _f; //<- renamed internal variable

    double _n21; //<- renamed internal variable

    double _n22; //<- renamed internal variable

    output = "# f0, f, n21, n22 \n";

    for (f0 = 1.0e-10; f0 <= 0.1; f0 = f0 * Math.Pow(10.0, 0.02))
    {
      n21 = -2.0 + Math.Floor(1.29 * Math.Pow(f0, -0.25));
      n22 = -2.0 + Math.Floor(0.373 * Math.Pow(f0, -0.25) * (12.0) * Math.Sqrt((n21 + 2.0) / (11.0 * n21 + 43.0)));
      f = (27.0 / 2.0) * f0 * Math.Pow(n21 + 2.0, -2.0) * Math.Pow(n22 + 2.0, -2.0);

      i.Add(index); // this repalces the above output = ... line

      f0.Add(f0); // this too....

      f0.Add(f); // this too....

      f0.Add(n21); // this too....

      f0.Add(n22); // this too....

    }

And add "f","f0","n21","n22" as new output parameters?

Sorry, I never really use the script components. When I need to write some lines of code, Visual C# is just way more comfortable and just as fast to compile. (plus you get to have debugging features...)

Anyway, I just found out, you can't give type hints and data acces to script output parameters. So you need to create the Lists first on your own.

You want to have a separate Lsit for each data item, so you can send each list to a separate output slot.

The rest should be pretty self explanatory...

Attachments:

Works perfectly. Thank you Hannes, I owe you a couple of beers!

Greetings to the architecturally wonderful Saxony!

One more thing: The point of this topic, is that for a list of numbers created by C component, I am trying to find the one with closest "f" output value
of 1.25e-9.

Danny Boyes gave me above, two solutions for this problem:

a) to subtract the 1.25e-9 from output values of "f" and then to look for the minimum value.

But in that case, I am loosing the index number of the most minimum number. And I need that index number in order to obtain(retrieve) the values from other outputs, with the same index.

b) to use the Fsim(Find similar member) component.

I am having problem with this solution too, as Grasshopper is not getting the closest value for some reason. Take a look:

Fsim component identifies value of 1.2196 e-9 (index: 258) as the most similar one to 1.25e-9. Difference between this two numbers is: 0.0304.
But that is not the closest value to 1.25e-9. The closest value to 1.25e-9 is 1.2771 e-9 (index: 259), with difference of 0.0271.

I thought that maybe the reason for this was because my 1.25e-9 input is created with Panel. Therefor I tried using Number parameter, and also Number slider of 1.25 with Function component x*10^(-9), with Number slider value of 1.25 as an "x" input. Still the same thing happens in all three cases - I am getting the value of 1.2196 e-9 (index: 258) as the most closest one.


Any thoughts why is this happening?

Thank you.

Attachments:

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service