Finding the elements of an array in another array

Post Reply
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Finding the elements of an array in another array

Post by Antonio Linares »

This is an example of checking if the elements of an array are contained into another array:

Code: Select all | Expand

function Main()

   local a1 := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
                 { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
   local a2 := { { 0, 0, 0 }, { 1, 1, 1 } }
   local a, b
   
   for each a in a2
      for each b in a1
         if hb_jsonEncode( a ) == hb_jsonEncode( b )
            ? "found a2[" + Str( a:__enumIndex() ) "] in a1[" + Str( b:__enumIndex() ) + "]"
         endif
      next
   next      

return nil

You can run it here directly:
https://fivetechsoft.github.io/snippets?20210820071349

I wonder if we could make this code generic for n dimensions
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Re: Finding the elements of an array in another array

Post by Antonio Linares »

You may have noticed that a1 represents a 3D world cube (defined by eight 3D dots) and a2 represents a line (only two 3D dots)

When we search for a2 dots in a1, we are checking if such line exists into the cube :-)

The idea is that given a n 3D dots (a cloud of dots) we check if it contains another 3D object (another cloud of dots)

The target would be to detect a M dimensions object into another N dimensions object
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Re: Finding the elements of an array in another array

Post by Antonio Linares »

OpenAI GPT3 engine (Artificial Intelligence) assign a "dot" to each "word", so it creates a cloud of dots.

Finding a "pattern" is to recognize a sub cloud of dots in the main cloud.

Learning the basics for AI... :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Carles
Posts: 1149
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Been thanked: 7 times
Contact:

Re: Finding the elements of an array in another array

Post by Carles »

Hi AL,

I think we are specialists in creating management programs, and we are very good. But to enter the AI ​​world ... Maybe it takes many years to learn and be good at these techniques. it's an exciting world anyway, of course ... :D


C.
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Otto
Posts: 6403
Joined: Fri Oct 07, 2005 7:07 pm
Has thanked: 24 times
Been thanked: 2 times
Contact:

Re: Finding the elements of an array in another array

Post by Otto »

Image

Carles, I think you missed something.
Antonio has been involved with AI for a long time. For example, here is a photo of his speech about AI at the Fivewin / Harbour meeting in 2017.
He is an AI expert!

You should be there when Antonio show us with his AI program who the lady of the Fivewin sample is
Image

Olga from a James Bond film.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Carles
Posts: 1149
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Been thanked: 7 times
Contact:

Re: Finding the elements of an array in another array

Post by Carles »

Otto,

It's just a comment. I try not to miss anything, in fact I was in his talk in 2017 and I know that he is an AI specialist. Sometimes I think you are his manager... :D

C.
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

UT Page -> https://carles9000.github.io/
Forum UT -> https://discord.gg/bq8a9yGMWh
Skype -> https://join.skype.com/cnzQg3Kr1dnk
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Re: Finding the elements of an array in another array

Post by Antonio Linares »

My friends,

Trying to understand a little bit about it

just to get some basic concepts and share them :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Re: Finding the elements of an array in another array

Post by Antonio Linares »

Thanks to Cristobal and Rao (for hb_ValToExp() suggestion):

Code: Select all | Expand

