Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6000839
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T00:45:05+00:00 2026-05-23T00:45:05+00:00

I’m writing a path tracer in C++ and I’d like to try and implement

  • 0

I’m writing a path tracer in C++ and I’d like to try and implement the most resource-intensive code into CUDA or OpenCL (I’m not sure which one to pick).

I’ve heard that my graphics card’s version of CUDA doesn’t support recursion, which is something my path tracer utilizes heavily.

As I have it coded both in Python and C++, I’ll post some simplified Python code for readability:

def Trace(ray):
  hit = what_object_is_hit(ray)

  if not hit:
    return Color(0, 0, 0)

  newRay = hit.bouceChildRayOffSurface(ray)

  return hit.diffuse * (Trace(newRay) + hit.emittance)

I tried manually unrolling the function, and there is a definite pattern (d is diffuse and e is emittance):

Level 1:  d1 * e1 

Level 2:  d1 * d2 * e2
        + e1

Level 3:  d1 * d2 * d3 * e3
        + d1 * d2 * e2
        + e1

Level 4:  d1 * d2 * d3 * d4 * e4
        + d1 * d2 * d3 * e3
        + d1 * d2 * e2
        + e1

I might be wrong, though…

My question is, how would I go about implementing this code in a while loop?

I was thinking using something of this format:

total = Color(0, 0, 0)
n = 1

while n < 10:   # Maximum recursion depth
  result = magical_function()

  if not result:  break

  total += result
  n += 1

I’ve never really dealt with the task of unraveling a recursive function before, so any help would be greatly appreciated. Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T00:45:06+00:00Added an answer on May 23, 2026 at 12:45 am

    In a recursive function, each time a recursive call occurs, the state of the caller is saved to a stack, then restored when the recursive call is complete. To convert a recursive function to an iterative one, you need to turn the state of the suspended function into an explicit data structure. Of course, you can create your own stack in software, but there are often tricks you can use to make your code more efficient.

    This answer works through the transformation steps for this example. You can apply the same methods to other loops.

    Tail Recursion Transformation

    Let’s take a look at your code again:

    def Trace(ray):
      # Here was code to look for intersections
    
      if not hit:
          return Color(0, 0, 0)
    
      return hit.diffuse * (Trace(ray) + hit.emittance)
    

    In general, a recursive call has to go back to the calling function, so the caller can finish what it’s doing. In this case, the caller “finishes” by performing an addition and a multiplication. This produces a computation like
    d1 * (d2 * (d3 * (... + e3) + e2) + e1)). We can take advantage of the distributive law of addition and the associative laws of multiplication and addition to transform the calculation into [d1 * e1] + [(d1 * d2) * e2] + [(d1 * d2) * d3) * e3] + ... . Note that the first term in this series only refers to iteration 1, the second only refers to iterations 1 and 2, and so forth. That tells us that we can compute this series on the fly. Moreover, this series contains the series (d1, d1*d2, d1*d2*d3, ...), which we can also compute on the fly. Putting that back into the code:

    def Trace(diffuse, emittance, ray):
      # Here was code to look for intersections
    
      if not hit: return emittance                            # The complete value has been computed
    
      new_diffuse = diffuse * hit.diffuse                     # (...) * dN
      new_emittance = emittance + new_diffuse * hit.emittance # (...) + [(d1 * ... * dN) + eN]
      return Trace(new_diffuse, new_emittance, ray)
    

    Tail Recursion Elimination

    In the new loop, the caller has no work to do after the callee finishes; it simply returns the callee’s result. The caller has no work to finish, so it doesn’t have to save any of its state! Instead of a call, we can overwrite the old parameters and go back to the beginning of the function (not valid Python, but it illustrates the point):

    def Trace(diffuse, emittance, ray):
      beginning:
      # Here was code to look for intersections
    
      if not hit: return emittance                            # The complete value has been computed
    
      new_diffuse = diffuse * hit.diffuse                     # (...) * dN
      new_emittance = emittance + new_diffuse * hit.emittance # (...) + [(d1 * ... * dN) + eN]
      (diffuse, emittance) = (new_diffuse, new_emittance)
      goto beginning
    

    Finally, we have transformed the recursive function into an equivalent loop. All that’s left is to express it in Python syntax.

    def Trace(diffuse, emittance, ray):
      while True:
        # Here was code to look for intersections
    
        if not hit: break
    
        diffuse = diffuse * hit.diffuse                 # (...) * dN
        emittance = emittance + diffuse * hit.emittance # (...) + [(d1 * ... * dN) + eN]
    
      return emittance
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I would like to count the length of a string with PHP. The string
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I've got a string that has curly quotes in it. I'd like to replace
I have a French site that I want to parse, but am running into
I am currently running into a problem where an element is coming back from
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.