Dr. Brown takes your phone calls on all subjects and answers some of your best e-questions on today's broadcast, his last show live from Nashville this week. Listen live here 2-4 pm EST, and call into the show at (866) 348 7884 with your questions and comments.
Dr. Brown's Bottom Line: Don't try to find out how far you can go without theoretically losing your salvation. Pursue the Lord with a whole heart, embrace holiness, and let Him keep you by His power.
Dr. Brown's Bottom Line: Let's not tamper with the foundations of society. If we do, we do so to our own harm.
We live in the strangest of times today. This play out of the Netanyahu is the same drama that the Democratic convention had when selecting their platform. What was revealed at the convention was that the Socialist party is about getting God out of our fabric of the American way. Also for partitioning the land of Israel and dividing Jurusalem. The news today is the insidious outgrowth of an anti God vision for the world that this current adminstration has. I support Netanyahu as the only significant leader today in the whole world with a voice. He is our Churchhill for this era. We need to reorient ourselves to the truth, which is in short supply at the moment.
TULIP dogma was not believed or taught in the ante-Nicene period of the church (first three centuries), particularly ULI. Anyone can discover this on his/her own by reading their writings.
David Bercot has done a tremendous amount of time-consuming, valuable research in this area. His audio teachings are now on YouTube, under Scroll Publishing.
I wasn't addressing TULIP, as my post above and my articles linked explain. And I'm not a Calvinist. I'm aware of David Bercot, and I have some of his books. I often use his Dictionary Of Early Christian Beliefs as a reference work. But his compilation of sources is incomplete, and he's wrong on some issues. If you think anything you've cited refutes what I've argued, you'll have to explain why.
Jason, thanks for the article on eternal security. I too am not a Calvinist, and see the scriptures teaching our eternal security.
Looking forward to reading the other articles.
Jason, I'm not going to read blog posts. If you'd like to support your argument with references from the ante-Nicene writings, with page or Kindle locations, I'd find that helpful. I'm only interested (at the present time) on the church before Augustine of Hippo.
Is it so strange if I find my security in the words that so often are all around the word "if"?
Not strange at all Ray if you find that security.
Meaning that you have found security, not that you find "that" security. My statement can be read two ways I think so I wanted to clarify.
Yes, I think God knows more about our security than we do. What we may think of as being our security, might be something else.
Somewhere the other day, on TV, someone was saying to another, something like, "So if I worry about being late, and do that often enough, then I should find myself showing up early?" That made sense to me.
Sometimes a little worry or concern isn't always a bad thing.


Nutricosmetics are nutritional supplements involved in structure & function of the skin. Micronutrients such as vitamin C, Omega-3 fatty acids, carotenes and flavonoids helps to protect the skin from various damages such as wrinkles, ageing of skin, UV protection and reduces the impact of free radicles. The first person to invent Nutricosmetics is the Swedish biochemist "Ake Dahlgren".


They were removed from a US Airways flight at Minneapolis-St Paul International Airport and questioned by police.
Six Muslim imams were removed from a US Airways flight at Minneapolis-St Paul International Airport and questioned by police for several hours before being released, a leader of the group said.
The six were among passengers who boarded Flight 300, bound for Phoenix, around 6:30 pm on Monday, airport spokesman Pat Hogan said.
The six Muslim scholars were returning from a conference in Minneapolis of the North American Imams Federation, said Shahin, president of the group. Five of them were from the Phoenix-Tempe area, while one was from Bakersfield, California, he said.
"I never felt bad in my life like that," he said. "I never. Six imams. Six leaders in this country. Six scholars in handcuffs. It's terrible."
Ibrahim Hooper, spokesman for the Washington-based Council on American-Islamic Relations, expressed anger at the detentions.


Drive Lamborghinis. In Italy. On ice.
For more experienced drivers, their avanzato program includes over-/understeering with a Gallardo LP 560-4, Gallardo LP 570-4 Superleggera, and Aventador LP 700-4. Then you'll learn how to drift, and hit a gymkhana course -- if you don't know what that is but you find yourself on it anyway, you'll definitely be living on a prayer.


text:
In botany: All other is apricot
imagine Before we put ourselves with a glass of sweet apricot spritzer mentally in the Wachau, to us, as we leave on a Church square, sitting on a summer day th
25 July 2020 Saturday 12:19
imagine Before we put ourselves with a glass of sweet apricot spritzer mentally in the Wachau, to us, as we leave on a Church square, sitting on a summer day the views along the blue-green Danube, through vineyards and fruit trees, needs to be clarified: Is the famous apricot the Wachau is really so much more than just a humble Austrian apricot?
Johanna Kuroczik
editor in the Department "science" of the Frankfurt General Sunday newspaper.
F. A. Z.
The "Original Wachau apricot" is a soft orange with red Speckles, and tastes particularly sweet, in spite of their acidic nuances. With a seal around 220 growers guarantee since 2003, in the Wachau region, only traditional varieties, the "klosterneuburger Marille to grow, mainly". The origin of the species Prunus armeniaca in China and Central Asia, with the support of the Roman Empire, the apricot is but since about two thousands of years in the lower Austrian valley home. Tags reigns Pannonian heat, which provides close to the forest area for cool nights: This game have a direct influence on the taste, says the EU document to the "protected designation of origin" of the Wachau apricot. However, the old varieties were sensitive, says Franz Reisinger, Chairman of the Association "Wachauer Marille PDO" – and Lord of more than 2000 trees. Take your white flowers usually in March. If it freezes then, again, ruined the harvest, so it was this year.
A bad year for the apricot
with the warm Winter, the trees bloomed early, a few days of cold air from Scandinavia in April, quite enough to keep the income in the summer of 2020, just five per cent of the usual amount of shrink. Last week the harvest began: several Times a day the farmers and their helpers pull the series through the tree, because the fruit must be picked at the right time. Optimal is when you can easily from the Branch to solve. "We harvest with the eyes," says Reisinger. The stone fruit tastes only until the next day really good, you can get muddy and is not worth more then to jam. Apricot is grow is always with risk, the white of the Fruit grower. In case of rain, the tires would burst of fruit on the trees, then the already maue harvest down the drain would be. 2020 is a very bad year for the apricots: this weekend the population of the Wachau to celebrate (along with Thousands of tourists) usually, the annual apricot festival, a folk festival on the Church square in Spitz. Particularly rich in tradition, the mayor praises it, even though it takes place only in 1951. However, between apricot not more dumplings, neat apricot brandy and Wachau wine to take care of such Details. Because of the Corona pandemic, the fruit sauce is now.
Updated Date: 25 July 2020, 12:19
1 Cycling: Ackermann sprints in Romania to victory 2 Freedom of the press in Brazil, Bolsonaro fails to 3 According to Corona infection: Bolsonaro is explained... 4 Nicholas Sandman: the students agree with the Washington... 5 After criticism for Hagia Sophia: The spoiled children... 6 Eintracht Frankfurt: an object of speculation in the... 7 Protests in Portland: Federal police used tear gas... 8 Controversial politician: AfD-the arbitration court... 9 The country garden show in Bad Homburg: The emergency... 10 Mobile Working: the Minister of labour for protection...
Magnetic bands on the rise: data storage without Limit
Power-efficient Supercomputer: A catalyst for the Internet
Social systems: Ideological trenches that do not exist so
Nasa announcement: the exciting new moon-discovery
Cause of stillbirth: When a pregnancy ends abruptly
Charles Barkley States NBA, NFL players Must Purchase...
Tips for Increasing Profit in an E-Commerce Business
Common Steps to Starting a New Business
Wedding Planning Pro Tips
Cycling: Ackermann sprints in Romania to victory

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: How to create a very dynamic and animated UI in android? I need to make an android app that has a very dynamic ui.
For example imagine we have an activity with only one button inside that in center. Then when someone clicks the button. The button converts to edittext. When user enters some text, the editText converts to textview. And then under the textview, two new buttons automatically Appear. This proccess will go on untill user create a binary-tree like structure. I want this kind of UIs.
I Hope you Undrestand My Problem.
My question is, how can i achieve this kind of UIs?
Can you give any suggestion?

A: It depends on what the requirements are, are we talking about simple animations like fading out and fading in, maybe some pulsation and then edit text appearance. It depends because it might be enough to use existing tools like using the ObjectAnimator or even xml or you will have to do some fancy stuff as in writing animation code that meets your particular requirements. Apart from that a factor is what versions of Android are you trying to support JellyBean and above or Lollipop and above.

redpajama_set_name: RedPajamaStackExchange


Medicated concealer helps clear and prevent blemishes. Gentle, soothing formula provides natural-looking coverage as blemishes heal.
Loose, lightweight powder for every skin type. Sets makeup; makes pores seem to disappear.
Achieve flawless complexion in just a click away with Quick Fix Care Concealer.
Containts Bisabolol(Chamomule Essential Oil extract) to care for sensitive skin.
Pink Beauty is a beauty retail enterprise founded in 2005. Ranging from hair care, skincare, make-up, fragrance, oral care, beauty supplements, Pink Beauty provides beauty care for everyone.
Copyright 2019, pinkbeauty.com.sg. All Rights Reserved.


Peoples Dental Clinic, Jagat Farm, Greater Noida offers best denture repairing at discounted flat price of INR 1000/-. We take responsibility of rectifying any error in your denture. The offer includes correcting any breakage, trimming, extensions, pinching points, polishing & finishing of denture, soft liner correction. You may consult our dentist for any problem in your complete denture.


There are few cocktails that are as approachable and easy to make as a Moscow mule. All it takes is three ingredients (vodka, ginger beer, and lime), some ice, and maybe even a copper mule mug and voila, it's cocktail time. With only three ingredients, though, they need to be high quality or you risk having a bad drink and a generally terrible time from there on out..
We've rounded up some of the tastiest (and also affordable) options for the next time you whip up these delicious cocktail at home. (But before you do, you may want to check out our guide to making Moscow mules and our top choices for ginger beer).
While Moscow mules aren't actually from Russia, it's fun to choose a Russian vodka as a star. Stolichnaya dates to the early 1900s and is made from wheat and rye. The Russians know their vodka, and Stoli is a full-bodied spirit with a subtle vanilla character with little burn.
Smirnoff is the brand that led to vodka passing whiskey as America's most popular spirit in the mid-20th century. Today, Smirnoff is one of the most recognizable vodkas and a solid choice for use in any cocktail thanks to its clean, slightly mineral taste.
Made with potatoes in Poland, Luksusowa vodka adds a bit of creaminess to the body of a Moscow mule. Expect a little minerality in the palate, but Luksusowa is a generally superbly clean vodka and leaves little behind, letting the ginger beer take over.
When the Ballast Point Brewing founders sold their beer brand to Constellation for $1 billion, they managed to keep their distillery. Now Cutwater Spirits, they make an excellent line of spirits that includes Fugu vodka. Fugu is named after the potentially deadly sushi fish, which leaves a nice numbness to the lips when prepared properly — similar to a strong mule.
Made in Iceland from glacial water and energy from geothermal heat, Reyka has more herbal and earthy notes than many other vodkas. Pour in some Reyka for an icy addition to a Moscow mule.
Based in Hawaii, Ocean Vodka Organic Farm and Distillery is committed to keeping the world clean. Made with sugar cane and desalinated ocean water, this vodka is clean with little to no taste and a silky, neutral finish perfect for cocktails.
The winner of our inaugural Spirit Awards in the Best American Vodka category, Highwater Vodka from Jackson Hole Still Works is produced from locally grown corn and oats for a soft, easy vodka — perfect for letting spicy ginger beer shine.
Made in Detroit, Michigan, Valentine Vodka is produced from a blend of grains (corn, wheat, and barley) and is a prime example of the spirit renaissance in the Motor City. Well-balanced, it is a great spirit for a variety of cocktails, mules included. Valentine was a runner-up in the Best American Vodka category in 2018's Spirit Awards.
There's a reason Tito's is one of the best-selling vodkas in the country (and the world). It is easy to drink and goes with everything. Tito's is known for philanthropic work with dogs, to boot, which is a big plus in our book.
Made from organic corn, Prairie Organic is a great option when you're looking for a smooth vodka that is made from high-quality ingredients. Easy on the palate, the creamy mouthfeel is a great complement to the other bright and spicy ingredients.
Article originally published February 27, 2018. Last updated March 7, 2019.