function Main()

   local a1 := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
                 { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
   local a2 := { { 0, 0, 0 }, { 1, 1, 1 } }
   local a, b
   
   for each a in a2
      for each b in a1
         if hb_ValToExp( a ) == hb_ValToExp( b )
            ? "found a2["   Str( a:__enumIndex() ) "] in a1["   Str( b:__enumIndex() )   "]"
         endif
      next
   next      
   
   ? NCombinations( 8, 3 )

return nil

function NFactorial( n )

   local nResult  := 1
   local x
   
   for x = n to 1 step -1
      nResult := nResult * x
   Next x

return nResult

function NCombinations( n, m )

return nFactorial( n ) / ( nFactorial( m ) * nFactorial ( n - m ) )
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
nageswaragunupudi
Posts: 10721
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Been thanked: 8 times
Contact:

Re: Finding the elements of an array in another array

Post by nageswaragunupudi »

I do not know anything about AI.
Confining myself to the programming part relating to lines and cubes (3d geometry), purely out of academic interest.

We can use any of the functions hb_jsonEncode(), hb_ValToExp(), ValToPrgExp() of FW_ValToExp().
All these functions convert array to string making it easy for comparision.
The above samples test whether the line a2 starts and ends at two vertices of the cube a1 and also inform the vertex numbers. In these samples, the conversion function is called 8 x 2 x 2 = 32 times.
Following samples have the same functionality but call the conversion function only 3 times.

Code: Select all | Expand


function CubeAndLine1()

   local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
                    { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
   local aLine := { { 0, 0, 0 }, { 1, 1, 1 } }
   local cCube, ch, nVertex

   cCube    := hb_jsonEncode( aCube )
   ch       := Left( cCube, 1 )

   if ( nVertex := NumAt( ch, Left( cCube, At( hb_jsonEncode( aLine[ 1 ] ), cCube ) - 1 ) ) ) > 0
      ? "aLine starts at Vertex No: " + Str( nVertex, 2, 0 ) + " of the Cube"
   else
      ? "Start of aLine is not at any vertex of the cube"
   endif

   if ( nVertex := NumAt( ch, Left( cCube, At( hb_jsonEncode( aLine[ 2 ] ), cCube ) - 1 ) ) ) > 0
      ? "aLine ends at Vertex No: " + Str( nVertex, 2, 0 ) + " of the Cube"
   else
      ? "End of aLine is not at any vertex of the cube"
   endif

return nil

/*
// function NumAt() is from hbct.lib.
// In case hbct.lib is not linked, we can use this function
//
static function NumAt( c, cStr )

   local nAt    := 0
   local nCount := 0

   do while ( nAt := hb_At( c, cStr, nAt +  1 ) ) > 0
      nCount++
   enddo

return nCount
*/

 


Another variant:

Code: Select all | Expand


function CubeAndLine2()

   local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
                    { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
   local aLine := { { 0, 0, 0 }, { 1, 1, 1 } }
   local cCube, pt

   cCube    := hb_ValToExp( aCube )

   if ( pt := hb_ValToExp( aLine[ 1 ] ) ) $ cCube
      ? "aLine starts at Vertex: " + pt + " of the Cube"
   else
      ? "Start of aLine is not at any vertex of the cube"
   endif

   if ( pt := hb_ValToExp( aLine[ 2 ] ) ) $ cCube
      ? "aLine ends at Vertex: " + pt + " of the Cube"
   else
      ? "End of aLine is not at any vertex of the cube"
   endif

return nil
 


This logic works not only for cube/cuboid but also for any solid having any number of vertices.

I do not thik this is required.
Still for academic interest, if one likes to know if a Line is completely inside a cube/cuboid, this sample answers the question:

Code: Select all | Expand


function LineInCube()

   local aCube := { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 },;
                    { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 } }
   local aLine := { { 0.1, 0.2, 0.8 }, { 0.6, 0.4, 0.3 } }
   local aMin  := Array( 3 )
   local aMax  := Array( 3 )
   local c

   AEval( aCube, { |aVertex|
                  local n
                  for n := 1 to 3
                     if aMin[ n ] == nil .or. aMin[ n ] > aVertex[ n ]
                        aMin[ n ] := aVertex[ n ]
                     endif
                     if aMax[ n ] == nil .or. aMax[ n ] < aVertex[ n ]
                        aMax[ n ] := aVertex[ n ]
                     endif
                  next
                  return nil
                  } )


   if IsPointInside( aLine[ 1 ], aMin, aMax )
      c  := "Line starts inside the cube and "
      if IsPointInside( aLine[ 2 ], aMin, aMax )
         c  += "ends inside the cube"
      else
         c  += "ends outside the cube"
      endif
   else
      c  := "Line starts outside the cube and "
      if IsPointInside( aLine[ 2 ], aMin, aMax )
         c  += "ends inside the cube"
      else
         c  += "ends outside the cube"
      endif
   endif

   ? c

return nil

function IsPointInside( aPoint, aMin, aMax )
return ( aPoint[ 1 ] >= aMin[ 1 ] .and. aPoint[ 1 ] <= aMax[ 1 ] .and. ;
         aPoint[ 2 ] >= aMin[ 2 ] .and. aPoint[ 2 ] <= aMax[ 2 ] .and. ;
         aPoint[ 3 ] >= aMin[ 3 ] .and. aPoint[ 3 ] <= aMax[ 3 ] )

 


Now, this logic can be extended to check if a small cube/cuboid is fully enclosed by another larger cube/cuboid.

Logic: Check if both the min and max points of the small cube are in between the min and max points of the larger cube.

This logic works even with more complex solids with any number of vertices, but with one big exception.

Exception:
This logic works only if the larger solid is completely convex (convex at every vertex) and fails in case of concave solids.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Antonio Linares
Site Admin
Posts: 42521
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 31 times
Been thanked: 76 times
Contact:

Re: Finding the elements of an array in another array

Post by Antonio Linares »

No matter what you do, you are a Master

Thank you Rao
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply