OpenMP through std::set using iterator - c++

I have a mesh with huge number of segments, I want to apply filter and fill std::set set_, which is private member of class A. There is function called fill_vec() which is going to fill the vector using a for loop:
fill_set()
{
for(mesh::SegIterator it = A.beginSeg(); it != A.endSeg(); ++it )
{
mesh::Segment Seg_ = *it;
int SignP = 0;
int SignN = 0;
for(mesh::PointIterator itp = Seg_.beginPoint(); itp != Seg_.endPoint(); ++itp )
{
double old_, new_;
...
...
if( old_ > 0.0 && new_ > 0.0 )
SignP++;
if( old_ < 0.0 && new_ < 0.0 )
SignN++;
}
if( (SignP == 1 && SignN == 1) || (SignP == 1 && SignN == 2) )
{
set_.insert(Seg_);
}
}
I am trying peform above code in parallel using OpenMP and C++03. I saw some solutions like as this. Any other safe and neat solution?

Try changing from it != A.endSeg() to it < A.endSeg(). The problem with != is the loop is not countable. The compiler can't know for sure that the loop will ever end. Switching it to < should make it countable.

Related

Issue with function to check if tree is a BST

So I have a function to check if a tree is a bst(if every node only has smaller values on its left and larger values on its right). Every other function works and the problem is with this one (second one just calls helper). I think the issue has something to do with the recursive call root-left hitting null but I am not sure and even if it is not sure how to fix. Can add more code as needed. Any help is appreciated.
visual studio error i get is : R00t -> left was nullptr
other compiler: segmentation fault core dumped.
bool isBSThelper(TreeNode* R00t)
{
if (R00t == NULL)
return true;
//if (R00t->left != NULL && (R00t->info < R00t->left->info))
if (R00t->info < R00t->left->info)
return false;
//if (R00t->right != NULL && (R00t->info < R00t->right->info))
if (R00t->info > R00t->right->info)
return false;
return isBSThelper(R00t->left) && isBSThelper(R00t->right);
}
bool TreeType::isBST() const
{
return isBSThelper(root);
}
According to your comment
even with if (R00t->left != NULL || R00t->right != NULL) error persists
the problem would persist. Let me rewrite and iterate from there (since I can't comment to ask for clarification -new user). If your code was like
bool isBSThelper(TreeNode* R00t) {
if ( R00t == NULL )
return true;
if ( R00t->left != NULL || R00t->right != NULL ) {
if ( R00t->info < R00t->left->info )
return false;
if ( R00t->info < R00t->right->info )
return false;
}
return isBSThelper(R00t->left) && isBSThelper(R00t->right);
}
then you would potentially still encounter the same problem, since the expression
if (R00t->left != NULL || R00t->right != NULL) {
would still make this expression with values
R00t->left != NULL
but
R00t->right == NULL
evaluate to true.
One solution might be
To make sure R00T->left and R00t->right are either valid (pointing to a node) or NULL (preferably nullptr if you are using C++)
And code like this:
bool isBSThelper( TreeNode* R00t ) {
if ( R00t == NULL )
return true;
if ( R00t->left != NULL && R00t->info > R00t->left->info )
return false;
if ( R00t->right!= NULL && R00t->info > R00t->right->info )
return false;
return isBSThelper( R00t->left ) && isBSThelper( R00t->right );
}
And the problem would be no more. (1) is critical.
An additional note: Your code does not check
if (R00t->left != NULL && R00t->right!= NULL && R00t->left->info < R00t->right->info)
return false;
which is another property of a Binary Search Tree (or obviously using ">" instead of "<" here as you see fit).

OpenVR - IVRSystem::GetControllerState always returns empty structs

I've been following Kamran Bigdely-Shamloo's article on how to get positional information from the HTC Vive and it has worked well so far. My next step was to "listen" to button presses. I've read the documentation and it says here that all I need to do is query IVRSystem::GetControllerStateand it'll return a
"struct with the current state of the controller"
This struct however always contains variables that have the 0 value. The following function is called in a while (true) loop from the main function.
bool CMainApplication::HandleInput()
{
SDL_Event sdlEvent;
bool bRet = false;
while ( SDL_PollEvent( &sdlEvent ) != 0 )
{
if ( sdlEvent.type == SDL_QUIT )
{
bRet = true;
}
else if ( sdlEvent.type == SDL_KEYDOWN )
{
if ( sdlEvent.key.keysym.sym == SDLK_ESCAPE
|| sdlEvent.key.keysym.sym == SDLK_q )
{
bRet = true;
}
if( sdlEvent.key.keysym.sym == SDLK_c )
{
m_bShowCubes = !m_bShowCubes;
}
}
}
// Process SteamVR events
// Periodically returns an event of type 404 ("VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor)"
vr::VREvent_t event;
vr::VREvent_Controller_t controllerEvent;
std::chrono::milliseconds ms4;
while( m_pHMD->PollNextEvent( &event, sizeof( event ) ) )
{
ms4 = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
);
ProcessVREvent( &event);
printPositionalData(&event, ms4);
}
vr::VRControllerState_t state;
// Check every device attached, usually it's four devices
// Second if statement is never reached
for (int i = 0; i < 1000; i++) {
if (m_pHMD->GetControllerState(i, &state, sizeof(state))) {
dprintf("%d", i);
if (state.ulButtonPressed != 0 || state.unPacketNum != 0 || state.ulButtonTouched != 0) {
dprintf("Some action?");
}
}
}
dprintf("\n");
// Process SteamVR action state
// UpdateActionState is called each frame to update the state of the actions themselves. The application
// controls which action sets are active with the provided array of VRActiveActionSet_t structs.
vr::VRActiveActionSet_t actionSet = { 0 };
actionSet.ulActionSet = m_actionsetDemo;
vr::VRInput()->UpdateActionState( &actionSet, sizeof(actionSet), 1 );
m_bShowCubes = !GetDigitalActionState( m_actionHideCubes );
vr::VRInputValueHandle_t ulHapticDevice;
if ( GetDigitalActionRisingEdge( m_actionTriggerHaptic, &ulHapticDevice ) )
{
if ( ulHapticDevice == m_rHand[Left].m_source )
{
vr::VRInput()->TriggerHapticVibrationAction( m_rHand[Left].m_actionHaptic, 0, 1, 4.f, 1.0f, vr::k_ulInvalidInputValueHandle );
}
if ( ulHapticDevice == m_rHand[Right].m_source )
{
vr::VRInput()->TriggerHapticVibrationAction( m_rHand[Right].m_actionHaptic, 0, 1, 4.f, 1.0f, vr::k_ulInvalidInputValueHandle );
}
}
vr::InputAnalogActionData_t analogData;
if ( vr::VRInput()->GetAnalogActionData( m_actionAnalongInput, &analogData, sizeof( analogData ), vr::k_ulInvalidInputValueHandle ) == vr::VRInputError_None && analogData.bActive )
{
m_vAnalogValue[0] = analogData.x;
m_vAnalogValue[1] = analogData.y;
}
m_rHand[Left].m_bShowController = true;
m_rHand[Right].m_bShowController = true;
vr::VRInputValueHandle_t ulHideDevice;
if ( GetDigitalActionState( m_actionHideThisController, &ulHideDevice ) )
{
if ( ulHideDevice == m_rHand[Left].m_source )
{
m_rHand[Left].m_bShowController = false;
}
if ( ulHideDevice == m_rHand[Right].m_source )
{
m_rHand[Right].m_bShowController = false;
}
}
for ( EHand eHand = Left; eHand <= Right; ((int&)eHand)++ )
{
vr::InputPoseActionData_t poseData;
if ( vr::VRInput()->GetPoseActionData( m_rHand[eHand].m_actionPose, vr::TrackingUniverseStanding, 0, &poseData, sizeof( poseData ), vr::k_ulInvalidInputValueHandle ) != vr::VRInputError_None
|| !poseData.bActive || !poseData.pose.bPoseIsValid )
{
m_rHand[eHand].m_bShowController = false;
}
else
{
m_rHand[eHand].m_rmat4Pose = ConvertSteamVRMatrixToMatrix4( poseData.pose.mDeviceToAbsoluteTracking );
vr::InputOriginInfo_t originInfo;
if ( vr::VRInput()->GetOriginTrackedDeviceInfo( poseData.activeOrigin, &originInfo, sizeof( originInfo ) ) == vr::VRInputError_None
&& originInfo.trackedDeviceIndex != vr::k_unTrackedDeviceIndexInvalid )
{
std::string sRenderModelName = GetTrackedDeviceString( originInfo.trackedDeviceIndex, vr::Prop_RenderModelName_String );
if ( sRenderModelName != m_rHand[eHand].m_sRenderModelName )
{
m_rHand[eHand].m_pRenderModel = FindOrLoadRenderModel( sRenderModelName.c_str() );
m_rHand[eHand].m_sRenderModelName = sRenderModelName;
}
}
}
}
return bRet;
m_pHMD is initalized as follows:
vr::IVRSystem *m_pHMD;
....
m_pHMD = vr::VR_Init( &eError, vr::VRApplication_Background );
I must be doing something wrong because in the following snippet, the if statement is passed only for the first four iterations, which should be a controller, the vive tracker, the headset and the lighthouses. This tells me that I am able to access these states, but I am somehow not able to read the information.
for (int i = 0; i < 1000; i++) {
if (m_pHMD->GetControllerState(i, &state, sizeof(state))) {
dprintf("%d", i);
if (state.ulButtonPressed != 0 || state.unPacketNum != 0 || state.ulButtonTouched != 0) {
dprintf("Some action?");
}
}
I can't imagine its a bug, so my guess is that my configuration is faulty, or I'm doing the wrong query.
Any help is greatly appreciated!
Apparently I was making two mistakes.
Mistake #1 was that I was using the wrong sample file. I used hellovr_opengl from the OpenVr sample folder, but instead hellovr_dx12 was the working solution. It must have a different kind of configration as well, since I copied a function which was working into the hellovr_opengl project and there, it did not work! Then I copied the functions I added to the hellovr_dx12 project and was able to get the controller states of the Vive controller.
However, I wanted to get the states of the Vive Tracker, which didn't work. After some googling I found out about an issue with the current SteamVR driver, so I reverted it back to a beta hoftix, which solved the Vive Tracker issue for me.
You have to call;
vr::VRInput()->SetActionManifestPath

Not able to return out of recursion

I have the following piece of code. It aims at traversing the [attached screenshot] Tree structure in depth first manner.
As you can see, I am interested in the highlighted entry in green -> Has Class( DatasetType ) node of this tree structure. This Tree structure is subjected to additions of new nodes by customers. So, I have to traverse the Tree structure to find my node of interest. I have formulated the below code. But And I can see that it identifies that node of my interest.
However, it is not stopping there. It is proceeding onto the next sibling i.e., Has Class( EPMJob ). I want my processing to stop. I am pretty sure that my way of returning stuff is missing something. but not able to pin point.
Any inputs are most welcome.
tag_t findHasTypeDatasetNodeInAMTree( tag_t amTreeNode )
{
CharPointer nodeName;
Response stat = askRuleName( amTreeNode, &nodeName );
CharPointer nodeArgument;
stat = askRuleArg( amTreeNode, &nodeArgument );
if( tc_strcmp( nodeName.getString(), "Has Class" ) == 0 && tc_strcmp( nodeArgument.getString(), "DatasetType" ) == 0 )
{
return amTreeNode;
}
int numChildNodes = 0;
TagPointer childNodes;
stat = askChildren( amTreeNode, &numChildNodes, &childNodes );
if( numChildNodes == 0 )
{
return NULLTAG;
}
// The following is the piece that needs attention.
// Do not want to NULL check here though
for( int inx = 0; inx < numChildNodes; ++inx )
{
findHasTypeDatasetNodeInAMTree( childNodes[inx] );
}
return NULLTAG;
}
I'm not sure what this is doing:
for( int inx = 0; inx < numChildNodes; ++inx )
{
findHasTypeDatasetNodeInAMTree( childNodes[inx] );
}
But I'm pretty sure it doesn't stop when you find something so the result is ALWAYS NULLTAG. How about something like:
for( int inx = 0; inx < numChildNodes; ++inx )
{
auto result = findHasTypeDatasetNodeInAMTree( childNodes[inx] );
if( result != NULLTAG )
return result;
}

Settling values on an undirected graph

I have a graph that has values on nodes
value = A/B/C
values = { A , B , C }
Aim: Connected nodes must have same values post settling :
Example :
Pre settling :
node1 = { A, B }
node2 = { A, B, C }
node3 = { D }
Post settling :
node1 = { A, B ,C, D }
node2 = { A, B ,C, D }
node3 = { A, B ,C, D }
Settling algorithm:
Make pairs of nodes ( node1, node2 ) , ( node2, node3 ) etc.
didSomething = false
doWhile ( didSomething )
for ( iterate all pairs )
didSomething |= settle ( a-pair )
didSomething is true if ( node1.values != node2.values )
Problem: Some graph sets take TOO long to settle on.
prefferably not use idea of connected components , some nodes aquire values differently from others
> **gprof**
>
> SkipAcrossBlocks::PortSpreader::settle() [12] [13] 56.1 0.09
> 48.77 7367012 SkipAcrossBlocks::EdgePair::settle() [13]
> 0.03 45.78 7367012/7367012 bool std::operator=
> <SkipAcrossBlocks::OneJumpRecord,
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord>
> >(std::set<SkipAcrossBlocks::OneJumpRecord,
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord> > const&,
> std::set<SkipAcrossBlocks::OneJumpRecord,
> std::less<SkipAcrossBlocks::OneJumpRecord>,
> std::allocator<SkipAcrossBlocks::OneJumpRecord> > const&) [14]
SkipAcrossBlocks::OneJumpRecord = "value"
std::set < SkipAcrossBlocks::OneJumpRecord > " values "
gprof says
7*10^6 calls to compare equality on "values"
takes up most time.
settling on a pair of nodes for completeness:
bool EdgePair::settle() {
// if edge is internalRailORglobal should not aquire other rails
if ( edge1->cannotAquire() && edge2->cannotAquire() ) {
return false;
}
else if ( !edge1->cannotAquire() && edge2->cannotAquire() ) {
if ( edge1->superSetOf( edge2 )) {
return false;
}
edge1->spreadValues.insert( edge2->spreadValues.begin(), edge2->spreadValues.end());
return true;
}
else if ( edge1->cannotAquire() && !edge2->cannotAquire() ) {
if ( edge2->superSetOf( edge1 )) {
return false;
}
edge2->spreadValues.insert( edge1->spreadValues.begin(), edge1->spreadValues.end());
return true;
}
else {
// neither are internalORglobal
if ( edge1->spreadValues == edge2->spreadValues ) {
return false;
}
edge1->spreadValues.insert( edge2->spreadValues.begin(), edge2->spreadValues.end());
edge2->spreadValues = edge1->spreadValues;
return true;
}
}
Following equality comparison seems to be the one taking time :
if ( edge1->spreadValues == edge2->spreadValues ) {
return false;
}
I would be intersted in :
Can set comparison be made more effective
Other algorithms / ideas
prefferably not use idea of connected components , some nodes aquire values differently from others
Thanks
You essentially compute connected components but in a very inefficient way. Since your answer does depend on connected components it is unlikely you can find some algorithm not using them.
Good news is that connected components can be computed in very fast and efficient way, see example in Boost.Graph library: http://www.boost.org/doc/libs/1_55_0/libs/graph/example/connected_components.cpp
Your whole flow could be:
numComponents = boost::connected_components(G, componentsMap);
vector allValues(numComponents);
one pass over componentsMap to populate allValues
one pass over allValues to associate them with vertices
Complexity will be almost linear w.r.t. to graph size.

Pointers with STL maps and lists

I did do a good search on the 'net about this and turned up lots of help regarding vectors but not really anything on STL lists. I am attempting to erase a pointer from a list within a map. (a little tricky). I really want to use pointers and not revert to another (worse) system of doing things. I will show the code
bool RoomDB::removePlayer( int socketid, int roomid ) {
list<GamePlayer>::iterator itit;
for( itit == roomlist[roomid].playerlist.begin(); itit != itit.end(); itit++ ) {
if( itit.socketno == socketid )
itit.erase( itit );
}
I think it should just be like this:
roomlist[roomid].playerlist.remove_if(
[socketid](GamePlayer const & gp) { return gp.socketno == socketid; }
);
If you don't have lambdas, you'll have to write a little predicate yourself, or you go the manual way; but now beware of the loop:
for (std::list<GamePlayer>::iterator it = roomlist[roomid].playerlist.begin();
it != roomlist[roomid].playerlist.end(); /* no increment */ )
{
if (it->socketno == socketid)
{
it = roomlist[roomid].playerlist.erase(it);
}
else
{
++it;
}
}
There are a bunch of things wrong. I will try to list all of them, though I may miss some:
It should be list<GamePlayer*>::iterator itit; if, as you say, your lists contain pointers
It should be itit = roomlist[roomid].playerlist.begin();, not itit = ..., like KerrekSB said
It should be itit != roomlist[roomid].playerlist.end(), not itit != itit.end()
It should be if( (*itit)->socketno == socketid ), not if( itit.socketno == socketid ) (again, if your list contains pointers)
It should be roomlist[roomid].playerlist.erase(itit), not itit.erase(itit).