For a truly distinctive experience, select our bright, modern facility for your next event. Our spaces allow us to accommodate small, intimate events of less than 50 people, or large events of up to 500 guests.
Imagine an elegant cocktail party or a buffet dinner in our beautiful atrium, a private show in our state-of-the-art planetarium, a lecture or boardroom-style meeting in one of our classrooms, or a corporate meeting in our auditorium. Let our creative and talented special events staff assist you with your next event "Louisiana Art & Science Museum Style."
Please contact Event Coordinator Leslie Charleville at 225.344.5272, ext. 137 or at events@lasm.org.
Make it an event they'll remember...limited only by your imagination. We'll be delighted to assist you.
*Please note that Art & Science Museum facilities cannot be rented for weddings or wedding-related events.


Using floating wall shelves in the modern interior is a reasonable solution if you want to decorate your room and to an additional place for keeping different trifles. They are very interesting and unusual. It seems that they grow straight from the wall.
Decorative floating wall shelves will demonstrate your books, souvenirs, figurine, decorative plates, candles, flowers and photos. Such shelves can be made of different materials: wood, metal, glass, plastic material. They will surely suit to any design, but you should pay attention to the color and the shape.
There is some more pleasant information concerning this piece of furniture – the variety of colors. The most popular colors are: black, white, brown, natural wood color. But luckily today manufacturers offer great variety of colors and shapes and you will certainly choose the one you want. They can be not only one-colored, but also multicolored with different pictures of flowers and geometrical figures.
If you need modern floating wall shelves for keeping your things in a little room (bathroom, drawing-room), it is better to choose the light-hued ones and place them one above the other. It will help to save the space and keep many things. Dark color perfectly harmonizes with the light ones and makes the room official, but comfortable at the same time. Everything depends on your fantasy!


This is a collection of my videos or some other which I have appeared.
One could find me from 1:55. Little help: I wear jeans, light yellow sweather, shawl and sunglasses.
Duel is a Q&A show broadcasted by Slovak public television and radio (RTVS) which tests competitors knowledge in various topics. I appeared there 2 times - on 3.5.2013 and 6.5.2013.


text:
Macarthur 'looked like a basketball team' against Jets, says Milicic
Khabib may come out of retirement if …
Home Badminton Rio 2016: The Race Begins
Rio 2016: The Race Begins
Today begins the battle for places at the Rio 2016 Olympic Games, with badminton players worldwide plunging into the Olympic Qualification Period which ends 1 May, 2016.
The year-long quest to be among the elite competing at the first-ever Olympics on the South American continent will see athletes trying to earn enough points from BWF-sanctioned international tournaments, including BWF Major Events, the MetLife BWF World Superseries, Grand Prix Gold, International and Future events as well as Continental Championships.
The world ranking list of 5 May 2016 will determine who makes the cut and who misses out.
A few changes distinguish the 2016 Olympics competition from previous editions. A maximum of two players per NOC (National Olympic Committee) is allowed in each event, which means the total quota for each NOC will be 16 (8 men and 8 women) compared to 18 at London Olympics 2012.
The host's quota is restricted to one player in either singles categories; each group in singles will contain a minimum of three players, and the group stages of the competition will be followed by a draw for the knockout stage. An NOC can field two players/pairs if both are ranked in the top 16 in singles and in the top 8 in doubles.
The total quota for badminton (including Host Country places and Tripartite Commission Invitation places) is 172.
Of this, 164 (82 each for men and women) are qualification places; two are Host Country places and six (three each for men and women) are Tripartite Commission Invitation places. All athletes must have played in a minimum of three tournaments in their respective event, counting towards the world rankings lists, during the Olympic qualifying period.
The Tripartite Commission awards a select number of places to help promote the fundamental Olympic principle of universal representation. These are given to NOCs with few or no qualified athletes, to participate in the Olympic Games. These places provide the NOCs, whenever possible, with the opportunity to be represented at the Olympic Games by the best athlete from their country.
The list of initially qualified athletes for each event (including Continental Representation places, Host Country places and Tripartite Commission Invitation places) will be published as part of the world ranking lists of 5 May 2016.
The lists will be used to allocate 34 individual quota places for men and 34 individual quota places for women to the highest ranked athletes, respecting the maximum quota allocation per NOC per event. The 34 quota places will include the Continental Representation places.
In each singles event, there will be at least one athlete from each of the five BWF continental confederations. If a continental confederation has no singles athlete qualified in an event, the highest ranked athlete in that continent will become eligible (a host country place is separate from the Continental Representation place).
No NOC can qualify athletes/pairs in more than two events through the Continental Representation place system. If an athlete qualifies (and is selected) in more than one event, the resulting unused quota place will be allotted to the next best ranked eligible athlete of the same gender in the singles event of the world ranking list of 5 May 2016.
The number of quota places in the three doubles events is 48 (16 pairs each in Men's Doubles, Women's Doubles and Mixed Doubles), including the Continental Representation places.
No NOC can qualify athletes/pairs in more than two events through the Continental Representation Place system. Each doubles event is required to have at least one pair from each of the five BWF continental confederations.
Previous articleNine Teams Face Final Push for Knockout Stage Places
Next articleADT hopefuls eye glory at PGM Sabah Championship
Khairul Izuan tidak rela 'panaskan kerusi simpanan'
Zii Jia tepati ramalan, Soniia, Kisona tersingkir
Malaysia akan hantar pasukan B19 ke Sukan SEA 2021


text:
Oyster Mythbusting: Debunking 5 Common Misconceptions
Julie Qiu
Julie Qiu is an oyster expert that has been featured in Vogue, Food & Wine, the Chicago Tribune, and on Somebody Feed Phil on Netflix. Her blog, In a Half Shell, was a 2019 Saveur Blog Awards finalist.
Raw oysters: whether or not you're a fan, you've probably made up your mind about them one way or another. But how much do you really know? Surprisingly, there are a lot of misconceptions out there about these enigmatic bivalves. With oyster popularity on the rise, it's time we set the record straight.
Myth #1: The bigger or more expensive the oyster, the better it must be.
When it comes to accurately evaluating an oyster's quality, size and price aren't big factors. According to Shane Covey, co-owner of Upstate Craft Beer & Oyster Bar, time is actually the variable that matters most. "My buying protocol is to seek out the freshest. Like any commodity that is alive, it has a shelf life and it immediately starts to depreciate in value as time passes. As far as size is concerned, I have found customers who like a bigger bang for their buck, but size has nothing to do with an oyster's flavor profile. I carry over 24 different types, and compartmentalizing them into bigger-is-better just doesn't fit."
So how do you determine freshness? Ask your fishmonger or oyster shucker about the harvest date. It can be found on the bag tag, which is a slip of paper that comes in every bag of oysters. Growers are required to provide them and sellers are required to keep them on hand.
Myth #2: Oysters are delicious, but not that nutritious.
Worried that raw oysters are high in calories, cholesterol, and heavy metals? This will help put your mind at ease. Oysters were previously thought to contain high amounts of cholesterol, but new methods of calculating cholesterol levels have actually removed oysters from the hit list. In fact, Dr. Denise Skonberg, Associate Professor at the University of Maine's School of Food and Agriculture assures me that oysters are a healthy food! "I consider them a powerhouse of micronutrients, including zinc, iron, and vitamin B12. They are definitely not high in calories; a 3 ounce serving of raw Eastern oysters has only about 45 calories. That amount has about a week's worth of the daily zinc requirement and about 5 days worth of the B12 requirement for adults. Oysters are also an excellent source of the very bioavailable heme iron."
At this rate, your wallet is more likely to suffer around oysters before your health ever does.
Myth #3: Raw oysters are not safe to eat during months without the letter R.
"The enigmatic R rule is perhaps the most widely known, and most misunderstood, oyster myth of them all"
The enigmatic R rule is perhaps the most widely known, and most misunderstood, oyster myth of them all. Although it once served a purpose, the policy is pretty much defunct now. Sandy Ingber, Executive Chef of the Grand Central Oyster Bar helps explain why. "The warmer, non-'R' months, are when oysters spawn. Spawning oysters are not actually harmful to eat, they just aren't palatable."
The R rule once helped to give wild oysters time to repopulate. But these days, many varieties have instead been bred to not spawn at all, allowing them to be harvested and consumed year-round.
One important caveat is that warmer-than-average water temperatures have increased the prevalence of vibrio vulnificus. The pathogen, which some oysters have been found harbor, can indeed make people sick. But incidences of illness are carefully monitored by the USDA and harvesting policies have become much stricter than before. "So one, if not the most important thing for the consumer to know, is to only buy oysters from retailers or restaurants that sell products from certified waters," says Chef Ingber. Now that's a sensible rule to abide by, R month or not.
Myth #4: Eating oysters is bad for the environment.
Oyster reefs are amazing structures that provide a natural habitat for marine life and help clean our water. So by eating them, aren't we actually doing damage to the environment? The truth is that 98% of all oysters we consume are farm-raised, and much of the industry has modernized their operations to leverage sustainable aquaculture methods. Matt Gregg, owner of Forty North Oyster Farm in Mantoloking, New Jersey is among the thousands of oyster farmers along the East Coast looking to make a difference. "We're seeing a renaissance of ambitious salt-of-the-earth entrepreneurs, growing oysters in an environmentally sustainable way. Oyster aquaculture is different than let's say, tilapia aquaculture; there is no input. I don't feed my oysters anything. They actually eat a food that created the whole problem: algae. For my farm, by the time an oyster is ready to go to market, it could have filtered up to 40k gallons of water. That's just one oyster!"
While it sounds counterintuitive, consuming oysters actually helps the environment. It keeps the bivalves' biggest advocates in business, which means cleaner bays! (So eat more oysters!)
Myth #5: Oysters pair best with Champagne or wine.
Oysters and cold Champagne, Sauvignon Blanc, or Chablis are classic pairings, but by no means are they the be-all-end-all of "merroir-terroir" matchmaking. There's a growing preference for oyster and beer pairings (check out our suggestions here), but my personal favorite is well-matched selection of oysters and sake. "The brilliance of the oyster and sake pairing is that the combination brings out the creaminess and minerality of the oyster as it picks up on the similar elements in the sake," sake expert Monica Samuels explains. "In general, West Coast oysters are far more successful with sake than East Coast, as sake does have a brininess that can overemphasize the saltiness in an oyster. One great pairing is Takatenjin "Soul of the Sensei" Junmai Daiginjo with a creamy West Coast oyster with notes of melon. This sake has upfront qualities of green melon with a creamy, slightly lactic quality on the finish—they are super elegant together."
Not a sake fan? We've got a handy guide to oyster pairings right this way!
More Oyster Reading
Knife Skills: How to Shuck an Oyster
5 Great Oyster Joints in New Orleans
A Comprehensive Guide to Buying Better Shrimp
A Guide to Clam Types and What to Do With Them
The Shrimp Industry Is Dirty. Can New Farming Technology Clean It Up?
All About Geoduck: The Life of a (Delicious) Oversized Mollusk
Pacific Razor Clams: How to Catch, Clean, and Cook Them
How to Clean and Debeard Mussels
5 Tea Myths That Need to Disappear
This Small West Coast Oyster Is Making a Big Comeback
How to Stock a Japanese Pantry: 13 Indispensable Ingredients
Debunking Thai Food Myths With Pok Pok's Andy Ricker
Seafood Fraud: The Turning Tides of an Industry Epidemic
How to Serve Raw Oysters at Home
What Is Coffee's Carbon Footprint?
Classic Beer and Food Pairings: Do They Really Work?
The Food Lab's Reading List, Day 10: The River Cottage Cookbook
What You're Really Getting When You Buy Parmesan Cheese in America


