• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Nested for loop

Stats

  • Locked Locked
  • Replies 9
  • Subscribers 143
  • Views 16672
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Nested for loop

Leonardo Vinci
Leonardo Vinci over 5 years ago

A=list(

(1 2)

(6 2)

(8 2) 

(5 2) 

(7 2)

(3 2)

)

B=list(

(8 10)

(3 10)

(1 10) 

(5 10)

(7 10)

(6 10) 

)

I want to have a list C, whose 1st element from A matches the 1st element in B and make a list like the shown below :

C=list(

( (1 2) (1 10) )

( (6 2) (6 10) )

( (8 2) (8 10) )

( (5 2) (5 10) )

( (7 2) (7 10) )

( (3 2) (3 10) )

)

Note that the y elements of sublists of A and list B are 2 and 10 respectively, all same. Also, length of lists A and B are also same.

I have a nested "for" loop and "cons" to achieve C, but for some cases its not working. Can you help me in achieving this?

Maybe we can make use of map functions? mapcar/mapcan?

Thanks,

Leo

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago

    C=foreach(mapcar elem1 A
      list(
        elem1
        car(exists(elem2 B car(elem1)==car(elem2)))
      )
    )

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 5 years ago in reply to Andrew Beckett

    What about if i swap x and y like this:

    A=list(

    (2 1)

    (2 6)

    (2 8) 

    (2 5) 

    (2 7)

    (2 3)

    )

    B=list(

    (10 8)

    (10 3)

    (10 1) 

    (10 5)

    (10 7)

    (10 6) 

    )

    and want to have a list C, whose 2nd element from A matches the 2nd element in B and make a list like the shown below :

    C=list(

    ( (2 1) (10 1) )

    ( (2 6) (10 6) )

    ( (2 8) (10 8) )

    ( (2 5) (10 5) )

    ( (2 7) (10 7) )

    ( (2 3) (10 3) )

    )

    Note that the x elements of sublists of A and list B are 2 and 10 respectively, all same. Also, length of lists A and B are also same. Can you help me in achieving this using map functions?

    Also, please explain the use of mapcar (like what is it doing and in which situations to use mapcar functions).

    Thanks,

    Leo

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Leonardo Vinci

    Hi Leo,

    Very similar - it's just that the elements being compared change - so here using cadr rather than car to get the second elements in the lists.

    C=foreach(mapcar elem1 A
      list(
        elem1
        car(exists(elem2 B cadr(elem1)==cadr(elem2)))
      )
    )

    will do this. 

    A brief coverage of mapping functions. The various mapping functions, map, mapc, mapcar, mapcan, maplist, mapcon each accept a function of one or more arguments, plus as many lists as there are arguments to the function passed in as the first argument to the mapping function. The mapc, mapcar, and mapcan functions work on successive elements of the lists, whereas map, maplist and mapcan are passed successive lists. map and mapc return the original list (actually the first list), mapcar and maplist return a list constructed from the return values of the function called, and mapcan and mapcon expect the function called to return a list, and they then destructively concatenate all the returned lists together.

    Some examples:

    a='(1 2 3 4)
    b=mapc('println a)

    prints:

    1
    2
    3
    4

    and b is set to (1 2 3 4)

    b=map('println a)

    prints:

    (1 2 3 4)
    (2 3 4)
    (3 4)
    (4)

    return value is the same as with mapc.

    b=mapcar('minus a)

    returns (-1 -2 -3 -4) - as you can see, it applied the minus function to each element in the list and returned that.

    Anyway, the foreach form is a simple shorthand to avoid you having to define a function. If you don't provide the mapping function as the first argument, it's doing a mapc. If you do specify it, it behaves as with that mapping function. So:

    b=foreach(mapcar elem a elem**2)

    is the same as doing:

    procedure(myfunc(val)
      val**2
    )

    b=mapcar('myfunc a)

    The last thing in the body of the foreach is the return value used to assemble the list. These both return (1 4 9 16).

    So, to describe how the code above works, it loops over the first list (A), and then uses exists() to find if the first (or second) element of the sublist it is on matches the first (or second) element of anything in list B, and then builds a list of the A sublist and the found B sublist, and then assembles a new list based on these newly created pairs.

    I hope that helps?

    Regards,

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 5 years ago in reply to Andrew Beckett

    Thank you very much sir!

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 5 years ago in reply to Andrew Beckett

    For some reason in C, I am getting only 1st element as required, for rest elements I am getting nil Y. 

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Leonardo Vinci

    Presumably you've either made a mistake in copying the code, or are using different data, or have updated it to do something else. The code above works fine with your data.

    Perhaps you need to re-post the exact code you're using and the data you're using so we can spot the error?

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 5 years ago in reply to Andrew Beckett

    A=

    (

    (0.286 0.5835)
    (0.286 1.2585)
    (0.286 1.9335)
    (0.286 2.6085)

    )

    B=

    (

    (6.408 1.9335)
    (6.408 2.6085)
    (6.408 1.2585)
    (6.408 0.5835)

    )

    I want C as,

    C=

    (

    ((0.286 0.5835)(6.408 0.5835))
    ((0.286 1.2585)(6.408 1.2585))
    ((0.286 1.9335)(0.286 1.9335))
    ((0.286 2.6085)(0.286 2.6085))

    )

    Currently C is coming as,

    C=

    (

    ((0.286 0.5835)(6.408 0.5835)) 
    ((0.286 1.2585) nil) 
    ((0.286 1.9335) nil) 
    ((0.286 2.6085) nil)

    )

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 5 years ago in reply to Leonardo Vinci

    Most likely this will be due to some rounding error in how the numbers have been computed before lists A and B are created. If the numbers are entered literally, the code works. If the numbers come directly from points in the database, then the code would also work - this is because the database stores points as integers, and so they will be consistently converted to integers from floats.

    In general (see numerous posts on these forums, and on the internet as a whole in other languages) comparing floating point numbers in general with == is problematic because small rounding errors can lead to values that are very close but not identical. In the code below, I emulate the rounding error by adding tiny offsets to the numbers - this shows results as you were seeing. I then show two strategies for doing the comparison. The first is assuming that they are coordinates and converting them to integers (multiplying by the DBUPerUU) and comparing as integers. The second is using the nearlyEqual function which has a tolerance of 1e-9 in the comparison. If the numbers are really coordinates, the first approach is what I'd recommend; if they are generic floating point numbers, the second may be better (you can always alter the relative and absolute tolerances).

    ;------------------------------------------------------------------------
    ; Emulate a rounding error in the numbers
    ;------------------------------------------------------------------------
    err=1e-14
    A=
    list(
      list(0.286 0.5835) 
      list(0.286 1.2585) 
      list(0.286 1.9335) 
      list(0.286 2.6085)
    )
    
    B=
    list(
      list(6.408 1.9335+err)
      list(6.408 2.6085+err)
      list(6.408 1.2585-err) 
      list(6.408 0.5835)
    )
    
    C=foreach(mapcar elem1 A
      list(
        elem1
        car(exists(elem2 B cadr(elem1)==cadr(elem2)))
      )
    )
    
    ;------------------------------------------------------------------------
    ; If the numbers are corresponding to coordinates, compare as integers
    ;------------------------------------------------------------------------
    ; DBUPerUU=cv~>DBUPerUU
    DBUPerUU=2000.0
    D=foreach(mapcar elem1 A
      list(
        elem1
        car(exists(elem2 B round(cadr(elem1)*DBUPerUU)==round(cadr(elem2)*DBUPerUU)))
      )
    )
    
    ;------------------------------------------------------------------------
    ; More generic approach using nearlyEqual
    ;------------------------------------------------------------------------
    E=foreach(mapcar elem1 A
      list(
        elem1
        car(exists(elem2 B nearlyEqual(cadr(elem1) cadr(elem2))))
      )
    )
    
    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 5 years ago in reply to Andrew Beckett

    Thanks a lot Andrew. It seems that was the problem. Thank you! :)

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information