text:
\section{Introduction}

Adequate semigroups form a class of semigroups in which the cancellation properties
of elements are reflected in the cancellation properties of idempotents.
They form a natural common generalisation of inverse semigroups and cancellative
monoids. Their importance was first recognised by Fountain
in the 1970's \cite{Fountain79}, but for many years their study was restricted by
a lack of applicable methods. In the last few years, interest has been
reawakened by the development of several new techniques and results
(see for example \cite{Araujo11,Branco09a,Gomes09,
K_freeadequate,K_onesidedadequate}).

\textit{Free algebras} form a natural focus of attention when studying any class of algebras
in which they exist; indeed, an understanding of the free objects in a class of algebras usually
yields considerable information about the class as a whole. In the case of adequate semigroups,
the fact that free adequate semigroups of every rank exist follows from
elementary principles of universal algebra (see for example \cite[Proposition~VI.4.5]{Cohn81}),
but an explicit description proved elusive until recently. In \cite{K_freeadequate}, the first
author gave a concrete geometric realisation of the free adequate semigroups (and monoids),
inspired by Munn's celebrated representation of the free inverse semigroups, in terms of directed,
labelled, birooted trees under a natural combinatorial multiplication operation. In \cite{K_onesidedadequate} he showed further
that the certain natural subsemigroups are the free objects in the
related categories of \textit{left adequate} and \textit{right adequate}
semigroups (and monoids). The free left, right and two-sided adequate semigroups also
turn out to be free objects in the larger classes of left, right and two-sided
\textit{Ehresmann semigroups} \cite{Branco09a,Gomes09,Lawson91}.

This representation immediately gave rise to a non-deterministic
polynomial-time
algorithm for the
word problem in finite rank free adequate semigroups and
monoids (and hence also in finite rank free left adequate and right adequate
semigroups and monoids). Since a relation holds in a free algebra in a category
exactly if the corresponding identity holds in \textit{all} algebras in the
category, this also yields an algorithm to check whether a given identity
holds in all adequate (or left adequate or right adequate) semigroups or
monoids.
This algorithm has proved surprisingly practical for human application to
short words, with the intuitive geometric nature of the representation
often allowing an effective use of guesswork to circumvent the issue
of non-determinism. However, a non-deterministic algorithm is clearly
not well-suited to computer implementation for larger words, and it would
also be more satisfactory for theoretical reasons to know the precise
asymptotic complexity of the problem.

In this paper, we apply some ideas from constraint satisfaction theory
to refine the algorithm into a deterministic form, thus showing that the
word problems for free adequate, free left adequate and free adequate
semigroups and monoids, and hence also the problem of checking whether identities hold
for all adequate semigroups or monoids, are decidable in quadratic (in the
RAM model of computation) time. Moreover, we show how to efficiently (again, in quadratic
time in the RAM model) compute normal forms (either trees
or words) for elements of the free adequate semigroup or monoid.

\section{Preliminaries}\label{sec_prelim}

In this section we very briefly recall the definitions of (left, right and two-sided) adequate
semigroups, and the first author's characterisation of the free (left, right
and two-sided) adequate semigroups monoids. The reader seeking a more complete
introduction with examples is referred to \cite{Fountain79} for adequate semigroups in general and
\cite{K_freeadequate} for free adequate semigroups and monoids.

Let $S$ be a semigroup whose idempotent elements commute. Denote by $S^1$ the
monoid consisting of $S$ with a new identity element $1$ adjoined. Then $S$ is
called \textit{left adequate} if for every element $x \in S$ there
is an idempotent element $x^+ \in S$ such that
$a x = bx \iff a x^+ = b x^+$ for all $a, b \in S^1$. If $S$ is left adequate then
the choice of $x^+$ is uniquely determined by $x$, and it is usual to
consider $S$ as a $(2,1)$-algebra with the binary operation of multiplication
and the unary operation $x \mapsto x^+$. In particular, we restrict attention
to morphisms respecting both operations.
Dually, $S$ is \textit{right adequate} if for every $x \in S$ there is an
idempotent $x^*$ with $xa = xb \iff x^* a = x^* b$ for all $a, b \in S^1$;
right adequate semigroups are also $(2,1)$-algebras. The semigroup $S$ is
called \textit{(two-sided) adequate} if it is both left adequate and right
adequate; the two maps $x \to x^+$ and $x \to x^*$, which in general will
be different, make $S$ into a $(2,1,1)$-algebra.

Now let $\Sigma$ be an alphabet. A \textit{$\Sigma$-tree} (or just
a \textit{tree} if the alphabet $\Sigma$ is clear) is a finite
directed graph with edges labelled by letters from $\Sigma$, whose
underlying undirected graph is a tree, together
with two distinguished
vertices (the \textit{start} vertex and the \textit{end} vertex) such that
there is a (possibly empty) directed path
from the start vertex to the end
vertex. The (unique) simple path from the start vertex to the end vertex
is termed the \textit{trunk} of the tree; vertices and edges lying on it are
called \textit{trunk vertices} and \textit{trunk edges} respectively. If
$e$ is an edge in such a tree, we denote by $\alpha(e)$,
$\omega(e)$ and $\lambda(e)$ respectively the source vertex, target vertex
and label of $e$. We say that a vertex $v$ is a \textit{descendant} of a vertex
$u$ if the unique simple undirected path between $v$ and the start vertex passes
through $u$.

As a notational convenience, we let $\Sigma' = \lbrace j' \mid j \in \Sigma \rbrace$
be an alphabet disjoint from and in bijective correspondence with $\Sigma$, and say
that a $\Sigma$-tree $X$ has \textit{an edge from $u$ to $v$ labelled $j'$} to mean that
it has an edge from $v$ to $u$ labelled $j$. (Intuitively, the elements of $\Sigma'$ can
be thought of as labelling directed edges when read ``in the wrong direction''. This
notation will allow a unified consideration of labels and directions of edges;
since label and direction play similar roles as obstructions to a morphism mapping one
edge to another, considering them together simplifies our arguments in several places.)

A \textit{morphism} $\rho : X \to Y$ of $\Sigma$-trees $X$ and $Y$ is a
map taking edges to edges and vertices to vertices which commutes with
$\alpha$, $\lambda$ and $\omega$ and maps the start and end vertex of $X$
to the start and end vertex of $Y$ respectively. An \textit{isomorphism} is a
morphism which is bijective on both edges and vertices. A \textit{retraction} is
an idempotent morphism from a $\Sigma$-tree to itself; its image is called a \textit{retract}.
A tree is called \textit{pruned} if it does not admit a
non-identity retraction. (Structures without retractions are often called
\textit{cores} in graph theory.)

The $\Sigma$-tree with a single vertex and no edges is called \textit{trivial}.
The set of all isomorphism types of $\Sigma$-trees (including the trivial
$\Sigma$-tree) is denoted $UT^1(\Sigma)$
while the set of isomorphism types of non-trivial $\Sigma$-trees is
denoted $UT(\Sigma)$. The set of all isomorphism types of pruned trees
[respectively, non-trivial pruned trees] is denoted $T^1(\Sigma)$
[respectively, $T(\Sigma)$]. For any $X \in UT^1(\Sigma)$ there is a unique
$Y \in T^1(\Sigma)$ which is isomorphic to a retract of $X$ \cite[Proposition~3.5]{K_freeadequate};
we denote this pruned tree $\ol{X}$ and call it the \textit{pruning} of $X$.

If $X, Y \in UT^1(\Sigma)$ then the \textit{unpruned product} $X \times Y$ is (the isomorphism type of)
the tree obtained by glueing together $X$ and $Y$, identifying the end vertex
of $X$ with the start vertex of $Y$ and keeping all other vertices and
all edges distinct; this is a well-defined, associative binary operation
\cite[Proposition~4.2]{K_freeadequate}. If
$X \in UT^1(\Sigma)$ then $X^{(+)}$ is (the isomorphism type of) the tree with
the same labelled graph and start vertex of $X$, but with end vertex of $X^{(+)}$ the
start vertex of $X$.
Dually, $X^{(*)}$ is the isomorphism type of the idempotent tree with the
same underlying graph and end vertex as $X$, but with start vertex the end vertex of $X$.
We define corresponding \textit{pruned operations} on $T^1(\Sigma)$ by
$XY = \ol{X \times Y}$, $X^* = \ol{X^{(*)}}$ and $X^+ = \ol{X^{(+)}}$.

A tree with a single edge and distinct start and end vertices is called a
\textit{base tree}; we identify each base tree with the label of its
edge, thus viewing $\Sigma$ itself as a set of $\Sigma$-trees.
The main
result of \cite{K_freeadequate} is that $T^1(\Sigma)$ is the free adequate monoid
on $\Sigma$, being freely generated under pruned multiplication, $*$ and $+$ by the base $\Sigma$-trees
\cite[Theorem~5.16]{K_freeadequate}. The map
$X \to \ol{X}$ is a $(2,1,1,0)$-morphism from $UT^1(\Sigma)$ onto $T^1(\Sigma)$
\cite[Theorem~4.5]{K_freeadequate}.
Moreover, the submonoid of $T^1(\Sigma)$ generated by the base trees under pruned
multiplication and $*$ [respectively, $+$] is the free left adequate [respectively,
right adequate] monoid on $\Sigma$ \cite[Theorem~3.18]{K_onesidedadequate}. Free
adequate, left adequate or right adequate semigroups can all be obtained by discarding
the trivial tree (which is the identity element) in the corresponding monoids
(see \cite[Proposition~2.2]{K_freeadequate} and \cite[Proposition~2.6]{K_onesidedadequate}).

\section{Computing with Formulas and Trees}\label{sec_exptree}

In this section we study the computational complexity of converting between
well-formed formulas, over a generating set $\Sigma$ and the binary and unary
operations in an adequate semigroup, and $\Sigma$-trees. This will allow
us, in later sections, to use algorithms operating on $\Sigma$-trees to
solve computational problems involving formulas.

For our complexity
analysis throughout this paper, we shall work in the RAM
model of computation, in which integer operations and indirection
(finding a value stored at a known position in an array) take unit time.
For simplicity we will analyse
the complexity of problems for a fixed rank semigroup, say on an alphabet
$\Sigma$, rather than the uniform complexity as the rank grows.
In places where it is necessary to be formal, we shall regard formulas as
words over the alphabet $\Omega$ consisting of generators from $\Sigma$ plus
the symbols
$($, $)$, $*$ and $+$ with the obvious meaning. We denote by $\Omega^*$
the set of all words over the alphabet $\Omega$, including the empty word
which we denote $\epsilon$. Our measure of the size of an expression will
be its length as a word over $\Omega$.

We assume
$\Sigma$-trees are by default stored as a natural number representing the
start vertex, a natural number representing the end vertex
and a list of edges (in no particular order), each
being a triple consisting of a label from $\Sigma$ and two natural numbers
encoding its start vertex and its end vertex. Sometimes it
will be expedient to convert trees to an alternative
representation. Note that the same abstract $\Sigma$-tree can admit
multiple representations, by numbering the vertices and ordering the edges
differently. Our measure of the size of a $\Sigma$-tree will be the
number of edges.

\begin{proposition}\label{prop_exptotree}
Given a well-formed formula $\omega$, one can compute in quadratic time
the (unpruned) $\Sigma$-tree which is its evaluation in $UT^1(\Sigma)$.
Moreover, this tree has size linear in the length of $\omega$.
\end{proposition}
\begin{proof}
A formula of length $n$ can be evaluated by a depth-first traversal
of a parse tree; this will clearly involve performing at most $n$ unpruned
operations with trees whose size is $O(n)$.
Clearly the unpruned $(+)$ and $(*)$ operations on trees can be performed
in constant time. Unpruned multiplication of trees can be performed in
time linear in the number of edges in the trees, by first relabelling
the vertices in the second tree (so that all references to its start
vertex become the end vertex of the first tree, and all its other vertices
are distinct from those in the first tree) and then concatenating the edge
lists and setting start and end vertices appropriately.

Thus, the $O(n)$ unpruned operations can each be performed in $O(n)$ time,
and the evaluation of the expression takes time $O(n^2)$.
Moreover, the resulting tree clearly has exactly one edge for each
occurrence of a generator in the expression, and hence has size linear
in the size of the expression.
\end{proof}

For our present purpose, the computations we wish to perform with
trees will all take quadratic time, so there is no particular benefit in
being able to compute the trees in faster than quadratic time.
However, we remark that the complexity of the algorithm given above can be
improved by a more sophisticated approach, using what is known in the computer science literature as a
``Union Find'' algorithm. Under this approach, when
performing multiplication, instead of merging the end vertex of one
tree with the start vertex of another, we keep them separate (allowing
the data structure to become a forest, rather than a tree) and
maintain another data structure recording which vertices are to be
merged at the end. An efficient implemention of this algorithm is extremely
close to being linear time; see \cite[Section~21.3]{Cormen01}
for more details.

Next, we shall show how a (not necessarily pruned) $\Sigma$-tree can be efficiently
converted into an well-formed formula.
We will define a function $\sigma : UT^1(\Sigma) \to \Omega^*$ such
that for each tree $X$, $\sigma(X)$ is a well-formed formula which
evaluates to $X$
in $UT^1(X)$, and then show that this function can be computed in quadratic time.
Note that since $\sigma$ is a function defined on abstract trees, the
algorithm produces a formula depending only on the abstract tree,
and not on its representation. We shall exploit this in
Section~\ref{sec_normalforms}
below
to compute normal forms (as formulas) for elements of the free adequate
semigroup.
To do this, we shall need a linear order on the set of all
formulas; for now, we will assume that we have such an order fixed. We
will discuss the choice and implementation of this order when we come to
analyse the complexity of the algorithm.

Let $X$ be a tree. We begin by defining a function $\rho$
from the vertex set of $X$ to $\Omega^*$; this is done inductively
by downwards induction on the distance of the vertex from the trunk.
Let $v$ be a vertex, and suppose $\rho$ is already defined on all vertices
strictly further from the trunk than $v$. Let
$v_1, \dots, v_p$ be the vertices adjacent to $v$ and strictly further from
the trunk, noting that $\rho(v_i)$ is already defined for each $i$.
For each $i$, let $e_i$ be the edge connecting $v$ to $v_i$,
and let $a_i \in \Sigma$ be its label. Define a formula $\tau_i \in \Omega^*$
by:
$$\tau_i = \begin{cases}
 (a_i \rho(v_i))+ &\textrm{ if $e_i$ is orientated away from $v$} \\
 (\rho(v_i) a_i)* &\textrm{ if $e_i$ is orientated towards $v$}
\end{cases}$$
Now we define $\rho(v) \in \Omega^*$ to be the word obtained by sorting the words
$\tau_i$ according to our ordering of formulas, and then concatenating.
(If $p = 0$, that is, if $v$ is a ``leaf'', this means $\rho(v) = \epsilon$.)

Now let $t_0, \dots t_q$ be
the trunk vertices of $X$ and $b_1, \dots, b_q$ the labels of the edges between
them, both in the obvious order. We define
$$\sigma(X) = \rho(t_0) b_1 \rho(t_1) b_2 \dots \rho(t_{q-1}) b_q \rho(t_q).$$

A simple but tedious inductive argument, akin to those in \cite{K_freeadequate},
shows that $\sigma(X)$ evaluates to the tree $X$ in $UT^1(\Sigma)$, and that
the number of characters in $\sigma(X)$ is at most four times the number
of edges in $X$.

To compute $\sigma(X)$, we start by precomputing adjacency matrices for $X$
corresponding to each possible edge label and direction; it is easily seen
that this can be done in $O(n^2)$ time where $n$ is the number of edges in $X$.
It is immediate from the inductive method of definition how to compute
$\sigma(X)$ by a simple depth first traversal (following non-trunk edges)
from each of the trunk vertices; this involves
considering each of $O(n)$ vertices once.

At each vertex, the only non-trivial operation is to sort the words $\tau_i$ into order
and then concatenate; the complexity of this of course depends on the choice of order. The
sum length of all the words $\tau_i$ is clearly $O(n)$. If
we choose the order to be lexicographic order (with respect to some arbitrary linear
order on $\Omega$), then a careful implementation of radix sort gives us a lexicographically
sorted list of formulas in $O(n)$ time, and concatenation is
clearly also $O(n)$.

Thus, the total time required for the algorithm is $O(n^2)$, and we have established:

\begin{proposition}\label{prop_treetoexp}
Given an unpruned $\Sigma$-tree $X$, we can in quadratic time compute
a well-formed formula which evaluates to $X$ in $UT^1(\Sigma)$. Moreover,
the formula has size linear in the size of $X$, and depends only
on the isomorphism type of $X$ and not on its representation.
\end{proposition}

\section{The Word Problem}\label{sec_wp}

Recall that the \textit{word problem} for an algebra $A$ with a given generating set
is the algorithmic problem of determining, given as input two well-formed formulas
over the generating set and the operations of the algebra, whether the formulas
represent the same element of the algebra. The word problem for free objects
in a variety of algebras is of particular importance, since it is trivially
equivalent
to the problem of testing whether a given identity holds in all algebras of
the variety.

In this section, we shall exhibit a quadratic time algorithm to solve
the word problem in a free adequate monoid $T^1(\Sigma)$. In fact in
Section~\ref{sec_normalforms} below, we shall see that it is also possible
to compute normal forms of elements of $T^1(\Sigma)$ in quadratic time;
this automatically yields another algorithm for the word
problem (by computing normal forms and comparing), of the same asymptotic
complexity. However, we present an explicit word problem algorithm first
since this is simpler, potentially easier to implement, and illustrates in
a simple context some of the ideas we will need in Section~\ref{sec_normalforms}.

By Proposition~\ref{prop_exptotree} we can efficiently convert
well-formed formulas in the free adequate monoid into unpruned
$\Sigma$-trees of comparable
size. It follows that to test
(efficiently) whether two given expression $x$ and $y$ represent the same
element of the free adequate monoid, that is, to solve the word problem,
it suffices to compute corresponding $\Sigma$-trees
$X, Y \in UT^1(\Sigma)$,
and then check (efficiently) if $\ol{X} = \ol{Y}$ in $T^1(\Sigma)$.

To solve
this latter problem, we begin with an elementary proposition, which
reduces it a constraint satisfaction problem (formulated in terms of
morphisms between structures, in the manner usual in the literature
of areas such as graph theory and universal algebra --- see for example
\cite{Hell04}).

\begin{proposition}\label{prop_equiv}
Let $X$ and $Y$ be $\Sigma$-trees. Then the following are equivalent:
\begin{itemize}
\item[(i)] $\ol{X} = \ol{Y}$;
\item[(ii)] $X$ and $Y$ admit isomorphic retracts;
\item[(iii)] there is a morphism from $X$ to $Y$ and a morphism from $Y$ to $X$.
\end{itemize}
\end{proposition}
\begin{proof}
The equivalence of (i) and (ii) follows from \cite[Proposition~3.5]{K_freeadequate}, so
it suffices to establish the equivalence of (ii) and (iii).

If (ii) holds then, in particular, some retract of $X$ is isomorphic to a
substructure of $Y$; composing the retraction of $X$ with the isomorphism
yields a morphism from $X$ to $Y$. By symmetry of assumption there is also
a morphism from $Y$ to $X$, so (iii) holds.

Now suppose (iii) holds, say $\sigma : X \to Y$ and $\tau : Y \to X$ are
morphisms. Then the compositions $\tau \circ \sigma : X \to X$ and
$\sigma \circ \tau : Y \to Y$ are maps on finite sets, and it follows that
we may choose $n$ such that both
$(\tau \circ \sigma)^n : X \to X$ and $(\sigma \circ \tau)^n : Y \to Y$
are idempotent, that is, are retractions of $X$ and $Y$ respectively.
Let $X'$ and $Y'$ be the retracts which are the respective images of
these retractions. Now it is easily verified that
$\sigma$ and $\tau \circ (\sigma \circ \tau)^{n-1}$ restrict to mutually
inverse isomorphisms between the retracts $X'$ and $Y'$, showing that
(ii) holds.
\end{proof}

Proposition~\ref{prop_equiv} implies that to check if two $\Sigma$-trees
are equivalent, and hence by the preceding arguments to solve the word problem
for the free adequate semigroup on $\Sigma$, it suffices to check whether each
$\Sigma$-tree admits a morphism to the other. Our main goal in the rest of
this section, then, is an efficient algorithm to test, given an ordered pair of
$\Sigma$-trees, whether there is a morphism from the first to the second.
Our approach is essentially a constraint propagation
algorithm, with the correctness of the result being shown by an
arc consistency argument utilising the tree-like nature of
our geometric representatives for elements. The ideas behind the proof
are well known in the fields of constraint satisfaction and artificial
intelligence (see for example
\cite{Dechter87}), but for the benefit of semigroup theorists who may not be
familiar with these fields we present the algorithm in an elementary form:

\begin{algorithm}\label{algH} \ \\

\noindent\textbf{Input:} Two $\Sigma$-trees $T_1$ and $T_2$ on $n$ and $m$ vertices respectively.

\noindent\textbf{Output:} ``Yes'' if there exists a homomorphism from $T_1$ to $T_2$. ``No'' otherwise.

\begin{enumerate}
\item Consider the start vertex of $T_1$, label this vertex $1$, and then use
a depth-first traversal (ignoring direction of edges) to label the remaining vertices
from $2$ to $n$ in ascending order.

\item For each $i$ in $\{1,\dots,n\}$, let $B_i$ be the set of vertices
in $T_2$.

\item For the start [end] vertex $i$ set $B_i$ to be the singleton set containing the
start [end] vertex of $T_2$
\item For $i$ descending from $n$ to $1$, and each vertex $j > i$ adjacent to $i$, do the following:
\begin{itemize}
\item[(i)] Let $a \in \Sigma \cup \Sigma'$ be the label of the edge from $i$ to $j$ in $T_1$;
\item[(ii)] Let $B_i:= B_i \cap B_j^\star$ where
\begin{align*}
B_j^\star = \lbrace x \mid & \textrm{ $T_2$ has an edge labelled $a$ } \\
&\textrm{ from $x$ to some $y \in B_j$ } \rbrace.
\end{align*}
\end{itemize}
\item If $B_1=\emptyset$, output ``No''; otherwise output ``Yes.''
\end{enumerate}
\end{algorithm}

\begin{proposition}\label{prop_wpcorrect}
Algorithm~\ref{algH} is correct, that is, $B_1$ is non-empty on completion of the
algorithm if and only if there is a morphism from $T_1$ to $T_2$.
\end{proposition}
\begin{proof}
For brevity, we identify the vertices with the labels from $1$ to $n$
assigned in the algorithm.
Suppose first that there is a morphism $\sigma : T_1 \to T_2$. We claim
that $B_i$ contains $\sigma(i)$ for all $i$, from which it follows in
particular that $B_1$ contains $\sigma(1)$ so that $B_1$ is
non-empty as required. Indeed, if not, choose $i$ maximal such that
$\sigma(i) \notin B_i$. Clearly $\sigma(i)$ was in $B_i$ after Step 2 of the
algorithm and, because $\sigma$ preserves start and end vertices, also after
Step 3; therefore, it must have been removed during Step 4.
For this to have happened, there must have been a $j > i$ and an edge from $i$
to $j$ (labelled $a \in \Sigma \cup \Sigma'$, say) such that
$\sigma(i) \notin B_j^\star$.
By the definition of $B_j^\star$, this means there was (at the time of removal)
no edge labelled $a$ from $\sigma(i)$ to any $y \in B_j$.
 But because $\sigma$ is a morphism, $\sigma(j) \in B_j$
is connected to $\sigma(i)$ by such an edge, so it must be that
$\sigma(j)$ was not in $B_j$ at the time $\sigma(i)$ was removed from
$B_i$. Now since $B_j$ only gets smaller, $\sigma(j)$ is not in $B_j$
at the end of the algorithm. But $j > i$, so this contradicts the
maximality of $i$.

Conversely, suppose $B_1$ is non-empty at the end of the algorithm. We
define a morphism $\sigma : T_1 \to T_2$ inductively as follows. First,
choose $\sigma(1) \in B_1$ arbitrarily. Now assume $1 < i < n$ and
we have defined
$\sigma$ on the vertices $1$, \dots $i-1$ and all edges between them, in
such a way as to preserve adjacency, labels and directions of edges, and
the start and end vertices if appropriate, and such that $\sigma(p) \in B_p$
for $1 \leq p \leq i-1$.

Since $T_1$ is a tree and the edges were numbered by a depth-first
traversal, it follows that vertex $i$ is connected to vertex $k$ for some
unique $k < i$; suppose $T_1$ has an edge from $k$ to $i$ labelled
$a \in \Sigma \cup \Sigma'$.

Considering the way $B_k$ is constructed, we see that every vertex in $B_k$,
including $\sigma(k)$, is connected to some $v \in B_i$.
Moreover, if $i$ happens to be the start [respectively, end] vertex of $T_1$,
then $B_i$ was originally set to contain only the start [end] vertex of $T_2$,
so it must be that $v \in B_i$ is the start [end] vertex of $T_2$.
Thus, by defining $\sigma(i) = v$ and $\sigma(e)$ to be the
appropriate edge, we extend $\sigma$ to be defined on the vertices
$1, \dots, i$ and all edges between, with the appropriate properties.
\end{proof}

We now analyse the complexity of Algorithm~\ref{algH}.
At the start of the algorithm, we can precompute for
each vertex in $T_1$ a list of edges adjacent to that vertex; this can be done
in $O(n)$ time.

Having done this, Step 1 of the algorithm (a simple depth first traversal
of the tree $T_1$) has complexity $O(n)$. If we store the lists $B_i$ as
arrays of $m$ boolean flags then Step 2 has complexity $O(mn)$
since we need to initialise $mn$ values. Step 3 has complexity $O(m)$,
since we must reset $m-1$ values for each of the start and end vertices.

The most interesting part is the complexity of Step 4. The number of
iterations of the outer loop is clearly bounded by the number of edges
in $T_1$, so it is $O(n)$ and the precomputed lists of edges mean there is
no extra overhead in finding the edges in the correct order.
In each iteration, the fact that the corresponding edge has been found
means Step 4(i) takes constant time. In Step 4(ii), computing $B_j^\star$
involves
passing through the list of all $O(m)$ edges of $T_2$ and for each edge
checking (in constant time) if one of the ends lies in $B_j$ and if the
label is correct; this takes
$O(m)$ time. Computing the intersection is simply
a boolean ``and'' operation on two arrays of length $m$, and so also takes $O(m)$
time. Thus, Step 4 takes time $O(mn)$, and the total complexity of the
algorithm is $O(mn)$.

Combining the above arguments with Proposition~\ref{prop_exptotree},
we have established the following main result:
\begin{theorem}
The word problem for any finite rank free left adequate, free right
adequate or free adequate semigroup is decidable in time
polynomial (quadratic, in the RAM model of computation) in the combined
length of the two formulas.
\end{theorem}

\section{Pruned Trees and Normal Forms}\label{sec_normalforms}

In this section, we show how to efficiently compute the minimal retract of a
$\Sigma$-tree. Combined with the results of Section~\ref{sec_exptree}, this
will allow us to compute normal forms (as formulas) for elements of
free adequate monoids. Our main algorithm is the following, the first four
steps of which are essentially the same as in Algorithm~\ref{algH}:

\begin{algorithm}\label{algN} \ \\

\noindent\textbf{Input:} A $\Sigma$-tree $T$ on $n$ vertices.

\noindent\textbf{Output:} The vertex set of a pruned subtree of $T$,
isomorphic to the $\ol{T}$.

\begin{itemize}
\item[(1)] Consider the start vertex of $T$, label this vertex $1$, and then use
a depth-first traversal (ignoring direction of edges) to label the remaining vertices
from $2$ to $n$ in ascending order.

\item[(2)] For each $i$ in $\{1,\dots,n\}$, set $B_i = \lbrace 1, \dots, n \rbrace$.

\item[(3)] For the start [end] vertex $i$ set $B_i = \lbrace i \rbrace$.

\item[(4)] For $i$ descending from $n$ to $1$ and each $j$ with $j > i$ and $i$ connected to $j$, do the following:
\begin{itemize}
\item[(i)] Let $a \in \Sigma \cup \Sigma'$ be the label of the edge in $T$
from $i$ to $j$.
\item[(ii)] Let $B_i := B_i \cap B_j^\star$ where
\begin{align*}
B_j^\star = \lbrace x \mid & \textrm{ $T$ has an edge labelled $a$ } \\
&\textrm{ from $x$ to some $y \in B_j$ } \rbrace.
\end{align*}
\end{itemize}

\item[(5)] Set $X = \lbrace 1, \dots, n \rbrace$.

\item[(6)] For $w$ ascending from $1$ to $n$ and $a \in \Sigma \cup \Sigma'$,
do the following:
\begin{itemize}
\item[(i)] If $w \notin X$ then go to the next $w$.
\item[(ii)] Otherwise, find all vertices $u$ such that $a$ labels
an edge from $w$ to $u$ and put them in a list $K$.
\item[(iii)] For each $u \in K$ such that $u > w$:
\begin{itemize}
\item[(a)] Check if $K \cap B_u = \lbrace u \rbrace$.
\item[(b)] If \textbf{not}, then remove $u$ from $K$, and traverse the
tree below $u$, removing $u$ and all its descendant vertices from $X$.
\end{itemize}
\end{itemize}
\item[(7)] Output $X$.
\end{itemize}
\end{algorithm}

Our next aim is to prove the correctness of this algorithm.

\begin{lemma}\label{lemma_retract}
The subtree $X$, as computed at the end of Algorithm~\ref{algN}, is a retract of $T$.
\end{lemma}
\begin{proof}
We shall show that each time a vertex and its descendants are removed from
$X$ at Step 6(iii)(b), there is a retraction from the tree $X$ prior
to the removal, onto the tree $X$ after the removal. Since the successive
subtrees $X$ form a chain under inclusion, it is clear that composing these
retractions in the appropriate order yields a retraction from $T$ onto
the final tree $X$, as required.

Indeed, suppose $u$ and its descendants are removed from $X$ at some point.
Let $w$, $a$ and $K$ be as in the algorithm at that point, and let $X_1$ and $X_2$
be the values of $X$ immediately before and after
the deletion, respectively.

Note that, since the identity map is a morphism, it is easily verified
that $i \in B_i$ for all vertices $i$ of $T$. The
fact that $u$ was removed means that $K \cap B_u \neq \lbrace u \rbrace$, and
we know $u \in K \cap B_u$, so we may choose some vertex $v \in K \cap B_u$
with $v \neq u$.

First, we follow the procedure from the proof of Proposition~\ref{prop_wpcorrect}
to inductively define a morphism $\sigma : T \to T$, but
being  more careful about our choices in order to ensure that
$\sigma(u) = \sigma(v) = v$.
We start by setting $\sigma(i) = i$ for all $i < u$; since $i \in B_i$ for all
$i$ it is easily verified that this is consistent with the procedure
in Proposition~\ref{prop_wpcorrect}. Note in particular
that $w < u$, so this means $\sigma(w) = w$. Now since $u, v \in K$, there
are edges from $w = \sigma(w)$ to $u$ and $v$ both labelled $a$, so in
following the procedure of Proposition~\ref{prop_wpcorrect}
we may choose to set $\sigma(u) = v$.
We now continue the process from the proof of Proposition~\ref{prop_wpcorrect}. For each vertex
$r$ in turn, if $r$ is a descendant of $u$, then we define $\sigma(r)$
as in the proof of Proposition~\ref{prop_wpcorrect}, making any choices arbitrarily. If $r$ is
not a descendant of $u$ then the unique vertex $k < r$ adjacent to $r$
is also not a descendant of $u$; thus, we have already defined
$\sigma(k) = k$ and we may set $\sigma(r) = r$.

Now $\sigma$ is a map on a finite set, and so has an idempotent power,
say $\sigma^i$. Since $v$ is not a descendant of $u$, we have
$\sigma(v) = v$, and hence $\sigma^i(u) = \sigma^{i-1}(v) = v$, so $u$
is not in the image of $\sigma^i$. Since the image of $\sigma^i$ is a
$\Sigma$-tree, it must contain the start
vertex and be connected, so we deduce that no descendants of $u$ are
in the image of $\sigma^i$. It follows that $\sigma^i$ maps $X_1$ to
$X_2$. Moreover, $\sigma$ fixes $X_2$, so restricting $\sigma^i$ to
$X_1$ gives the required retraction of $X_1$ onto $X_2$.
\end{proof}

\begin{lemma}
The retract $X$, as computed at the end of Algorithm~\ref{algN}, is pruned.
\end{lemma}
\begin{proof}
Suppose not, say $X$ admits a proper retraction $\sigma : X \to X$. Let
$u$ be a vertex in $X$ but not in the image of $\sigma$, and suppose $u$
is minimal with respect to this condition. Then $u \neq 1$, since $1$ labels
the start vertex which is fixed by every retraction. Thus, we may let $w$ be
the unique vertex with $w < u$ and $w$ adjacent to $u$.

Since $w < u$, by the minimality
of the choice of $u$, we have $\sigma(w) = w$. It follows that $\sigma(u)$
is connected to $w$ by an edge of the same label and orientation as that
connecting $u$ to $w$. This means that, when considering $w$ at step
6(iii), we would initially have had $\sigma(u) \in K$. Since
$\sigma(u)$ is in the final tree $X$, it was never removed from $K$.
Moreover, composing the retraction of $T$ onto $X$ (given by
Lemma~\ref{lemma_retract}) with
$\sigma$ gives a morphism of $T$ mapping $u$ to $\sigma(u)$; it follows
from the argument in the proof of Proposition~\ref{prop_wpcorrect} that
$\sigma(u) \in B_u$.

This means that at the time
$u$ was considered in Step 6(iii)(a) we had
$\sigma(u) \in K \cap B_u$. But then $K \cap B_u \neq \lbrace u \rbrace$,
so $u$ would have been removed from $X$, giving a contradiction.
\end{proof}

Turning to the complexity of the algorithm, Steps (1)-(4) are exactly
as in Algorithm~\ref{algH} (except that the source and target trees for
the morphism are the same, so $m=n$), and by the same analysis as in
Section~\ref{sec_wp} take time $O(n^2)$.

For efficiency, we store the set $X$ as an array of boolean flags. The time
requirement for Step
(5) is clearly $O(n)$. The loop in Step 6 is iterated at most $O(n)$ times.
In each such iteration, step (i) takes constant time. Step (ii) cannot
involve checking more than $O(n)$ vertices, so the total contribution
to the time required will be $O(n^2)$. In step (iii), note that each
element of $L$ is uniquely determined (across the entire algorithm) by
the ordered pair $(w,u)$ where there is always an edge between $w$ and $u$;
thus, the number of iterations of this step across the whole algorithm is
at most twice the number of edges in the tree, which is $O(n)$.
Within each iteration, each step takes $O(n)$ time, so the total contribution is
$O(n^2)$.

Thus, we have established:
\begin{theorem}\label{thm_pruning}
Given a $\Sigma$-tree $T$, one can compute in polynomial time (quadratic
time in the RAM model of computation) the pruned $\Sigma$-tree $\ol{T}$.
\end{theorem}

Combining with the results of Section~\ref{sec_exptree}, Theorem~\ref{thm_pruning}
allows us to compute normal forms (as formulas) in the free adequate monoid.
Indeed, given a formula $w$, by Proposition~\ref{prop_exptotree} we may
convert it in quadratic time to a corresponding unpruned $\Sigma$-tree $T$ of comparable size. By
Theorem~\ref{thm_pruning} we may then compute the pruned tree $\ol{T}$ in
time quadratic in the size of $T$ and hence in the size of $w$. Finally, by
Proposition~\ref{prop_treetoexp} we can convert $\ol{T}$ into the uniquely
defined formula $\sigma(\ol{T})$ in time quadratic in the size of $\ol{T}$; since $\ol{T}$
is no larger than $T$, this is also quadratic in the size of $T$, and hence
in the size of $w$.

\begin{theorem}
Given a formula in the free adequate, left adequate or right adequate
semigroup or monoid, one can compute
a normal form in polynomial (quadratic in the RAM model of computation) time.
\end{theorem}

We note that the resulting language of normal forms for elements, which by
definition is the set
$$\lbrace \sigma(\ol{T}) \mid T \textrm{ is a pruned $\Sigma$-tree} \rbrace,$$
does not appear to have a completely elementary description without reference to trees. Of
course one may check (in quadratic time) whether a given formula $w$ is a
normal form by following the above procedure to convert $w$ to a normal form
and then comparing with $w$; we do not know of a fundamentally easier method.

We also note that in the case of free \textit{inverse} monoids (and semigroups), it is known
\cite[Theorem 11]{Lohrey07} that the word problem is decidable in (RAM) linear
time. In the inverse case computations appear to be inherently simpler, as
the operation corresponding to computing a minimal retract (namely, computing a minimal
morphic image) can be performed by an iterative process of identifying vertices, where
the fact a pair of vertices can be identified is determined ``locally'', by looking only
in the immediate neighbourhood of the vertices. It seems unlikely that quite such a
fast algorithm can be obtained in the adequate case, but one might still ask whether our
algorithms can be significantly improved upon. Also shown in \cite[Theorem 11]{Lohrey07}
is that the word problem for a free inverse monoid is decidable (using a different
algorithm to the linear time one) in logarithmic space: the space complexity of the word
problem for free adequate monoids and semigroups is a natural topic for future research.

\section*{Acknowledgements}

The second author was supported by the Czech Government Grant Agency GA\v CR
project 13-01832S.
The authors thank the organisers of the 4th Novi Sad Algebraic Conference
(NSAC2013), which by bringing together researchers in semigroup theory
and universal algebra catalysed this research. They also thank Victoria Gould
for some helpful comments on the draft, and Stuart Margolis for pointing them
to the work of Lohrey and Ondrusch \cite{Lohrey07}.

\bibliographystyle{plain}

\def$'$} \def\cprime{$'${$'$} \def$'$} \def\cprime{$'${$'$}

redpajama_set_name: RedPajamaArXiv


text:
Q: FFMPEG desktop capture randomly stops streaming to RTMP endpoint. Why? I am using the following FFMPEG command for desktop streaming to an RTMP endpoint:
ffmpeg.exe -report -fflags nobuffer -framerate 30 -use_wallclock_as_timestamps 1 -f gdigrab -thread_queue_size 256 -offset_x 0 -offset_y 136 -video_size 1280x720 -i desktop -c:v libx264 -c:a aac -b:v 1000k -vf "format=yuv420p" -g 60 -f flv -movflags faststart -crf 23 rtmp://75cw3w9g:czol1pao@1cb45c.entrypoint.cloud.wowza.com/app-D2TFw12x/dCs4YjV5 -f dshow -rtbufsize 200M -thread_queue_size 1024 -i "audio=CABLE Output (VB-Audio Virtual Cable)"

Operating System is Windows 10.
The command works as expected, however, unpredictably, CPU usage and frame rate drop to very low levels, and the stream to RTMP clearly cuts out.
Below is an example of what happens:
ffmpeg started on 2022-01-14 at 21:32:42
Report written to "ffmpeg-20220114-213242.log"
Log level: 48
ffmpeg version 2021-06-23-git-947122f111-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10.3.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libglslang --enable-vulkan --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      57.  0.100 / 57.  0.100
  libavcodec     59.  1.102 / 59.  1.102
  libavformat    59.  3.101 / 59.  3.101
  libavdevice    59.  0.100 / 59.  0.100
  libavfilter     8.  0.102 /  8.  0.102
  libswscale      6.  0.100 /  6.  0.100
  libswresample   4.  0.100 /  4.  0.100
  libpostproc    56.  0.100 / 56.  0.100
[gdigrab @ 000002547ea616c0] Capturing whole desktop as 1280x720x32 at (0,136)
[gdigrab @ 000002547ea616c0] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, gdigrab, from 'desktop':
  Duration: N/A, start: 1642195962.552738, bitrate: 884748 kb/s
  Stream #0:0: Video: bmp, bgra, 1280x720, 884748 kb/s, 30 fps, 1000k tbr, 1000k tbn
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, dshow, from 'audio=CABLE Output (VB-Audio Virtual Cable)':
  Duration: N/A, start: 1569.872000, bitrate: 1411 kb/s
  Stream #1:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
[rtmp @ 000002540239b540] Ignoring unsupported var reason
Stream mapping:
  Stream #0:0 -> #0:0 (bmp (native) -> h264 (libx264))
  Stream #1:0 -> #0:1 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 000002547ead5fc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 000002547ead5fc0] profile High, level 3.1, 4:2:0, 8-bit
[libx264 @ 000002547ead5fc0] 264 - core 164 r3065 ae03d92 - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=60 keyint_min=6 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, flv, to 'rtmp://75cw3w9g:czol1pao@1cb45c.entrypoint.cloud.wowza.com/app-D2TFw12x/dCs4YjV5':
  Metadata:
    encoder         : Lavf59.3.101
  Stream #0:0: Video: h264 ([7][0][0][0] / 0x0007), yuv420p(tv, progressive), 1280x720, q=2-31, 1000 kb/s, 30 fps, 1k tbn
    Metadata:
      encoder         : Lavc59.1.102 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: N/A
  Stream #0:1: Audio: aac (LC) ([10][0][0][0] / 0x000A), 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc59.1.102 aac
frame=    1 fps=0.0 q=0.0 size=       0kB time=00:00:00.44 bitrate=   7.4kbits/s speed=9.33x
frame=   17 fps=0.0 q=0.0 size=       0kB time=00:00:00.44 bitrate=   7.4kbits/s speed=0.798x
frame=   32 fps= 30 q=0.0 size=       0kB time=00:00:00.44 bitrate=   7.4kbits/s speed=0.413x
frame=   46 fps= 29 q=0.0 size=       0kB time=00:00:00.44 bitrate=   7.4kbits/s dup=0 drop=1 speed=0.281x
frame=   57 fps= 28 q=29.0 size=      40kB time=00:00:02.63 bitrate= 124.9kbits/s dup=0 drop=1 speed=1.27x
frame=   64 fps= 24 q=29.0 size=     135kB time=00:00:02.96 bitrate= 374.3kbits/s dup=0 drop=1 speed=1.12x
frame=   76 fps= 23 q=29.0 size=     179kB time=00:00:03.44 bitrate= 425.3kbits/s dup=0 drop=1 speed=1.05x
frame=   82 fps= 22 q=29.0 size=     209kB time=00:00:03.96 bitrate= 432.2kbits/s dup=0 drop=1 speed=1.04x
frame=   85 fps= 18 q=29.0 size=     227kB time=00:00:03.96 bitrate= 470.3kbits/s dup=0 drop=1 speed=0.861x
frame=   87 fps= 16 q=29.0 size=     247kB time=00:00:03.96 bitrate= 510.9kbits/s dup=0 drop=1 speed=0.741x
frame=   92 fps= 16 q=29.0 size=     279kB time=00:00:03.96 bitrate= 576.8kbits/s dup=0 drop=1 speed=0.676x
frame=   94 fps= 14 q=29.0 size=     300kB time=00:00:03.96 bitrate= 620.6kbits/s dup=0 drop=1 speed=0.608x
frame=  104 fps= 15 q=29.0 size=     335kB time=00:00:04.44 bitrate= 616.9kbits/s dup=0 drop=1 speed=0.632x
frame=  108 fps= 14 q=29.0 size=     353kB time=00:00:04.44 bitrate= 649.7kbits/s dup=0 drop=1 speed=0.585x
frame=  114 fps= 14 q=29.0 size=     382kB time=00:00:04.95 bitrate= 630.4kbits/s dup=0 drop=1 speed=0.601x
frame=  118 fps= 10 q=29.0 size=     475kB time=00:00:04.95 bitrate= 784.8kbits/s dup=0 drop=1 speed=0.433x
frame=  124 fps=9.6 q=29.0 size=     490kB time=00:00:04.95 bitrate= 809.8kbits/s dup=0 drop=1 speed=0.385x
frame=  134 fps= 10 q=29.0 size=     525kB time=00:00:05.44 bitrate= 790.0kbits/s dup=0 drop=1 speed=0.407x
[gdigrab @ 000002547ea616c0] Thread message queue blocking; consider raising the thread_queue_size option (current value: 256)
frame=  143 fps= 10 q=29.0 size=     560kB time=00:00:05.95 bitrate= 770.5kbits/s dup=0 drop=1 speed=0.416x
frame=  150 fps= 10 q=29.0 size=     591kB time=00:00:05.95 bitrate= 812.3kbits/s dup=0 drop=1 speed=0.402x
frame=  156 fps= 10 q=29.0 size=     615kB time=00:00:06.44 bitrate= 781.6kbits/s dup=0 drop=1 speed=0.42x
frame=  162 fps= 10 q=27.0 size=     665kB time=00:00:06.44 bitrate= 845.0kbits/s dup=0 drop=1 speed=0.399x
frame=  167 fps=9.9 q=29.0 size=     686kB time=00:00:06.44 bitrate= 872.2kbits/s dup=0 drop=1 speed=0.384x
frame=  169 fps=9.6 q=29.0 size=     701kB time=00:00:06.95 bitrate= 826.2kbits/s dup=0 drop=1 speed=0.396x
frame=  171 fps=9.2 q=29.0 size=     721kB time=00:00:06.95 bitrate= 849.1kbits/s dup=0 drop=1 speed=0.373x
frame=  173 fps=8.8 q=29.0 size=     730kB time=00:00:06.95 bitrate= 860.1kbits/s dup=0 drop=1 speed=0.356x
frame=  178 fps=8.1 q=29.0 size=     821kB time=00:00:06.95 bitrate= 967.3kbits/s dup=0 drop=1 speed=0.316x

In this case, the problem occurred right after starting ffmpeg. In most cases this happens after a time interval so variable that it is difficult to identify any pattern.
For example, it can all go smoothly (at constant 30 fps) for 1 hour and then all of a sudden the CPU usage and frame rate drop to very low levels, and the stream to RTMP clearly cuts out.
I can provide any other information you may need.
Is there anyone who could give me some advice or suggestions?
Thanks.


text:
Q: Calculating vertices of z_far plane in world coordinates. Im working on my capstone project for a computer science degree and im having trouble figuring out how to do what the title says.
Just assume the camera is at the origin looking down -z in gl coordinates(or positive z in world coordinates)
Also, my projection matrix is based on a 16x9 aspect ratio with a 40 degree vertical fov. The zfar is 1000, and znear is 1.
I have approached this problem from 2 different angles. I tried to figure it out via matrix math, and also using trig. However neither approach is working correctly for me so far.
My first instinct, was to take my projection matrix, get the inverse of that matrix, than multiply the homogeneous coordinates that make up the zfar plane.
for example:
vec4(-1.0,1.0,-1.0,1.0) * inverse_projection// calculates top left vertex of z_far plane in world coords etc..

Below, is the code that demonstrates what i mean. Theoretically, after multiplying the {-1,1,-1} by the inverse projection matrix the resulting vector should have a z coordinate of 1000, since that is the zfar used in the construction of the projection matrix.
glm::vec4 pp  = glm::vec4(-1, 1, -1, 1.0);

printf("zfar[0] = %.2f, %.2f, %.2f, %.2f\n", pp.x, pp.y, pp.z, pp.w);
pp = pp * inverse_projection;
printf("zfar[0] * inverse_projection = %.2f, %.2f, %.2f,  w=%.2f\n", pp.x/pp.w  ,pp.y/pp.w  ,pp.z/pp.w ,pp.w);
pp = pp * projection;
printf("zfar[0] * projection = %.2f, %.2f, %.2f,  w=%.2f\n",  pp.x/pp.w  ,pp.y/pp.w  ,pp.z/pp.w ,pp.w);

Output:
zfar[0] = -1.00, 1.00, -1.00, 1.00
zfar[0] * inverse_projection = -0.21, 0.12, -0.33,  w=1.50
zfar[0] * projection = -1.00, 1.00, -1.00,  w=1.00

But, As you can see, it says that in world coordinates, z_far is at -0.33, when it should be at -1000 Its not even close to being right. My guess is that i dont have the W coordinate correct for it to successfully translate into world coordinates.
I also tried calculating the zfar via trg.
void test_getFrustumInWorld( double height, double width, double v_fov, double z_near, double z_far, glm::mat4 projection)
{
    //height and width refer to height and width of screen
    glm::vec4 z_far_world[4];
    double z_far_height = (tan(v_fov/2)*z_far)*2;
    double aspect_ratio = height/width; //how many heights there are in one width
    double z_far_width = z_far_height * aspect_ratio;

    double zf_right = z_far_width/2.0;
    double zf_top = z_far_height/2.0;

    z_far_world[0] = glm::vec4(-zf_right, zf_top, 1000.0, 1.0);
    z_far_world[1] = glm::vec4(-zf_right,-zf_top, 1000.0, 1.0);
    z_far_world[2] = glm::vec4( zf_right,-zf_top, 1000.0, 1.0);
    z_far_world[3] = glm::vec4( zf_right, zf_top, 1000.0, 1.0);

    for(int i=0; i< 4; i++)
    {
        double w = z_far_world[i].w;
        printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w,  z_far_world[i].y/w,  z_far_world[i].z/w,  z_far_world[i].w);

    }

    printf("\nprojected:\n");
    for(int i=0; i< 4; i++)
    {
        z_far_world[i] = z_far_world[i] * projection;
        double w = z_far_world[i].w;
        printf("z_far_world[%d] = {%.2f, %.2f, %.2f, w=%.2f}\n",i,z_far_world[i].x/w,  z_far_world[i].y/w,  z_far_world[i].z/w,  z_far_world[i].w);

    }
}

Output:
z_far_world[0] = {-1258.40, 2237.16, 1000.00, w=1.00}
z_far_world[1] = {-1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[2] = {1258.40, -2237.16, 1000.00, w=1.00}
z_far_world[3] = {1258.40, 2237.16, 1000.00, w=1.00}

projected:
z_far_world[0] = {0.16, -0.50, 0.50, w=-2002.00}
z_far_world[1] = {0.16, 0.50, 0.50, w=-2002.00}
z_far_world[2] = {-0.16, 0.50, 0.50, w=-2002.00}
z_far_world[3] = {-0.16, -0.50, 0.50, w=-2002.00}

The numbers in that first block of output, are the coordinates i arrived at view trig calculations.
The second block of numbers is the vertices after the projection matrix was applied to them. Once the projection matrix is applied, the resulting coordinate should some combination of all 1 and -1. but instaed its something like {0.16, 0.5, 0.5}. Which is totally wrong.
Also just to clarify, the output is the coords after a division by W.
What the hell am i missing? this should have been simple, but nothing is making sense.
Where am i going wrong? Am i misunderstanding something? Im totally stuck.

A: In your glm code, there are two major problems:
glm assumes (at least for matrix operations) that we are working with column vectors. This means, that the default order of operations is M * t. If you want to use row vectors and operations of the form t * M , then M has to be transposed to work correctly.
A projected z-coordinate of -1.0 is not located on the far plane but on the near plane. Also OpenGL expects (by default) values to be larger when they are further away. So if you want a point on the far plane, then it has to have a z coordinate of 1.0.


Tel Aviv, Israel, September 28, 2016, RADWIN (www.radwin.com), the leading provider of train-to-ground wireless communications solutions, and MaximaTelecom - operator of the largest worldwide Wi-Fi network onboard Moscow Metro – today announced results of RADWIN's recently-launched Next Generation Train-to-Ground solution. RADWIN's new platform delivered 500 Mbps actual Ethernet throughput onboard Moscow Metro Line 11 (Kakhovskaya), setting a new benchmark in the industry.
The Wi-Fi network deployed by MaximaTelecom and RADWIN in the Moscow Metro system, has been operational for almost 3 years, providing Internet access to up to 2.5 million commuters daily, who generate traffic of up to 70 TeraBytes each day. The Wi-Fi network spans over 650 trains along 660 km of tracks and tunnels. The constant growth in network traffic and the need to support multiple services and additional applications - such as HD streaming for passengers and CCTV onboard trains - necessitated a network upgrade. Using RADWIN's Next Generation Train-to-Ground solution, MaximaTelecom was able to demonstrate up to 500 Mbps of net Ethernet throughput per train that will support a wide array of existing and future applications.


text:
Maren Kathleen Elliott is an interdisciplinary artist (visual arts, music, movement) and educator from Edmonton, Alberta. She was raised in the arts, training in classical viola, dance, and exploring visual and written expression. Maren received her BA (Psychology, Music) from the University of Alberta in 2016. In 2017, she was Artist in Residence at the University of Alberta's Arts-based Research studio and received an individual project grant from the Edmonton Arts Council for her work in mixed media. In 2018, She was one of six featured artists for the Edmonton Shaw Conference Community Art Program, and she has subsequently exhibited work in cities across Canada from Vancouver to Ottawa. Most recently, she has been Artist in Residence at the Ottawa School of Art.
Maren is passionate about arts accessibility, story telling, mental health advocacy, and community activation. She has worked as a distress line listener, practical support worker, outreach arts educator for all ages, dancer, and group fitness instructor. All of these experiences have shaped and influenced her creative practice. in her studio, she often combines images and seemingly ordinary materials into creative meditations that bridge her passions for social sciences and human connection


text:
Solutions & Partnerships
Georgia's technical college system is building on good relationships with the university system and the business community to boost enrollments
Ed Lightsey,
www.komich.com
Career Academy Advocate: Mark Whitlock|!!| CEO of the Central Educational Center in Newnan
There was a time when rising enrollments at Georgia's tech-nical colleges were as predictable as azaleas in the spring, climbing annually by double digits.
But the onset of a fading economy in 2007 led to across-the-board budget cuts and other austerity measures, including significant changes made to the state's HOPE Scholarship Program in 2011. A hike in the required minimum grade point average (GPA) from 2.0 to 3.0 meant many students lost their HOPE eligibility and forced 9,000 of them out of Technical College System schools.
The technical colleges saw their enrollments decline rapidly, with 25,000 fewer students signing up for classes in 2012 than the year before. An improvement in the economy also contributed to the declining enrollment as more students left the classroom for the workplace.
"A lot of things drove the decline in enrollment," says Ron Jackson, commissioner of the Technical College System of Georgia (TCSG). "One of them was the change from the quarter system to longer semesters and a little bit higher tuition. But we were able to survive that." Jackson says tuition shortfalls and gaps for students were met by measures like loan programs. "A lot of scholarship programs implemented by our college foundations also helped."
Despite the impact of tough economic times, technical college leaders are optimistic about the future. (At press time, the Georgia House had passed a measure to change the GPA eligibility for HOPE grants to 2.0; the Senate had yet to vote.)
Austerity measures are beginning to soften as Georgia's economic developers land projects that are creating more high-paying jobs, with the state's technical colleges installing innovative training programs to create the workers needed for those jobs.
From Athens to Valdosta, and across Middle Georgia through the Atlanta suburbs, technical colleges are forging alliances with local schools, businesses, industries and each other. They are generating millions in shared grant dollars, and at the same time dramatically changing the shape of education in the state.
There is an understandable weariness in Ron Jackson's voice these days. For the past several years, Jackson has been patching up holes in an ever more porous state budget. The most common remedy for Jackson's budget tightening efforts has been the merger, the act of combining technical colleges that share a bit of common ground in their service areas.
As the new year was beginning, Jackson was in the midst of what he believed would be the final merger. "I hope it will be the last one," he says. "But budget constraints being what they are, I can't guarantee that. Every one I've done recently I said was the last one, and I proved myself wrong every time." Jackson says he expects a budget reduction from state funding of about $27 million, with perhaps a little help from some nimble creativity in the management of a few sources over which he has some measure of control.
"We've increased our tuition, and that'll help us a little bit," Jackson says, but he is also relying on what he believes to be the greatest strength of the technical college system: relationships and partnerships.
"Our relationship with business is so intricately entwined that it really is the power of our system and how we deliver what we deliver," Jackson says. "Our partnership with the University System is new and growing to where we have articulation agreements for 27 of the core courses that a student might take while enrolled in any of our programs. A student can transfer those to any University System college. We're going to sign an agreement with all the private colleges in Georgia to allow the transfer of credits in those same 27 courses."
Individual technical colleges have partnerships with their local school systems and client businesses that hire them to perform customized training for their workers.
Jackson says the TCSG also counts as partners the members of their advisiory committees and local boards, as well as the volunteers who serve on their foundations. The advisory committees, for instance, can bring ideas for new training programs to their local college and, in many cases, the ideas become part of the curriculum in six weeks or less. "All of that is a synergy that we get from those partnerships that keeps us on the cutting edge of supporting businesses in Geor-gia," Jackson says. "Most of our colleges now are a size where they are at least economically viable, as long as we don't continue to have resource challenges."
Georgia's 24 post-merger technical colleges have access to their own resources, from the companies for which they provide certain training courses and from federal, state, private and local grants.
Athens Technical College is in line to be among the largest beneficiaries of recent federal grants, thanks to a 2012 $13.6-million grant from the U.S. Department of Labor. The school is the lead technical college in a three-college partnership with the Caterpillar company in training programs for the heavy equipment manufacturer and will receive a $9.6-million portion of the grant.
"That is believed to be the largest such federal grant ever received by the technical college system," says Flora Tydings, president of Athens Tech. "It is certainly the largest such grant ever received by Athens Tech. Training is under way at a new Quick Start Training Center on the Athens Tech campus."
Caterpillar has begun hiring for administrative positions, with 30 employees on the payroll, a modest beginning for what is expected to be 1,400 workers on board when the initial training period has been completed and the first products are coming off the line – by the end of this year.
"We do have a lot of training [yet] to do," Tydings says. "We've made a 10-year commitment to Caterpillar for the training center." Nearby Madison County is expected to be a rich source for workers, a fact that stimulated a $3.65-million grant for a career academy to serve future workforce needs of Caterpillar, according to Tydings.
Tydings and her Athens Tech team were just pausing to take a breath in August 2012 after launching the Caterpillar training when word came that California-based Baxter Inter-national Inc. planned to invest more than $1 billion in new facilities across several counties not far from the Caterpillar site near Athens, giving Athens Tech another training partner.
"Baxter was a little bit longer project," Tydings says, "but it really moved along when the commissioner of the technical colleges and the chancellor of the University System flew out to California to meet with the Baxter execs."
The Baxter plant site, which will eventually employ 1,500 in the production of bio-pharmaceuticals and plasma, will include a warehouse and distribution center, in addition to lab technicians and administrative personnel. "We have about 33 companies in the Athens area that we've been supplying lab techs, so this is an area we've been accustomed to training in for quite some time," Tydings says. "Both these projects [together] are huge, definitely right there with Kia. These two companies will change the workforce of Northeast Georgia once they reach full staffing." They are already changing the nature of high school education.
Career Academies
In the mix of training partners for Athens Tech, including Caterpillar and Baxter, is the Madison County School District, beneficiary of the $3.65 million to jumpstart a career academy in a partnership with Athens Tech to train future Caterpillar employees. The regional career academy also counts as partners the school systems of Clarke and Elbert counties. Such partnerships mark a trend in education and workforce training operating in tandem for high school students.
There are 27 career academies across Georgia in partnership with technical colleges serving 28,000 students last year, with those figures representing 35 local school districts, according to Mark Whitlock, CEO of the Central Educational Center (CEC) in Newnan, a charter college and career academy that is itself a partnership with local businesses, Coweta County School System and West Georgia Technical College.
"We began with the idea we needed to respond to the new needs of business and industry in the area," Whitlock says of the 13-year-old CEC, which has become a popular first stop for Georgia counties seeking advice from the nonprofit on starting a career academy. "Those needs centered around greater use of automation, greater use of technology, less supervision and more global customers."
Business and industry executives were asking the CEC if a way could be found to get high school students on track to possessing the technical skills at an age younger than 27, 27 being the average age of technical college enrollees. "Georgia businesses were saying, 'We'd like younger people to have that level of maturity with technical skills,'" Whitlock says.
That led high schools to offer high levels of technical programs for students being ushered into dual enrollment programs with the technical colleges, enabling them to be both high school students and enrollees at the technical schools. "We had 206 young people [in Coweta County last year], and most of them earned at least one technical college certificate before they graduated from high school," Whitlock says. "That means they're on their way to the possibility of an associate degree with the technical college at some point, and certainly at an age far less than 27."
Merging Resources
Middle Georgia Technical College in Warner Robins is merging with Central Georgia Technical College, with its main campus in Macon in what TCSG Commissioner Jackson is hoping will be the last marriage of its kind in the state. "This merger creates an 11-county service area that is 40 percent larger than the landmass of Delaware," says Ivan Allen, president of Central Georgia Technical College, the name of the newly merged institution. "That area will have over a half-million people. What the merger will do is give this college more resources and a greater capability to meet the needs of Robins Air Force Base, as well as the needs of defense contractors who service Robins."
One of those contractors is Northrop Grumman, a longtime contractor with the base. "We have a long history with them for aircraft maintenance and avionics training on Robins, where we've offered over 16,000 hours in training per year," Allen says. Interest in the well-being of the base is intense in this part of the state, due in part to the 23,000 workers there who take home in excess of $1 billion in pay each year.
"Warner Robins Air Force Base is critically important to the economy of Georgia and Middle Georgia, and that college merger now is also kind of synergistic because the University System is also merging Middle Georgia College and Macon State College," says Jack-son. "The governor has recommended in his [2014] budget a new [$10-million] military training center to be shared jointly between the university system and the technical college system. That would centralize our military affairs outreach, not only for Warner Robins, but also for the state in general."
The center would provide training and educational opportunities for the military and their families, as well as veterans coming back from war zones and seeking to re-enter the workforce, according to Jackson.
For Jackson, the Air Force base is just one example of a new spirit of cooperation between the technical colleges and the university campuses.
"The chancellor of the university system and I are very much in concert with the governor on closer working relationships," Jackson says. "Our two boards are working together now in ways they've never worked before."
Health Focus
Dr. Ray Perren is president of Wire-grass Georgia Technical College, one of the products of a merger, and an institution that has partnered with Valdosta State University and South Georgia Medical Center to produce sorely needed nurses and other healthcare professionals for his college's South Georgia region and the rest of the state. Perren is optimistic when discussing the future prospects for his campus and its students.
"About 40 percent of our student body is in one of these healthcare programs, and right now we have about 4,000 students," Perren says. "There is a great demand for these healthcare professionals, and the projections for the future say that trend will continue on, fueled by an aging baby boomer population and the growth in popularity of the South Georgia area as a retirement destination."
Perren has noticed growth in the number of enrollees who already have a bachelor's degree. "We still do have some people who are coming to cross-train. Of the number of people coming to Wiregrass to get an associate degree or diploma in a specific field, and who hold bachelor's degrees or higher, healthcare would be among the most popular choices," he adds. "Economists are telling us that 80 percent of the jobs that will be created over the next 10 to 15 years will demand something be-yond high school, but not necessarily require a four-year degree."
As pleased as he is by the partnerships and new working relationships with university system schools, Commissioner Jackson is very clear about the role of the technical colleges. "We don't want to be transfer institutions. We still want to be workforce development driven," he says. "Our enrollment went down last year, from 195,000 to 170,000. I believe it will be up by the end of this year."
Training Powerhouse
Three years ago, Terry Elam, president of Augusta Technical College, received an offer he couldn't refuse, to do something he'd never done before.
"We were approached by Southern Nuclear [a division of the Southern Company], along with several other major nuclear plant owners in the Southeast, including Duke Power, about a nuclear technology program to train operators for the new nuclear reactors being built in South Carolina and, of course, at Plant Vogtle," he recalls.
"We saw it as a challenge because, obviously, it was something we had never done before." In fact, Augusta Tech already had some assets in place that would fit nicely into a program designed to teach and train operators at the nuclear plant. After all, Plant Vogtle is only 30 miles from the school's campus, and Augusta Tech was already teaching some basic courses necessary to the nuclear operator class. "At the same time, Southern Nuclear was setting up its own training facility in the Augusta area to train workers for reactors 3 and 4 now under construction," Elam says.
"They actually moved on campus, which really fostered a great relationship because they were doing some partnerships with other companies, and we were able to take advantage of the training done by those other companies."
Faster than an atom in flight, Augusta Tech became a nuclear power in Georgia's technical college system. A curriculum was developed to create nuclear operators who, after they finished their coursework with a two-year associate degree, could walk straight into jobs and starting salaries of $50,000 a year, according to Elam.
The class of 2011 had 40 students, with about 23 of those hired by Plant Vogtle. "The next year we took 60 students, the group that is in school now, and we're about to take our third class," Elam says. "There's an internship at the plant, and one of the unique things about it is that at the first two classes they allowed their employees, [who are] subject-matter experts, to come to our classes, co-teach, observe the students and help them through the program." Southern Nuc-lear has also chipped in with books and scholarships.
"It's a great partnership," Elam says. "It's been an academically challenging major for our students, but the outcome for jobs has been really good and the pay is way above the norm." – Ed Lightsey
Categories: Education, Features


Do you like carrots? Enjoy long frolicking in the grass? If you answered yes, we have the perfect job for you!
Towne Square Mall is looking to hire Easter Bunny Characters for this Easter Season. Bunny Characters could even make up to $15 an hour!
If you are interested hop on over and apply!