If you?re looking for a reliable company to build the home of your dreams, look no further?Schuler Quality Homes LLC is here to make it happen! Our team will work with you to design a custom floor plan with all the space and features that meet your needs and budget. We have over 30 years of experience with constructing high-quality homes, so you?ll have peace of mind knowing your new home will be built to last!
We build new homes for residents throughout Ohio, including Highland County, Clinton County, Fayette County, Clermont County, Ross County, Adams County, Brown County, Greene County and Clark County.


Procrastination seems to be my plight.
With last minute anxiety, I search for insight.
I have read many words that are not my own.
There is no joy in memorizing another author's poem.
I think of all those moments when I could have worked.
But instead I enjoyed the now and let the future lurk.
Listening to nature's green song and talking with friends.
I see no reason to make amends.
Procrastination makes me feel alive.
Not just another bee of the hive.
Preparing five hours to talk for one.
Is a waste of time for a child of the sun.


Bold and stylish, the Lumisource Tetra End Table will draw will eyes from any angle. The unique geometric design paired with wood and brushed stainless steel, creates a combination that will compliment a variety of decor styles. The single wood drawer makes it easy to maintain a clutter-free room because of the built in storage, the perfect piece to place next to a bed, sofa or easy chair.


Are you an experienced Primary Teacher who is looking for extra responsibility and a school that recognises hard work by rewarding its teachers with promotion and professional development?
Would you be keen to work in a school that is graded as 'Good' by Ofsted but has ambitions of becoming even better and is keen to tap into the knowledge of its excellent class teachers?
Tradewind has supported the Head Teacher at this fantastic inner London School to appoint the very best staff available. This September they are looking to add a Senior Primary Teacher to their ranks! This is a rare opportunity for join a fantastic school!
This is an Ofsted 'Good' 2 form entry school, located in the heart of Haringey close to Tottenham Hale tube station. The school has recently celebrated its 60th anniversary and has long been well regarded as a strong school by families in the local area.
The school attracts pupils from a variety of backgrounds and beliefs and higher than average EAL, SEN and free school meals pupils mean that the starting point of many pupils who join the school are below expected ability level. The school works hard to ensure they catch up quickly which is why their value-added score is one of the best in the borough.
The School is looking for a talented Senior Primary Teacher with a passion for literacy or numeracy. The opportunity to help develop either one of these important subjects across the school will enhance any CV and is a direct path into senior leadership at this school.
If you would like extra information on the school and this Senior Primary Teacher role then we would ask you to contact Adrian at Tradewind on 0207 845 6279 for a confidential discussion. Alternatively, please email your CV to adrian.holder@twrecruitment.com for an immediate call back!
Job Description: Full job description available by contacting us.


text:
Davis Funds
» Davis ETFs
You are now leaving www.davisfunds.com.
Return to Video Archive
Why financials are more attractive today than in decades
The opportunity: Financial companies' valuations do not reflect their growing earnings power and stronger balance sheets
Share Return to Video Archive
Prospectuses and Forms
More videos from Davis Funds
Davis Global Fund & Davis International Fund Portfolio Update
PM Danton Goei on building portfolios distinctly different from the index that have outperformed their index since inception; compelling global businesses in areas as diverse as ecommerce, social media, online education, leading Industrials and Financials
Watch Now Watch Now
Opportunities in Today's Market
Companies and sectors that we believe represent the greatest opportunities today, ranging from high growth digital economy leaders to great, durable and growing companies being offered at prices not seen in years.
This report is authorized for use by existing shareholders. A current Davis Financial Fund prospectus must accompany or precede this material if it is distributed to prospective shareholders. You should carefully consider the Fund's investment objective, risks, charges, and expenses before investing. Read the prospectus carefully before you invest or send money.
DAVIS DISTRIBUTORS, LLC (DDLLC) paid MackTrack Inc. their customary licensing fee to reprint this profile. MackTrack Inc. is not affiliated with DDLLC, and DDLLC did not commission MackTrack Inc. to create or publish this profile.
Morningstar Overall Rating of 4 stars. 93 funds in the Financial category. Based on risk-adjusted returns. The Morningstar rating/number of funds is provided as of March 31, 2016: three years, 3 stars/93; five years, 3 stars/88; and ten years, 4 stars/73. Class A shares. Past performance is not a guarantee of future results.
This video is not a solicitation for Davis Large Cap Value Portfolios, Davis New York Vetnure Fund, or Selected American Shares.
This video includes candid statements and observations regarding investment strategies, individual securities, and economic and market conditions; however, there is no guarantee that these statements, opinions or forecasts will prove to be correct. These comments may also include the expression of opinions that are speculative in nature and should not be relied on as statements of fact.
Objective and Risks. Davis Financial Fund's investment objective is long-term growth of capital. There can be no assurance that the Fund will achieve its objective. Under normal circumstances the Fund invests at least 80% of its net assets, plus any borrowing for investment purposes, in securities issued by companies principally engaged in the financial services sector. Some important risks of an investment in the Fund are: stock market risk: stock markets have periods of rising prices and periods of falling prices, including sharp declines; manager risk: poor security selection may cause the Fund to underperform relevant benchmarks; common stock risk: an adverse event may have a negative impact on a company and could result in a decline in the price of its common stock; large-capitalization companies risk: companies with $10 billion or more in market capitalization generally experience slower rates of growth in earnings per share than do mid- and small-capitalization companies; mid- and small-capitalization companies risk: companies with less than $10 billion in market capitalization typically have more limited product lines, markets and financial resources than larger companies, and may trade less frequently and in more limited volume; headline risk: the Fund may invest in a company when the company becomes the center of controversy. The company's stock may never recover or may become worthless; financial services risk: investing a significant portion of assets in the financial services sector may cause the Fund to be more sensitive to systemic risk, regulatory actions, changes in interest rates, non-diversified loan portfolios, credit, and competition; foreign country risk: foreign companies may be subject to greater risk as foreign economies may not be as strong or diversified; emerging market risk: securities of issuers in emerging and developing markets may present risks not found in more mature markets; foreign currency risk: the change in value of a foreign currency against the U.S. dollar will result in a change in the U.S. dollar value of securities denominated in that foreign currency; depositary receipts risk: depositary receipts may trade at a discount (or premium) to the underlying security and may be less liquid than the underlying securities listed on an exchange; focused portfolio risk: investing in a limited number of companies causes changes in the value of a single security to have a more significant effect on the value of the Fund's total portfolio; interest rate sensitivity risk: interest rates may have a powerful influence on the earnings of financial institutions; credit risk. The issuer of a fixed income security (potentially even the U.S. Government) may be unable to make timely payments of interest and principal; and fees and expenses risk: the Fund may not earn enough through income and capital appreciation to offset the operating expenses of the Fund. See the prospectus for a complete description of the principal risks.
Davis Advisors is committed to communicating with our investment partners as candidly as possible because we believe our investors benefit from understanding our investment philosophy and approach. Our views and opinions include "forward-looking statements" which may or may not be accurate over the long term. Forward-looking statements can be identified by words like "believe," "expect," "anticipate," or similar expressions. You should not place undue reliance on forward-looking statements, which are current as of the date of this report. We disclaim any obligation to update or alter any forward-looking statements, whether as a result of new information, future events, or otherwise. While we believe we have a reasonable basis for our appraisals and we have confidence in our opinions, actual results may differ materially from those we anticipate.
The information provided in this material should not be considered a recommendation to buy, sell or hold any particular security. As of March 31, 2016, the top ten holdings of Davis Financial Fund were: Markel, 6.8%; Wells Fargo, 6.7%; Berkshire Hathaway–Class A, 5.3%; Visa–Class A, 5.3%; Chubb, 5.1%; American Express, 5.1%; Bank of New York Mellon, 5.0%; JPMorgan Chase, 4.8%; U.S. Bancorp, 4.5%; and Goldman Sachs Group, 4.2%.
Davis Funds has adopted a Portfolio Holdings Disclosure policy that governs the release of non-public portfolio holding information. This policy is described in the prospectus. Holding percentages are subject to change. Visit davisfunds.com or call 800-279-0279 for the most current public portfolio holdings information.
For each fund with at least a 3-year history, Morningstar calculates a Morningstar Rating™ based on Morningstar's risk-adjusted return measure that accounts for variation in a fund's monthly performance (including the effects of sales charges, loads, and redemption fees), placing more emphasis on downward variations and rewarding consistent performance. The top 10% of funds in a category receive 5 stars, the next 22.5% receive 4 stars, the next 35% receive 3 stars, the next 22.5% receive 2 stars and the bottom 10% receive 1 star. (Each share class is counted as a fraction of one fund within this scale and rated separately which may cause slight variations in the distribution percentages.) The Overall Morningstar Rating™ for a fund is derived from a weighted average of the performance figures associated with its 3-, 5-, and 10-year Morningstar Rating™ metrics. The Morningstar Ratings™ are for the specified share class; other classes may have different performance characteristics. Unlike Morningstar Ratings™, Total Return Rankings do not take into account a sales charge. Ratings are based on past performance and are not a guarantee of future results. Class A shares maximum sales charge is 4.75%.
Broker-dealers and other financial intermediaries may charge Davis Advisors substantial fees for selling its products and providing continuing support to clients and shareholders. For example, broker-dealers and other financial intermediaries may charge: sales commissions; distribution and service fees; and record-keeping fees. In addition, payments or reimbursements may be requested for: marketing support concerning Davis Advisors' products; placement on a list of offered products; access to sales meetings, sales representatives and management representatives; and participation in conferences or seminars, sales or training programs for invited registered representatives and other employees, client and investor events and other dealer-sponsored events. Financial advisors should not consider Davis Advisors' payment(s) to a financial intermediary as a basis for recommending Davis Advisors.
The S&P 500® Index is an unmanaged index of 500 selected common stocks, most of which are listed on the New York Stock Exchange. The Index is adjusted for dividends, weighted towards stocks with large market capitalizations and represents approximately two-thirds of the total market value of all domestic common stocks. The S&P 500 Financials is a capitalization-weighted index that tracks the companies in the financial sector as a subset of the S&P 500® Index. Investments cannot be made directly in an index.
Shares of the Davis Funds are not deposits or obligations of any bank, are not guaranteed by any bank, are not insured by the FDIC or any other agency, and involve investment risks, including possible loss of the principal amount invested.
Davis Distributors, LLC, 2949 East Elvira Road, Suite 101, Tucson, AZ 85756, 800-279-0279, davisfunds.com
Family of Funds
New York Venture Fund
International Fund
Financial Fund
Appreciation and Income Fund
Government Bond Fund
Government Money Market Fund
Other Ways to Invest
Value Portfolio
Financial Portfolio
Investment Discipline
Sell Discipline
The Davis Investment Discipline Applied to Real Estate
Davis Funds Attributes
Investment Team Biographies
Insights About Davis Advisors
Insights into Successful Investing
Prospectuses and Applications

redpajama_set_name: RedPajamaCommonCrawl


Hi,I am Arun.I worked as an Anchor/News Reader in a local channel in Tamilnadu. My field of passion is an Acting.I am Interested to Act in a Movies/Serial/Short films in any role which is suitable for me. Also I am interested in modelling and I wish to be model in an Ad Films.Basically I am a Singer i learned Carnatic music for 5 Years and also I am talented in Swimming,Horse Riding,Bike Riding and Driving (Auto,Car,Van).I am looking for an opportunity to prove my Acting skills in the film industry.
I worked as an Anchor/News Reader in the channel.I hosted a live show during Dhassara Festival by interacting with different family regarding Navarathiri Kolu and I hosted many recorded shows like Box office,Top 10 Songs.


British runner Dan Lawson is on his way to breaking the nine-day record running across the entire island of Great Britain.
British vegan ultrarunner Dan Lawson, 44, is currently attempting to set a new record running 874 miles across the island of Great Britain, from the northern tip of Scotland to the western tip of Cornwall, England, in less than nine days. "This will be his biggest running challenge yet," a crew member said. "He would like to beat the current record of nine days, two hours, 26 minutes—the phenomenal time by Andrew Rivett. He is well-aware of how hard this will be and will put everything he has into it." Lawson is currently completing his fifth consecutive day of running an average of 90 miles each day. The challenging route includes traversing the Cairngorms mountain range in Scotland and Lake District mountains in England. Dawson already holds multiple world-class race titles, such as Britain's Grand Union Canal Race, the 400K Ultra Gobi Race, and the UltraBalaton 218K. As further evidence that a plant-based diet is optimal for endurance sports, last month, 53-year-old vegan runner Catra Corbett set the fastest known time on the 310-mile Muir Ramble Route course through California.


Kraftmaid Bathroom Closet – Look in your cupboard – fast. It is packed with packed with so much things which you cannot even find the things you really need, right? It is time to wash your closet out. The great news: you do not have to throw out everything. If you are reorganizing your closet, the very first thing you have to do is assess what you want to keep and what you want to throw away.
The next thing? Choose the ideal custom cabinet program to organize your lifetime. It's possible to use a pre-measured closet system. This machine has a fairly rigid set of shelves, gadgets, and racks, made to fit in the area you measure your cupboard to provide.
This procedure makes the most effective use of space, provided your cupboard is set to match one of the pre-made methods available. But it is not flexible for those who have, for instance, a fairly small clothing selection but a thousand pairs of shoes and matching purses. The next way to quickly organize your cupboard is by using a closet organization kit. These kits are much more flexible in size and generally consist primarily of many different modules, frequently expandable plastics.
A closet organization kit is easier to modify but doesn't make the most effective use of space available. Some people pick a method somewhere in between those, with a portion of the closet devoted to a rigid closet system and the remainder flexible to utilize organization kits and similar individual modules.
Tags : Kraftmaid bathroom wall cabinet | Kraftmaid bathroom cabinet catalog | Kraftmaid bathroom closet | Kraftmaid bathroom cabinet dimensions | Kraftmaid bathroom cabinet.


Digital painting is SO exciting, especially for plein air painting and life drawing because the iPad is just SO EASY to take along – anyplace! Personally, I ONLY use digital painting when I can't use real paints in my studio, like when I'm away from home or out plein air painting BUT I'm certainly enjoying pushing it to the max.
In early 2018 I spent 5 week studying Spanish and doing plein air painting in Guanajuato, Mexico. WOW! You can take an iPad anywhere and you certainly can't do that with real paints. I was able to be very painterly, freely plein air painting in churches, streets – everywhere! The more you work with the digital painting and digital drawing apps, the more you progress, just like any skill.
Digital painting images can be printed on paper, canvas, aluminum with beautiful results.
MORE Digital painting in life drawing.


text:
Q: gradle directory in an Android Studio project There is a directory called gradle in my Android Studio project. They don't say it should be excluded from version control. What is in this directory?
Update #1.
Android Studio bug. It updates gradle/wrapper/gradle-wrapper.properties every time I run it.

A: The directory gradle having a Gradle Wrapper inside it
The wrapper is something you should check into version control. By distributing the wrapper with your project, anyone can work with it without needing to install Gradle beforehand.
Even better, users of the build are guaranteed to use the version of Gradle that the build was designed to work with. Of course, this is also great for continuous integration servers (i.e. servers that regularly build your project) as it requires no configuration on the server.
That is why it is not excluded from version control.

redpajama_set_name: RedPajamaStackExchange


If you regularly shop at membership warehouse clubs like Costco, Sam's Club and BJ's Wholesale Club, or big box stores like Walmart and Target, you probably understand why they offer headache remedies in the front of the store and booze in the back.
Sometimes you need both to endure the experience.
But Jordan Page, a mother of five and the blogger behind Fun, Cheap or Free and Budget Boot Camp, manages to stay sane while shopping and says she also enjoys it! These are her tried-and-true tips for shopping at the mega stores.
1. Decide which store is right for you.
Membership stores: If there are only one or two people in your household, Page suggests you should weigh the cost of membership against money saved. If you feel like you're not saving enough money over the year to pay for the membership, ask the manager if you qualify for a refund.
Big box stores offer apps that give extra savings to customers, too. For example, the Cartwheel app at Target gives special discounts on certain items scanned with the app. Walmart's Savings Catcher app refunds the difference in price as compared to top local competitors' advertised prices.
2. Make a smart shopping list.
For example, unless your family can realistically consume 5 pounds of bananas in a few days, it's better to buy exactly the number of bananas you need at your local grocer.
Your phone also has a calculator, which comes in handy when figuring out the price per unit of any item. It can also keep a running total of what you're buying so you won't go over budget.
3. Discover the best time to shop.
Since every store is different, talk with the workers at your favorite store for tips on when to shop. Looking for the freshest produce? Ask employees in the produce section when they get deliveries. Want to make sure your favorite grocery items are in stock? Ask stockers what day shelves are usually stocked. Don't like long lines? Ask the cashiers for the lightest shopping days and times.
Of course, if you're shopping online, any time is a good time to shop.
Sam's Club members can shop online and either have their order delivered to their home for a fee or they can arrange to pick up purchases at the store the next day at no extra charge — and there's no minimum purchase required. Costco offers online shopping and home delivery for a fee.
Walmart also offers free same day pick-up but requires a $50 minimum purchase.
Target offers free shipping on purchases over $25 and same day pick up at stores, with no minimum purchase.
4. Take advantage of rebates and sales.
While Costco and Sam's Club do not accept manufacturers' coupons, BJ's does accept them. In addition, all three stores have their own coupon and rebate offers that can be extremely valuable.
Coupon discounts are automatically taken at the register. Keep the sale booklet handy when making your list and while shopping; or get the app for in-store sale items each month. Keep in mind that stores like Costco rotate sales every two to three months. That means if there's a coupon on coffee, for example, buy enough to last until coffee goes on sale again two to three months later. Ask your local store how often sales are rotated.
Learn to read the codes: At Costco, if an item is not going to be restocked, there will be an asterisk on the price label on the shelf front. So, if you love pitted dates, for example and you see an asterisk next to the price, it's time to stock up!
Likewise, if an item is marked down at Costco, the price will always end in 97 cents. If you find an item that you like marked with an asterisk and ending in .97, grab all your budget can bear before it's gone.
5. Utilize 30-day low-price guarantees.
Check to see if your warehouse or big box store refunds customers for the difference in price if the item purchased goes on sale within 30 days. Costco does, but check with your local Costco store to see if it requires the original receipt, or if employees will be able to look up your receipt using your membership number.
6. Compare prices at the pharmacy.
At both Sam's and Costco, shoppers do not need a membership card in order to purchase prescription medicines. Compare these store prices with those at your local pharmacy. You may discover a substantial savings on your prescriptions, plus they sometimes offer free health screenings for high blood pressure, cholesterol, vaccines and more.
7. Check out store brands.
Warehouses and big box stores do not stock every brand of every item made. If they did, they'd lose money, said Page, because they'd have so much inventory. To guarantee the best prices for customers, they usually stock the most popular brand of an item, like Bounty paper towels, as well as the store's own brand of paper towels.
Here's what you don't know: At Costco, many times the same company makes both products. They are not identical — one may be thinner or larger — but they are often very close in quality. This goes for common household items and even certain types of wine.
"If you haven't tried a warehouse store brand item, give it a try," said Page.
8. Score big in the meat department.
Most people shop for food at warehouse stores but the biggest dollar savings are often on the other side of the store in places you might not expect. By purchasing bulk sizes of non-perishables, like laundry detergent and baby diapers (one of Costco's biggest sellers), you save the most money — and these products won't spoil.
Other money-saving non-perishables that offer substantial savings include electronics, jewelry, eyeglasses, photos, tires and gasoline. Plus, the stores carry many big name brands.
Warehouse stores operate on an early in/early out method. That means that seasonal items, like yard and lawn care products, appear in their stores months ahead of their competitors. So you should think ahead, too, and stock up when seasonal items become available. If you buy one or two items each time you shop, you won't have to pay full price at your regular store later.
This post was originally published on Feb. 2, 2017.


text:
irishmirrorLoad mobile navigation
Mirror.co.uk
BelfastLive.co.uk
Rare interview gives glimpse of what Roy Keane was really like in training as a player
Keane was a legendary figure for Manchester United and an ex-player has lifted the lid what he was like in training.
irishmirror
Gareth Fullerton
Roy Keane in training
Want the day's sports headlines straight to your inbox? Our FREE newsletter will keep you ahead of the game
From Roy Keane's temper to Wayne Rooney's wild tackles, former goalkeeper Roy Carroll says Manchester United's old-school training sessions demonstrated the winning mentality at the club.
Carroll spent four years at Old Trafford and went on to win a Premier League medal in 2002-03, and also lift the FA Cup.
The ex-Northern Ireland international played his part in a dominant reign under legendary former manager Sir Alex Ferguson, and no-nonsense captain Keane.
Carroll says both men were driven to succeed, and their hunger to win was ever-present - even during simple 5-a-side games.
He also recalls a young striker by the name of Rooney flying into 'knee-high' tackles during box drills.
"I worked with so many great players, and they were all different," Carroll told Belfast Live's That's What I Call Football podcast.
"You had Paul Scholes who turned up for training, did the boxes and kicked a few balls into the net. He is a family man, so he went home after training.
"You then had Cristiano Ronaldo who was a different character. He worked so hard on his game as you would imagine, staying after sessions to practice.
"It was scary how many of these young players came through the ranks at the time. I remember Rooney coming in and he was so young.
"We did these boxes. You had six or seven players outside and two players in the middle. And Rooney was just slide tackling people when he was in the middle.
"He was going for the knees and everything. And it was just the speed of the passing and the ball, it was unbelievable. It was proper boxes.
"We try and tell the young lads now with Northern Ireland: Do it quicker. Do it faster. We have been there and know what it is like, and you want those lads to take it on board."
And Carroll says nobody hated losing more than inspirational skipper Keane, even if was just a training session.
"Roy Keane. Jesus, I have never seen a man like it," Carroll said.
"In the 5-a-side, I used to be scared of playing for him in case I let a goal in. Because he would knock me out.
"But that was the winning mentality at Manchester United. You lose a 5-a-side game in training, everyone was upset.
"If we conceded a goal on Saturday, we would go up the other end and score two or three. It was like a basketball game.
"It was the mentality of 'we're going to win no matter what'. And that was the mentality of Sir Alex Ferguson."
While Manchester United's players were elevated to football stars following their rise to the top under Ferguson, Carroll says there were no heirs or graces about the all-conquering squad.
Carroll arrived from Wigan Athletic in 2001 after being watched by Ferguson for two years.
He admits he "didn't sleep for two weeks" ahead of his arrival at Old Trafford, but says "superstars" like David Beckham helped make the daunting transition a lot easier.
"I was really nervous at the first training session. But then David Beckham comes up and introduces himself, and I just stared at him and replied, 'I know who you are'. I didn't even introduce myself," Carroll laughed.
"I watched these superstars on TV, but when I arrived they weren't superstars. They were so welcoming, every single one of them.
"That made me feel better. Some clubs in the lower leagues, the players hardly speak to you when you arrive.
"When I went through League Two and Three, it was a lot harder moving clubs. But when I moved to the Premier League, everyone at Manchester United made me feel welcome.
"And my first game was against Aston Villa in the sixth game of the season and I loved it."
Former Northern Ireland shot-stopper Carroll, who won 45 caps for his country, recalls having to earn his stripes when he first burst onto the international scene as a teenager.
"When I first came in to the Northern Ireland squad at 18 years old there was big Taggs (Gerry Taggart), Neil Lennon, Jim Magilton. I remember sitting at the front of the bus because you weren't allowed to sit at back for three or four years," he said.
"It is a bit more comfortable now for young players coming into the squad.
Ruby Walsh believes Jordan Gainford and Sam Ewing will be "gutted" with Davy Russell's return to the saddle
Jack O'Donoghue says Munster have learned to 'cop on' if Saints come on heavy
Tributes pour in after death of young GAA star Saoirse Buckley
Latest Burnley bid for Michael Obafemi turned down by Swansea City
Aidan O'Shea breaks silence over Lee Keegan retirement after South Africa holiday
Get the latest sports headlines straight to your inbox by signing up for free email alerts
Follow Irish Mirror
Barclay's Premier League
Joe CanningInside Joe Canning's private life including wife Meg and romantic honeymoon away as he appears on Laochra GaelCanning decided to retire after the 2021 season and has since tied the knot to his partner Meg.
Conor McGregor goes public and confirms next UFC move
The UFC star took to social media to confirm his next move.
Derry City fend off competition from rivals to sign midfielder
Derry City FC
Derry City are set to complete the signing of former Ireland underage international midfielder Adam O'Reilly in the coming days.
Erling Haaland's release clause, Man City exit plan and "dressing room burden" claim
Erling Haaland has been a revelation since signing for Manchester City, netting 25 goals in just 19 appearances - nine more than three-time Golden Boot winner Harry Kane
Everyone says same thing about Roy Keane as he shaves off moustache
Roy Keane's facial hair had been causing quite the stir on social media in recent weeks.
Red Bull F1Max Verstappen has target on his back as worries remain over Sergio Perez relationshipIn Mirror Sport's F1 2023 season preview, Daniel Moxon explores how well prepared Red Bull will be as they look to defend both titles for the first time in a decade
Arsenal's XI for last FA Cup tie vs Man City highlights Mikel Arteta's ruthless overhaul
With Arsenal making the trip to Manchester City in the FA Cup, it is worthwhile analysing just how much has changed with the Gunners since the sides last met in this competition
Underdog tag can work to Ireland's advantage in Euro qualifiers, says ex-Dundalk star
Stephen Kenny
Ireland have been handed a nightmare drawn for the Euro 2024 qualifiers, with France and the Netherlands as rivals.
What time and TV channel is Ulster v Stormers today in the URC?
Ulster take on Stormers tonight as URC action resumes.
Paul Geaney plays down Tyrone comparison as Kerry start year on back foot
Kerry GAA
'We haven't had a whole pile of lads leaving the panel, I think Tyrone had a shot of guys leaving their panel after their win. We are in a slightly different boat to them.'
Irish passportIrish passport warning as little-known rules could see holidaymakers turned away from airportFrom the number of blank pages to the condition of your passport, here's what you need to know
All the people who don't need to pay Ireland's TV licence fee and may not even realise it
Households in Ireland with a television, even if it is broken, are required to have a TV licence which costs €160 every year. But there are certain groups who can get a free TV licence and they may not even realise it.
Met Eireann verdict on Ireland 'Polar Vortex' fears as weather phenomenon could trigger big freeze
Met Eireann
Some weather experts have sounded alarm bells over the emergence of a weather phenomenon that could bring another cold blast to the country. It comes as one long-range weather map shows Ireland blanketed in snow.
Fresh blow for Christy Dignam as Aslan star's nephew Christopher has died
Inmate, 25, found dead at Castlerea Prison named - as he is believed to have passed away in his sleep
Donegal man Keith Boyle was found dead in his bed at Castlerea Prison in Co Roscommon on Thursday morning
Conor McGregorConor McGregor's partner Dee Devlin's public display of affection as UFC star denies allegation he assaulted a womanThe two-time UFC champion has denied allegations he assaulted a woman on his multi-million euro yacht
Gabriel Agbonlahor names Liverpool players whose 'legs have gone' after Jurgen Klopp dig
The former Premier League star has not held back in his assessment of Liverpool and their issues this season as he calls into question Jurgen Klopp's ability to get a tune out of his players
Michael Healy Rae blasts calls for new safe drinking advice and says friend lived to 108 drinking whiskey every night
Michael Healy-Rae
The Kerry TD and publican says those suggesting it need to get themselves examined
HSE outlines four key steps to helping your child if they start choking after two tragedies in matter of days
Statistics show that in the European Union alone each year, an estimated 400 children, aged 14 years or younger die from choking
Dragons' Den winner secured £100k investment but claims he never saw a single tycoon again
Simon Heap went onto Dragons' Den and secured a £100,000 deal with Deborah Meaden and Peter Jones, but after that he claims he never heard from the business giants again so backed out of the lucrative investment
Man in his 20s rushed to hospital with 'stab wounds' following daylight assault in Dublin city
An Garda Siochana
The violent incident took place on Marlborough Street which was subsequently sealed off
Irish pint lover visits every single pub in Dublin in one day - and it took a surprising amount of time
The pub enthusiast covered a total of 34 kilometres, touching 238 pubs in a single day.
Gerry Hutch will learn his Regency trial fate - just days after his 60th birthday
Gerry The Monk Hutch
After 52 days, 13 weeks, hours of CCTV evidence, 10 hours of tapes , witnesses, maps, and the dramatic cross-examination of Jonathan Dowdall, the so-called 'Trial of the Century' finally came to a close today
Man who raped sleeping girlfriend is jailed - she tells court he "used my body for his selfish needs"
Francis Bourne (47) of, Buncrana, Co Donegal pleaded guilty to the rape of a woman at her home in Donegal on November 31, 2016
Cristiano Ronaldo has been criticised by manager Rudi Garcia for missing an opportunity to score during Al-Nassr's 3-1 loss against Al-Ittihad in the Saudi Super Cup
Aoibhin Garrihy says she didn't worry about Doireann making her Dancing With The Stars hosting debut - once she didn't fall down the stairs
Exclusive: Aoibhin spoke of her pride at seeing her little sister on the glitzy Rte One show
Toddler dies in 'tragic choking accident' at house in Cork
It's understood emergency services rushed to the scene and fought to save the little boy, but he died at the scene.
NTA publishes plans for Dublin's transport system with Luas, DART and Metrolink extensions
The plans include multiple extensions to the Luas to serve Finglas, Lucan, Poolbeg and Bray by 2028
Dermot Bannon reveals celebs cannot hide their real personalities on his shows - as he opens up about working with Julian Benson
Dermot Bannon
Exclusive: 'I think the country got to know the real Daniel through Room To Improve and they'll probably do the same with the real Julian.'
Male pedestrian, in his 40s, hospitalised with 'serious' injuries following Dublin crash
The injuries sustained by the male pedestrian are understood to be "serious"
A Place in the Sun viewers slam 'time-wasting' couple and their huge demands
Fans of A Place In The Sun were full of complaints about Thursday's episode as a couple searched for their dream home in Crete


The Maine Organic Farmers and Gardeners Association (MOFGA) is creating a ten-acre preservation orchard at its Common Ground Education Center in the town of Unity. The Maine Heritage Orchard (MEHO) will be home to more than 500 apple and pear varieties traditionally grown in Maine. Many of these varieties are now on the verge of extinction. The orchard is planted on a terraced, reclaimed gravel pit and is managed using innovative, organic orchard practices.


Quiet moments are often hard to be found at this time of year, at least for a lot of people, but they can usually be found (or created) when needed. At least, I hope that's been the case for all of you.
Here are a few of the things that have caught my eye between the holidays and a week-long plague (a rather horrible head cold that has kept me down for the count).
"I'm a homebody," he says. "I love to stay in at night, light a fire, have a whiskey and watch a movie or read a good book. People forget about books. They're always just turning on the television, but reading a good book is the most nourishing thing you can do."
My face is always at rest.
Unfortunately, so is my body.
But the psychologists discovered something they called a "bitchy resting face," which gave me pause, as I didn't realize that bitchy was a psychological term.
I also wondered if men could have a "bitchy" resting face.
Or if that was simply called a "face."
You can read the whole essay online at the Inquirer site.


In this paper the problem of semiautomatic tree-ring detection in scanned images of European larch wood sample is considered. In particular, the attention is paid to find image enhancement approach which increases the number of tree rings detected in the wood image by the CooRecorder software. The results provided by different preprocessing methods (including thresholding, contrast enhancement and various spatial filters) are assessed by means of the number of the detected tree rings. Discussion and interpretation of the results are also provided.
This work was co-financed by the Lodz University of Technology, Faculty of Electrical, Electronic, Computer and Control Engineering as a part of statutory project no 501/12-24-2-5416.
This work was co-financed by the AGH - University of Science and Technology, Faculty of Geology, Geophysics and Environmental Protection as a part of statutory projects no. 11.11.140.173, no. 11.11.140.613 and no. 11.11.140.626.


text:
Printed from https://ideas.repec.org/p/eab/microe/22113.html
Internationalization of Indian Enterprises : Patterns, Strategies, Ownership Advantages and Implications
Nagesh Kumar
(RIS)
The recent spate of large cross-border acquisitions e.g. Tata Steel-Corus, Hindalco-Novelis, and Tata Motors-Jaguar/Land Rover, among others and Greenfield investments by Indian companies have helped in focusing attention on the emergence of new corporate players on the global scene. Indias emergence as a source of FDI outflows is impressive for its level of development. It is argued that the destinations, sectoral composition, motivations, and entry strategies of Indian investments have been changing with magnitudes. This paper examines the sources of Indian companies ownership advantages and trends, patterns and implications. It has been argued that the source of their ownership or competitive advantage lies in their accumulation of skills for managing large multi-location operations across diverse cultures in India and in their ability to deliver value for money with their frugal engineering skills honed up while catering to the largerpart of income pyramid in India.
Nagesh Kumar, 2008. "Internationalization of Indian Enterprises : Patterns, Strategies, Ownership Advantages and Implications," Microeconomics Working Papers 22113, East Asian Bureau of Economic Research.
Handle: RePEc:eab:microe:22113
File URL: http://www.eaber.org/node/22113
Nagesh KUMAR, 2008. "Internationalization of Indian Enterprises: Patterns, Strategies, Ownership Advantages, and Implications," Asian Economic Policy Review, Japan Center for Economic Research, vol. 3(2), pages 242-261, December.
Louis T. Wells, 1983. "Third World Multinationals: The Rise of Foreign Investments from Developing Countries," MIT Press Books, The MIT Press, edition 1, volume 1, number 026273169x, September.
Nagesh Kumar, 2007. "Regional Economic Integration, Foreign Direct Investment and Efficiency-Seeking Industrial Restructuring in Asia : The Case of India," Macroeconomics Working Papers 22110, East Asian Bureau of Economic Research.
UNCTAD Secretariat, 2006. "World Investment Report 2005—Transnational Corporations and the Internationalization of R&D," Foreign Trade Review, , vol. 40(4), pages 85-108, January.
Dunning, John H, 1979. "Explaining Changing Patterns of International Production: In Defence of the Eclectic Theory," Oxford Bulletin of Economics and Statistics, Department of Economics, University of Oxford, vol. 41(4), pages 269-295, November.
outward investment; emerging multinationals; Indian multinationals;
F21 - International Economics - - International Factor Movements and International Business - - - International Investment; Long-Term Capital Movements
F23 - International Economics - - International Factor Movements and International Business - - - Multinational Firms; International Business
All material on this site has been provided by the respective publishers and authors. You can help correct errors and omissions. When requesting a correction, please mention this item's handle: RePEc:eab:microe:22113. See general information about how to correct material in RePEc.
For technical questions regarding this item, or to correct its authors, title, abstract, bibliographic or download information, contact: (Shiro Armstrong). General contact details of provider: http://edirc.repec.org/data/eaberau.html .


text:
\section{BSP Algorithm}
\label{sec:ParAlg}
Along with the sequential suffix array construction algorithm, described in Section \ref{sec:SeqAlg}, K\"{a}rkk\"{a}inen et al. \cite{KarkkainenSandersBurkhardt} discuss the design of the algorithm on various computation models, including the BSP model. They give a brief overview of a parallel suffix array construction algorithm, running on a $\emph{BSP}(p,g,l)$ machine, with optimal $O(\frac{n}{p})$ local computation and communication costs and requiring $O(\log^2 p)$ synchronisation steps. The algorithm uses a number of existing parallel sorting and merging algorithms to achieve this result. In the first part of this section we present a deterministic BSP algorithm that preserves these optimal local computation and communication costs while reducing the number of required synchronisation steps to a near optimal $O(\log \log p)$. Following this, a detailed algorithm analysis is presented.

The algorithm described in Section \ref{sec:SeqAlg} initially solves the suffix array construction problem on a sample of the suffixes of the input string, in order to gain important information that is then used to efficiently sort all the  suffixes. Sampling techniques are widely used in various fields ranging from statistics to engineering to computer science. In fact, a number of parallel algorithms exist that use sampling to efficiently solve problems, including sorting \cite{ShiSchaeffer,ChanDehne} and convex hull \cite{Tiskin_convexhull} algorithms. In \cite{Tiskin}, Tiskin presents a BSP algorithm for the selection problem, in which, not only is the data sampled, but, the sampling rate is increased at a carefully chosen rate in successive levels of recursion. This reduces the number of synchronisation steps required by the parallel selection algorithm from the previous upper bound of $O(\log p)$ to a near optimal $O(\log \log p$), while keeping the local computation and communication costs optimal. We make use of this technique, which we call \emph{accelerated sampling}, to achieve the same synchronisation costs for our parallel suffix array construction algorithm, while, again, keeping the local computation and communication costs optimal. In contrast with \cite{Tiskin}, in our algorithm the sampling frequency has to be decreased, rather than increased, in successive levels of recursion.

The algorithms presented in this section are designed to run on a $BSP(p,g,l)$ machine. We denote the sub-array of an array $a$ assigned to processor $\pi \in \srange{0}{p}$ by $a_{\pi}$ and extend this notation to sets, i.e.\  we denote by $A_{\pi}$ the subset of a set $A$ assigned to processor ${\pi}$.

Before detailing our algorithm, we give an overview of the parallel integer sorting algorithm introduced in \cite{ChanDehne}. The algorithm is based on the parallel sorting by regular sampling algorithm \cite{ShiSchaeffer}, but uses radix sorting to locally sort the input, removing the extra cost associated with comparison sorting. Given an array $y$ having $m$ distinct integers, such that each integer is represented by at most $\kappa$ digits, the algorithm returns all the elements of $y$ sorted in ascending order. If two integers are identical, then their index in the array $y$ is used to determine their relative order, i.e.\  for two identical integers $y[i] \equiv y[j]$, we assume that $y[i]$ precedes $y[j]$ if $i \leq j$ and $y[i]$ succeeds $y[j]$ otherwise. Since the presented suffix array construction algorithm runs on strings over $\Sigma = \mathbb{N} \cup \{-1\}$, then we can use the same algorithm, which we refer to as the \emph{parallel string sorting} algorithm, to sort an array of $m$ strings or tuples, each of fixed length $\kappa$. In this case, the algorithm has $O(\kappa \frac{m}{p})$ local computation and communication costs and requires $O(1)$ synchronisation costs. The algorithm, given an input array $y$ of $m$ strings over $\Sigma$, with each string of length at most $\kappa$, works as follows.

\vspace{4mm}

\noindent \textbf{Algorithm 2.} \textit{Parallel String Sorting}

\noindent \textbf{Parameters:} integer $m \geq p^3$; integer $\kappa$

\noindent \textbf{Input:} array of strings $y = y[0] \ldots y[m-1]$, with each string over $\Sigma = \mathbb{Z}$ and of size $\kappa$

\noindent \textbf{Output:} array $y$ ordered in ascending lexicographic order

\noindent \textbf{Description:}

The input array $y$ is assumed to be equally distributed among the $p$ processors, with every processor $\pi \in \frange{0}{p-2}$, assigned the elements $y\srange{\frac{m}{p} \pi}{\frac{m}{p} \left (\pi+1 \right )}$, and processor $p-1$ assigned elements $y\srange{\frac{m}{p} \left ( p-1 \right )}{m}$. Note that each processor holds $\frac{m}{p}$ elements, except the last processor $p-1$, which may hold fewer elements. We call this type of distribution of elements among the $p$ processors a \emph{block distribution}. Each processor $\pi$ first locally sorts sub-array $y_{\pi}$, using radix sorting, and then chooses $p + 1$ equally spaced samples from the sorted sub-array, including the minimum and maximum values of $y_{\pi}$. These samples, which we call \emph{primary samples}, are sent to processor $0$. Having received $(p+1)p$ primary samples, each of which is a string of length $\kappa$, processor $0$ locally sorts these samples, using radix sorting, and chooses $p + 1$ sub-samples, including the minimum and maximum values of the primary samples.  These chosen sub-samples, which we call \emph{secondary samples}, partition the elements of $y$ into $p$ blocks $Y_0, \ldots, Y_{p-1}$. The secondary samples are broadcast to every processor, and each processor $\pi$ then uses the secondary samples to partition its sub-array $y_{\pi}$ into the $p$ sub-blocks $Y_{0,\pi}, \ldots, Y_{p-1,\pi}$. Each processor $\pi$ collects the sub-blocks $Y_{\pi,\chi}$ from processors $\chi \in \srange{0}{p}$, i.e.\  all the elements of $Y_{\pi}$, and locally sorts these elements using radix sorting. The array $y$ is now sorted in ascending lexicographic order, however, it might not be equally distributed among the processors, so an extra step is performed to ensure that each processor has $\frac{m}{p}$ elements of the sorted array. Note that each primary and secondary sample also has the index of the sample in $y$ attached to it, so that any ties can be broken. \Square

The parallel suffix array construction algorithm presented below requires that the input string $x$ of size $n$ be distributed equally among the $p$ processors, using a block distribution, prior to the algorithm being called. Therefore, each processor $\pi \in \frange{0}{p-2}$ initially holds the elements $x\srange{\frac{n}{p} \pi}{\frac{n}{p} \left ( \pi+1 \right )}$, while processor $p-1$ holds elements $x\srange{\frac{n}{p} \left ( p-1 \right )}{n}$. We denote by $I_{\pi}$ the subset of the index set $\srange{0}{n}$ that indexes $x_{\pi}$, $\pi \in \srange{0}{p}$, i.e.\  $I_{\pi} = \srange{\frac{n}{p} \pi}{\frac{n}{p} \left ( \pi + 1 \right )}$, for $\pi \in \frange{0}{p-2}$, and $I_{p-1} = \srange{\frac{n}{p} \left ( p-1 \right )}{n}$. We require that every processor $\pi \in \frange{0}{p-2}$, also holds a copy of the first $v-1$ characters of the substring $x_{\pi+1}$, where $v$ is a parameter of the algorithm, to be able to locally construct its subset of super-characters. Finally, we we use the same indexing for $a$ and $a_{\pi}$, i.e.\  $a[i] = a_{\pi}[i]$.

The algorithm is initially called on string $x$ of length $n$, with parameters $n$ and $v = 3$.

\vspace{4mm}

\noindent \textbf{Algorithm 3.} \textit{Parallel Suffix Array Construction}

\noindent \textbf{Parameters:} integer $n \geq p^{\frac{9}{2}}$; integer $v \in \frange{3}{n}$

\noindent \textbf{Input:} string $x = x[0] \ldots x[n-1]$ over alphabet $\Sigma = \srange{0}{n}$

\noindent \textbf{Output:} suffix array $SA_x = SA_x[0] \ldots SA_x[n-1]$

\noindent \textbf{Description:}

\noindent \textit{Recursion base}

Recall that if all the characters of $x$ are distinct, then $SA_x$ can be obtained by sorting the characters of $x$ in ascending order. Therefore, we call Algorithm 2 on string $x$ with parameters $m = n$ and $\kappa = 1$. When the algorithm returns with the sorted list of characters, which we call $x'$, each processor $\pi$, holds the sub-list $x'_{\pi}$ of size $\frac{n}{p}$, and checks for character uniqueness in its sub-list. If all the characters of each sub-list are distinct, then, each processor $\pi \in \frange{0}{p-2}$, checks with its neighbour $\pi + 1$ to ensure that $x'[\frac{n}{p}(\pi+1)-1] \not = x'[\frac{n}{p}(\pi+1)]$. If every character is distinct then each character in the sorted list $x'$ is replaced by its index in $x$ and $x'$ is returned. However, if at any point in this process two identical characters are found, then the following steps are performed:

\noindent \textit{Step 0 - Sample construction and initialisation}

Every processor $\pi$, constructs the difference cover $D$ of $\mathbb{Z}_v$ as discussed in Section \ref{sec:DiffCov}. Then, each processor $\pi$, for each $k \in \srange{0}{v}$, defines the subset ${B_k}_{\pi} = \{i \in I_{\pi} \mid i \bmod v=k\}$. This partitions each set of indices $B_k$ into $p$ subsets of size about $\frac{n}{pv}$. The subset $C_{\pi}$ of the difference cover sample $C$ is then constructed by every processor $\pi$, such that $C_{\pi} = \cup_{k \in D} {B_k}_{\pi}$. We denote by ${S_k}_{\pi}$, $k \in \srange{0}{v}$ and $\pi \in \srange{0}{p}$, the set of suffixes $s_i$, $i \in {B_k}_{\pi}$.

Finally, every processor $\pi$ also declares the array $rank_{\pi}$, of size $\frac{n}{p} + v$ for $\pi \in \frange{0}{p-2}$, and size $n - \frac{n}{p} (p-1) + v$ for $\pi = p-1$. Each element of $rank_{\pi}$ is initialised by -1. Note that the size of each $rank_{\pi}$, $\pi \in \frange{0}{p-2}$, follows from the fact that each such processor requires a copy of the first $v$ elements of $rank_{\pi+1}$ in order to be able to locally construct the tuples associated with all the non-sample characters in $x_{\pi}$.

\noindent \textit{Step 1 - Sort sample suffixes}

For every processor $\pi$, we define, for each $k \in D$, the substring of super-characters ${X_k}_{\pi} = \bigodot_{i \in {B_k}_{\pi}} \overline{x\srange{i}{i+v}}$, such that $|{X_k}_{\pi}| = \frac{n}{pv}$. Note that every substring $x\srange{i}{i+v}$ is locally available for all $i \in C_{\pi}$, due to the padding convention and the distribution of $x$ among the processors. Then, construct the string of super-characters $X$, as discussed in Section $\ref{sec:SeqAlg}$. This string is distributed among the $p$ processors, with each processor having $|D| \frac{n}{pv}$ super-characters. Note that it is not necessary to actually construct $X$, since the position of each ${X_k}_{\pi}$, and, therefore, the index of each super-character $\overline{x\srange{i}{i+v}}$, $i \in C$, in $X$ can be calculated by every processor $\pi$. However, this is done for simplicity. Algorithm 2 is then called on string $X$ with parameters $m = |D|\frac{n}{v}$ and $\kappa = v$. After sorting, a rank is assigned to each super-character in its sorted order, with any identical super-characters given the same rank, and the string $X'$ is constructed, as discussed in Section \ref{sec:SeqAlg}. Note that $X'$ is already equally distributed among the processors.

The algorithm is then called recursively on the string $X'$ with parameters $n = |X'|$ and $v' = \min (v^{\sfrac{5}{4}}, |X'|)$, where $v'$ is the value of $v$ in the subsequent recursion level. If $|X'| \leq \frac{n}{p}$, then $X'$ is sent to processor $0$, which calls the sequential suffix array algorithm on $X'$ with parameters $n = |X'|$ and $v = 3$. A detailed discussion on the bound of $v' = \min (v^{\sfrac{5}{4}}, |X'|)$ and its impact on the synchronisation costs of the algorithm is given later in this section.

When the recursive call returns with $SA_{X'}$, the rank of each $s_i$ in $SA_{X'}$, $i \in {C_k}_{\pi}$, $\pi \in \srange{0}{p}$, is recorded in $rank_{\pi}$. Also, a copy of the first $v$ elements of $rank_{\pi}$, for $\pi \in \srange{1}{p}$, is kept in $rank_{\pi - 1}$. The order of each suffix $s_i$ within each set $S_k$, $k \in D$, is stored by each processor $\pi$, for $i \in I_{\pi}$.

\noindent \textit{Step 2 - Find the order of the non-sample suffixes within each set $S_k$, $k \in \mathbb{Z}_v \setminus D$}

For each $k \in \mathbb{Z}_v \setminus D$, consider any $l_k \in \srange{1}{v}$ such that $(k + l_k) \bmod v \in D$. We define the tuple $t_i = (x[i], x[i+1], \ldots, x[i+l_k -1], rank[i+l_k])$, for each character $x[i]$, $i \in I_{\pi} \setminus C_{\pi}$, $\pi \in \srange{0}{p}$ and $k = i \mod v$. Note that every character in the tuple can be constructed locally on processor $\pi$.

Then, every processor $\pi \in \srange{0}{p}$ constructs the subsequence of tuples $(t_i)_{i \in {B_k}_{\pi}}$, for each subset ${B_k}_{\pi}$, $k \in \mathbb{Z}_v \setminus D$. Therefore, each sequence $(t_i)_{i \in {B_k}}$ is the concatenation of the subsequences $(t_i)_{i \in {B_k}_{\pi}}$ in ascending order of $\pi$. Recall from Section \ref{sec:SeqAlg}, that the number of sequences $(t_i)_{i \in {B_k}}$ to be sorted is $v - |D|$, and that each sequence contains $\frac{n}{v}$ tuples, of length at most $v$. Therefore, each processor holds about $\frac{n}{vp}$ tuples of each sequence.

Each sequence is then sorted using Algorithm 2 with parameters $m = \frac{n}{v}$ and $\kappa$ being the length of the tuples in the sequence, which is at most $v$. After each sequence is sorted, the order of each non-sample suffix $s_i$ within each set $S_k$, $k \in \mathbb{Z}_v \setminus D$, is stored by each processor $\pi$, $i \in I_{\pi}$.

\noindent \textit{Step 3 - Sort all suffixes by first $v$ characters}

Let each suffix $s_i$, $i \in \srange{0}{n}$, of $x$ be represented by the substrings $x\srange{i}{i+v}$. These substrings are sorted using Algorithm 2 with parameters $m = n$ and $\kappa = v$. The index of each substring in $x$ is used to determine the order of identical substrings. After sorting, the suffixes of $x$ will have been partitioned into the sets $S^{\alpha}$, $\alpha \in (\Sigma \cup \{-1\})^v$, as discussed in Section \ref{sec:SeqAlg}.

\noindent \textit{Step 4 - Merge and complete the suffix ordering}

Recall from Section \ref{sec:SeqAlg} that, each set $S^{\alpha}$, $\alpha \in (\Sigma \cup \{-1\})^v$, is partitioned into at most $v$ subsets $S^{\alpha}_{k}$, $k \in \srange{0}{v}$, and that the order of the suffixes within each such subset has been found in the previous steps. Ordering a set $S^{\alpha}$ is achieved through a $v$-way merging procedure based on Lemma \ref{lem:DiffCov}. For every two subsets $S^{\alpha}_{k'}$ and $S^{\alpha}_{k''}$, $k' , k'' \in \srange{0}{v}$, we choose any $l \in \srange{0}{v}$ such that $(k' + l) \bmod v$ and $(k'' + l) \bmod v$ are both in $D$. Then, comparing two suffixes $s_i \in S_{k'}$ and $s_j \in S_{k''}$ only requires the comparison of $rank[i + l]$ and $rank[j+l]$.

Therefore, in order to sort every element of $S^{\alpha}$ we require, for each element of $S^{\alpha}$, the order of the element within the subset $S^{\alpha}_{k}$ it belongs to and at most $|D|$ values from the array $rank$. Hence, at most $(|D| + 1) \frac{n}{p}$ values need to be received by each processor. Note that the order of each suffix $s_i$, $i \in \srange{0}{n}$, within the set $S_k$, $i \bmod v = k$, is stored on processor $\pi$, $i \in I_{\pi}$, as is $rank[i + l]$, for any $l \in \srange{0}{v}$.

After the sorting procedure in the previous step, the suffixes of a set $S^{\alpha}$, $\alpha \in \Sigma^v$, are contiguous and can be either contained within a single processor, or span two or more processors. If $S^{\alpha}$ is contained within one processor, then this processor locally merges each of the subsets of $S^{\alpha}$. If the set spans two processors $\pi', \pi'' \in \srange{0}{p}$, then, for each of the suffixes $s_i \in S^{\alpha}$, $i \in \srange{0}{n}$, on processor $\pi''$, the values required to merge $s_i$ into the ordered $S^{\alpha}$ are sent to $\pi'$. Processor $\pi'$ then locally merges each of the subsets of $S^{\alpha}$. Otherwise, if the set $S^{\alpha}$ spans more than two processors, the following procedure is performed.

Let $p'$ be the number of processors that the set $S^{\alpha}$ spans. Then, $S^{\alpha}$ is equally divided among the $p'$ processors, such that each is assigned $\frac{|S^{\alpha}|}{p'}$ elements. Again, note that the actual suffixes $s_i \in S^{\alpha}$, $i \in \srange{0}{n}$, are not communicated, but only the values required by the merging process are, i.e.\  at most $|D| + 1$ values for each suffix in $S^{\alpha}$.

Each of the $p'$ processors locally sorts its assigned elements of $S^{\alpha}$, using the $v$-way merging procedure, and chooses $p' + 1$ equally spaced primary samples from the sorted elements, including the minimum and maximum elements. Every primary sample is sent to one of the $p'$ processors that is chosen as the designated processor. Therefore, this designated processor receives $(p' + 1) p'$ primary samples, which it sorts locally using the $v$-way merging procedure. It then chooses $p' + 1$ equally spaced secondary samples from the merged primary samples, including the minimum and maximum primary samples, that partition $S^{\alpha}$ into $p'$ blocks. These secondary samples are broadcast to the $p'$ processors such that each processor can partition its assigned elements into $p'$ sub-blocks. Every processor then collects all the sub-blocks that make up a unique block and locally merges the received elements.

Note that a processor can only have elements from at most two sets that span across three or more processors. Therefore, this procedure can be done in parallel for each set $S^{\alpha}$. After all the sets $S^{\alpha}$ have been sorted, all the suffixes of $x$ have been ordered and the suffix array is returned. \Square

\subsection{Algorithmic Analysis}

The presented suffix array construction algorithms are recursive, and the number of levels of recursion required for the algorithms to terminate depends on the factor by which the size of the input string is reduced in successive recursive calls. While the number of levels of recursion does not influence the running time of the sequential algorithm, in BSP this determines the synchronisation costs of the algorithm, and, therefore, we want to reduce it to a minimum. Before detailing the costs of each step of the algorithm we explain how changing the sample size at each subsequent level of recursion results in $O(\log \log p)$ levels of recursion.

We refer to each level of recursion of the algorithm as round $i$, $i \geq 0$. Then, we denote by $n_i$, $v_i$ and $D_i$ the size of the input string, the parameter $v$ and the difference cover $D$ of $\mathbb{Z}_{v_i}$, respectively, in round $i$.

Recall from Section \ref{sec:DiffCov} that, the maximum size of a difference cover $D$ of $\mathbb{Z}_v$, for any positive integer $v$, that can be found in time $O(\sqrt{v})$ is $\sqrt{1.5 v} + 6$, i.e.\  $|D| = O(v^{\sfrac{1}{2}})$. Therefore, for the sake of simplicity, in our cost analysis we assume that $|D_i| = {v_i}^{\sfrac{1}{2}}$.

The analysis given in Table \ref{tab:AlgAnal} shows how changing the sampling rate affects the parameters $v$ and $n$ in subsequent recursive calls. Recall from Section \ref{sec:SeqAlg} that, the cost of each level of recursion in the sequential algorithm is $O(v_i n_i)$. Therefore, the table also shows that the order of work done decreases in subsequent recursive calls.

\begin{table}[t]
\centering
\caption{Algorithm analysis}
\begin{tabular}{|c|c|c|c|c|}
\hline
Round $i$ & $v_i$ & $|D_i|$ & $n_i$ & Work\\
\hline
$0$ & $v$ & $O\left ( v^{\frac{1}{2}} \right )$ & $n$ & $O\left ( v \cdot n \right )$\\
\hline
$1$ & $v^{(\frac{5}{4})}$ & $O\left ( (v^{(\frac{5}{4})})^{\frac{1}{2}} \right )$ & $\frac{v^{\frac{1}{2}}}{v} \cdot n = v^{-\frac{1}{2}} \cdot n$ & $O\left ( v^{(\frac{5}{4})} \cdot v^{(-\frac{1}{2})} \cdot n \right )$\\
\hline
$2$ & $v^{(\frac{5}{4})^2}$ & $O\left ( (v^{(\frac{5}{4})^2})^{\frac{1}{2}} \right )$ & $\frac{(v^{(\frac{5}{4})})^{\frac{1}{2}}}{v^{(\frac{5}{4})}} \cdot v^{-\frac{1}{2}} \cdot n = v^{(-\frac{9}{8})} \cdot n$ & $O\left ( v^{(\frac{5}{4})^2} \cdot v^{(-\frac{9}{8})} \cdot n \right )$\\
\hline
$i$ & $v^{(\frac{5}{4})^i}$ & $O\left ( v^{(\frac{5}{4})^i(\frac{1}{2})} \right )$ & $v^{-2(\frac{5}{4})^i + 2} \cdot n$ & $O\left ( v^{-(\frac{5}{4})^i + 2} \cdot n \right )$\\
\hline
$\log_{\frac{5}{4}} \left ( \log_v p^{\frac{1}{2}} + 1 \right )$ & $v \cdot p^{\frac{1}{2}}$ & $O\left ( v^{\frac{1}{2}} \cdot p^{\frac{1}{4}} \right )$ & $v^{2} \cdot \frac{n}{p}$ & $O\left ( v^{3} \cdot \frac{n}{p^{\frac{1}{2}}} \right )$\\
\hline
\end{tabular}
\label{tab:AlgAnal}
\end{table}

The results in Table \ref{tab:AlgAnal} clearly show that, if the algorithm is initially called on a string of size $n$, with parameter $v = 3$, on a $BSP(p,g,l)$ machine, then the size of the input converges towards $\frac{n}{p}$ super-exponentially. In fact,  after $\log_{\sfrac{5}{4}} ( \log_{3} p^{\sfrac{1}{2}} + 1 ) = O(\log \log p)$ levels of recursion, the size of the input string is $O(\frac{n}{p})$, and in the subsequent level of recursion the suffix array is computed sequentially on processor $0$. Note that the value $\frac{5}{4}$ as a power of $v$ is not the only one possible. In fact, any value $1 < a < \frac{3}{2}$ can be used, but $a = \frac{5}{4}$ is used for simplicity. Finally, note that $v_i > n_i$ only after $O(\log \log p)$ levels of recursion, at which point the algorithm is called sequentially on a single processor.

Having determined the number of recursive calls required by the algorithm, the cost of each step of the algorithm is analysed. For each step, the costs of the first round of the algorithm are specified below, along with the costs of round $\log_{\sfrac{5}{4}} ( \log_3 p^{\sfrac{1}{2}} + 1 )$, which we call the \emph{critical round}, since this is the round immediately before the algorithm is called sequentially on a string of length less than $\frac{n}{p}$.

In the recursion base, the costs are dominated by those of Algorithm 2, i.e.\  $O(\frac{n_i}{p})$ local computation and communication cost. Therefore, in the first round the local computation and communication costs are $O(\frac{n}{p})$, and in the critical round these costs are $O(\frac{n}{p^2})$. A constant number of synchronisation steps is required.

In step 0, constructing the difference cover $D_i$ has running time $O(\sqrt{v_i})$, i.e.\  $O(1)$ in the first round and $O(p^{\sfrac{1}{4}})$ in the critical round. Constructing the subsets $C_{\pi}$, independently for each processor $\pi \in \srange{0}{p}$, has $O(|D_i| \frac{n_i}{pv_i})$ local computation cost, i.e.\  $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p^{\sfrac{9}{4}}})$ in the critical round. Finally, declaring and initialising $rank_{\pi}$ requires $O(\frac{n_i}{p} + v_i)$ work, i.e.\  $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p^2})$ in the critical round. A single synchronisation step is required, with no communication.

In step 1, the costs are dominated by the construction of the string of super-characters $X$ and the call to Algorithm 2, leading to $O(|D_i|\frac{n_i}{p})$ local computation and communication costs. Therefore, the costs of this step in the first round are $O(\frac{n}{p})$ local computation and communication, while in the critical round these costs are $O(\frac{n}{p^{\sfrac{7}{4}}})$. A constant number of synchronisation steps is required in each round.

In step 2, the costs are again dominated by the call to Algorithm 2 for each sequence of tuples. The size of each sequence is $\frac{n_i}{v_i}$, and the size of each tuple is at most $v_i$. Therefore, the local computation and communication costs to sort each sequence are $O(\frac{n_i}{p})$, i.e.\  $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p})$ in the critical round. Each sequence is sorted independently using Algorithm 2, and, since the number of sequences to be sorted, $v_i - |D_i|$, is always less than $p$, then each sequence can be sorted in parallel in each round by having a different designated processor for each call to Algorithm 2. Therefore, the number of synchronisation steps required is always constant. Recall that Algorithm 2 requires slackness, $m \geq p^{3}$. Since, in the critical round, Algorithm 2 is called on a sequence of length $9 \frac{n}{p}$, we require that $n \geq p^{\sfrac{9}{2}}$. Note that this slackness can be reduced by sorting sequences locally if each sequence fits on a separate processor, however, such detail is beyond the scope of this paper and will be given in a journal version of this paper.

The cost of step 3 is simply the cost of Algorithm 2 on a string of size $n_i$ with $\kappa = v_i$, i.e.\  $O(v_i \frac{n_i}{p})$ local computation and communication costs and $O(1)$ synchronisation steps. Therefore, in the first round the local computation and communication costs are $O(\frac{n}{p})$ and these costs in the critical round are $O(\frac{n}{p^{\sfrac{3}{2}}})$.

In step 4, obtaining, for each suffix of $x$, the information required for the sorting each set $S^{\alpha}$ using a $v$-way merging procedure has $O(|D_i|\frac{n_i}{p})$ local computation and communication costs, i.e.\  $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p^{\sfrac{3}{2}}})$ in the critical round. Then, sorting a set $S^{\alpha}$ that is contained on a single processor has $O(|S^{\alpha}| v_i)$ local computation costs, and no communication is required. Note that in this case $|S^{\alpha}| < \frac{n_i}{p}$, so the local computation costs are $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p^{\sfrac{3}{2}}})$ in the critical round. If $S^{\alpha}$ spans two processors, then we send all the elements of the set to one of the two processors. Therefore, since each processor has $\frac{n_i}{p}$ suffixes, $|S^{\alpha}| < 2 \frac{n_i}{p}$, so the costs of sorting this set are $O(v_i \frac{n_i}{p})$ local computation, $O(|D_i| \frac{n_i}{p})$ communication and $O(1)$ synchronisation steps; i.e.\  $O(\frac{n}{p})$ local computation and communication costs in the first round and $O(\frac{n}{p^{\sfrac{3}{2}}})$ in the critical round.

Finally, if a set $S^{\alpha}$ spans $p' > 2$ processors, then $|S^{\alpha}| > (p' - 1) \frac{n_i}{p}$. In this case a procedure similar to the parallel radix sorting algorithm on $p'$ processors is performed. In fact, the only difference between the two is that $v$-way merging is used, instead of radix sorting, to locally sort the suffixes on each of the $p'$ processors. Since the $v$-way merging procedure on $n$ elements has the same asymptotic costs as the radix sorting procedure on an array of $n$ strings each of size $v$, over an alphabet $\Sigma = \mathbb{Z}$, then the local computation cost for this procedure is $O(v_i \frac{n_i}{p})$ and the communication cost is $O(|D_i| \frac{n_i}{p})$. Therefore, both these costs are $O(\frac{n}{p})$ in the first round and $O(\frac{n}{p^{\sfrac{3}{2}}})$ in the critical round. Since each such set can be merged independently in parallel, then a constant number synchronisation steps is required.

Note that, in the $i^{th}$ level of recursion, each step has local computation cost $O(v_i \frac{n_i}{p})$, communication cost $O(v_i \frac{n_i}{p})$ and $O(1)$ synchronisation costs. Also note that, as shown in table \ref{tab:AlgAnal}, $O(v_i n_i)$ decreases super-exponentially in each successive  level of recursion, and, therefore, the order of work done in each round of the BSP algorithm also decreases super-exponentially. Since the presented parallel suffix array construction algorithm is initially called on a string of size $n$ with parameter $v = 3$, the algorithm has $O(\frac{n}{p})$ local computation and communication costs and requires $O(\log \log p)$ synchronisation steps.

\section{BSP model}
\label{sec:BSP}
The \emph{bulk-synchronous parallel} (BSP) computation model \cite{Valiant,McColl} was introduced by Valiant in 1990, and has been widely studied ever since. The model was introduced with the aim of bridging the gap between the hardware development of parallel systems and the design of algorithms on such systems, by separating the system processors from the communication network. Crucially, it treats the underlying communication medium as a fully abstract communication network providing point-to-point communication in a strictly synchronous fashion. This allows the model to be architecture independent, promoting the design of scalable and portable parallel algorithms, while also allowing for simplified algorithm cost analysis based on a limited number of parameters.

A BSP machine consists of $p$ processors, each with its local primary and secondary memory, connected together through a communication network that allows for point-to-point communication and is equipped with an efficient barrier synchronisation mechanism. It is assumed that the processors are homogeneous and can perform an elementary operation per unit time. The communication network is able to send and receive a word of data to and from every processor in $g$ time units, i.e. $g$ is the inverse bandwidth of the network. Finally, the machine allows the processors to be synchronised every $l$ time units. The machine is, therefore, fully specified using only parameters $p$, $g$, $l$, and is denoted by $\emph{BSP}(p,g,l)$.

An algorithm in the BSP model consists of a series of \emph{supersteps}, or \emph{synchronisation steps}. In a single superstep, each processor performs a number of, possibly overlapping, computation and communication steps in an asynchronous fashion. However, a processor is only allowed to perform operations on data that was available to it at the start of the superstep. Therefore, in a single superstep, a processor can send and receive any amount of data, however, any received data can only be operated on in the following superstep. At the end of a superstep, barrier synchronisation is used to ensure that each processor is finished with all of its computation and data transfer.

The cost of a BSP superstep on a $\emph{BSP}(p,g,l)$ machine can be computed as follows. Let ${work}_i$ be the number of elementary operations performed by processor $P_i$, $i \in \srange{0}{p}$, in this superstep. Then, the \emph{local computation cost} $w$ of this superstep is given by $w = \max_{i \in \srange{0}{p}}({work}_i)$. Let $h^{out}_i$ and $h^{in}_i$ be the maximum number of data units sent and received, respectively, by processor $P_i$, $i \in \srange{0}{p}$, in this superstep. Then, the \emph{communication cost} $h$ of this superstep is defined as $h = \max_{i \in \srange{0}{p}}(h^{out}_i) + \max_{i \in \srange{0}{p}}(h^{in}_i)$. Therefore, the total cost of the superstep is $w + h \cdot g + l$. The total cost of a BSP algorithm with $S$ supersteps, with local computation costs $w_s$ and communication costs $h_s$, $s \in \srange{0}{S}$, is $W + H \cdot g + S \cdot l$, where $W = \sum_{s=0}^{S-1} w_s$ is the total local computation cost and $H = \sum_{s=0}^{S-1} h_s$ is the total communication cost.

The main principle of efficient BSP algorithm design is the minimisation of the algorithm's parameters $W$, $H$, and $S$. These values typically depend on the number of processors $p$ and the problem size.

\section{Conclusion}
\label{sec:Conc}

In this paper we have presented a deterministic BSP algorithm for the construction of the suffix array of a given string. The algorithm runs in optimal $O(\frac{n}{p})$ local computation and communication, and requires a near optimal $O(\log \log p)$ synchronisation steps.

The method of regular sampling in coarse-grained algorithms has been used to solve the sorting \cite{ShiSchaeffer,ChanDehne}, and 2D and 3D convex hulls \cite{Tiskin_convexhull} problems. Random sampling has been used to solve the maximal matching problem and provide an approximation to the minimum cut problem \cite{LattanziMoseleySuriVassilvitskii} in a parallel context. An extension of the regular sampling technique, which we call \textit{accelerated sampling}, was introduced by Tiskin \cite{Tiskin} to improve the synchronisation upper bound of the BSP algorithm for the selection problem. The same technique was used here to improve the synchronisation upper bounds of the suffix array construction problem. Accelerated sampling is a theoretically interesting technique, allowing, in specific cases, for an exponential factor improvement in the number of synchronisation steps over existing algorithms.

It is still an open question as to whether the synchronisation cost of the suffix array construction problem and the selection problem can be reduced to the optimal $O(1)$ while still having optimal local computation and communication costs. Another open question is whether further applications of the sampling technique, whether regular, random or accelerated, are possible.

\section{Difference Covers}
\label{sec:DiffCov}
The suffix array construction algorithms to be presented in this paper make use of the concept of difference covers \cite{ColbournLing,KilianKipnis,MereghettiPalano}. Given a positive integer $v$, let $\mathbb{Z}_v$ denote the set of integers $\srange{0}{v}$. A set $D \subseteq \mathbb{Z}_v$ can be defined such that for any $z \in \mathbb{Z}_v$, there exist $a, b \in D$ such that $z \equiv a - b$ $(\bmod$ $v)$. Such a set $D$ is known as a \textit{difference cover} of $\mathbb{Z}_v$, or \textit{difference cover modulo $v$} of $\mathbb{Z}_v$.

Colbourn and Ling \cite{ColbournLing} present a method for obtaining, for any $v$, a difference cover $D$ of $\mathbb{Z}_v$ in time $O(\sqrt{v})$, where $|D| = 6r + 4$, $r = \frac{-36 + \sqrt{48 + 96v}}{48}$. Hence, $|D| \leq \sqrt{1.5v} + 6$. Note that, in general, for any $v$ and any difference cover $D$ of $\mathbb{Z}_v$, $|D| \geq \frac{1 + \sqrt{4v - 3}}{2}$, since we must have $|D| (|D| - 1) + 1 \geq v$. Therefore, the size of the difference cover obtained by using the algorithm in \cite{ColbournLing} is optimal up to a multiplicative constant.

The algorithms to be presented in this paper require that $|D| < v$, so we assume $v \geq 3$. The optimal difference covers of $\mathbb{Z}_3$, $\mathbb{Z}_4$ are of size 2, 3 respectively, and for $v \geq 5$ the method of \cite{ColbournLing} gives difference covers of sizes given in Table \ref{tab:DiffCov}.

For technical reasons, discussed in Section \ref{sec:SeqAlg}, we also require that $0 \not \in D$. This does not represent a restriction since, for any $v$ and difference cover $D$ of $\mathbb{Z}_v$, a fixed $z \in \mathbb{Z}_v$ can always be chosen such that the set $D' = \{(d - z) \bmod v \mid d \in D\}$ is also a difference cover of $\mathbb{Z}_v$ (see e.g.\  \cite{MereghettiPalano}).

The following lemma is also required to ensure the correctness of the algorithms to be presented.

\begin{table}[t]
\centering
\caption{Size of the difference cover obtained using the algorithm in \cite{ColbournLing} for various values of $v$}
\begin{tabular}{|c|c|c|c|c|c|c|c|}
\hline
$v$&$5 \ldots 13$&$14 \ldots 73$&$74 \ldots 181$&$182 \ldots 337$&$338 \ldots 541$&$1024$&$2048$\\
\hline
$|D_v|$&$4$&$10$&$16$&$22$&$28$&$40$&$58$\\
\hline
\end{tabular}
\label{tab:DiffCov}
\end{table}

\begin{lemma}\textup{\textbf{\cite{KarkkainenSandersBurkhardt}}}
If $D$ is a difference cover of $\mathbb{Z}_v$, and i and j are integers, then there exists $l \in \srange{0}{v}$ such that $(i + l) \bmod v$ and $(j + l) \bmod v$ are both in $D$.
\label{lem:DiffCov}
\end{lemma}

For any difference cover $D$ of $\mathbb{Z}_v$ and integer $n \geq v$, a \textit{difference cover sample} is defined as $C = \{i \in \srange{0}{n} \mid i \bmod v \in D\}$. The index set $C$ is a $v$-periodic sample of $\srange{0}{n}$, as defined in \cite{KarkkainenSandersBurkhardt}. The fact that difference cover samples are periodic allows them to be used for efficient suffix sorting on a given string.

\section{Introduction}
\label{sec:Intro}
Suffix arrays are a fundamental data structure in the string processing field. They have been researched extensively since their introduction by Manber and Myers \cite{ManberMyers,PuglisiSmythTurpin}.

\begin{definition}
Given a string $x = x[0] \ldots x[n-1]$ of length $n \geq 1$, defined over an alphabet $\Sigma$, the suffix array problem aims to construct the suffix array $SA_x = SA_x[0] \ldots SA_x[n-1]$ of $x$ which holds the ordering of all the suffixes $s_i = x[i] \ldots x[n-1]$ of $x$ in ascending order; i.e.  $SA_x[j] = i$ iff $s_i$ is the $j^{th}$ suffix of $x$ in ascending lexicographical order.
\end{definition}

\subsection{Notation, Assumptions and Restrictions}

We assume zero-based indexing throughout the paper, and that the set of natural numbers includes zero. For any $i, j \in \mathbb{N}$, we use the notation $\frange{i}{j}$ to denote the set $\{a \in \mathbb{N} \mid i \leq a \leq j\}$, and $\srange{i}{j}$ to denote $\{a \in \mathbb{N} \mid i \leq a < j\}$.

The input of the algorithms to be presented in this paper is restricted to strings defined over the alphabet $\Sigma = \srange{0}{n}$, where $n$ is the size of the input string. This allows us to use counting sort \cite{CLRS} throughout when sorting characters, in order to keep the running time linear in the size of the input. Counting sort is also used in conjunction with the radix sorting technique \cite{CLRS}.

The set notation described above is extended to substrings by denoting the substrings of string $x$ by $x\srange{i}{j}$, where $x\srange{i}{j} = x[i] \ldots x[j-1]$. Also, the end of any string is assumed to be marked by an end sentinel, typically denoted \$, that precedes all the characters in the alphabet order. Therefore, to mark the end of the string and to ensure that any substring $x\srange{i}{j}$ is well defined, for $i \in \srange{0}{n}$ and $j > i$, we let $x[k] = -1$, for $k \geq n$.

It should be noted that the algorithms to be presented in Sections \ref{sec:SeqAlg}, \ref{sec:ParAlg} can also be applied to any string $X$, of size $n$, over an indexed alphabet $\Sigma'$ \cite{PuglisiSmythTurpin,Smyth}, which is defined as follows:

\begin{itemize}
	\item $\Sigma'$ is a totally ordered set.
	\item an array $A$ can be defined, such that, $\forall \sigma \in \Sigma'$, $A[\sigma]$ can be accessed in constant time.
	\item $|\Sigma'| \leq n$.
\end{itemize}

Commonly used indexed alphabets include the ASCII alphabet and the DNA bases. It should also be noted that any string $X$, of size $n$, over a totally ordered alphabet can be encoded as a string over integers. This is achieved by sorting the characters of the string, removing any duplicates, and assigning a rank to each character. A new string $X'$ of size $n$ is then constructed, such that it is identical to $X$ except that each character of $X$ is replaced by its rank in the sorted list of characters. However, sorting the characters of $X$ could require $O(n \log n)$ time, depending on the nature of the alphabet over which $X$ is defined.

The example in Table \ref{tbl:example} shows the suffix array for a string $X$, of size 12, over an indexed alphabet of a subset of the ASCII characters, written as string $X'$ over $\Sigma = \srange{0}{12}$.

\begin{table}[h]
\centering
\caption{Suffix array of a string $X$ over an indexed alphabet, written as $X'$ over $\Sigma = \srange{0}{12}$}
\begin{tabular}{rp{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}p{5mm}}
&$0$&$1$&$2$&$3$&$4$&$5$&$6$&$7$&$8$&$9$&$10$&$11$&$12$\\
$X=$&$a$&$c$&$b$&$a$&$a$&$c$&$e$&$d$&$b$&$b$&$e$&$a$&$\$$\\
$X'=$&$0$&$2$&$1$&$0$&$0$&$2$&$4$&$3$&$1$&$1$&$4$&$0$&$-1$\\
$SA_X=$&$11$&$3$&$0$&$4$&$2$&$8$&$9$&$1$&$5$&$7$&$10$&$6$\\
\end{tabular}
\label{tbl:example}
\end{table}

Let $x_1 \odot x_2$ denote the concatenation of strings $x_1$ and $x_2$. Then, for any set of integers $A$, $\bigodot_{i \in A} x_i$ is the concatenation of the strings indexed by the elements of $A$, in ascending index order. Throughout the paper we use $|b|$ to denote the size of an array or string $b$. To omit $\lceil \cdot \rceil$ operations, we assume that any real numbers are rounded up to the nearest integer.

\subsection{Problem Overview}

The suffix array problem is, by definition, directly related to the sorting problem. In fact, if all the characters of the input string are distinct, then the suffix array is obtained by sorting the strings' characters and returning the indices of the characters in their sorted order. In general, if the characters of the string are not distinct, the naive solution is to radix sort all the suffixes, which takes $O(n^2)$ time if counting sort is used to sort the characters at each level of the radix sort. However, numerous algorithms exist that improve on this running time. The first such algorithm was presented by Manber and Myers \cite{ManberMyers} and required $O(n \log n)$ time. The running time was reduced to $O(n)$ through three separate algorithms presented by K\"{a}rkk\"{a}inen and Sanders \cite{KarkkainenSanders}, Kim et al. \cite{KimSimParkPark}, and Ko and Aluru \cite{KoAluru}. A number of other algorithms exist with a higher theoretical worst case running time but faster running time in practice, as discussed in \cite{PuglisiSmythTurpin}. However, the study of these is beyond the scope of this work.

The idea behind the algorithms having linear theoretical worst case running time is to use recursion as follows:

\begin{enumerate}
	\item Divide the indices of the input string $x$ into two nonempty disjoint sets. Form strings $x'$ and $y'$ from the characters indexed by the elements of each set. Recursively construct $SA_{x'}$.
	\item Use $SA_{x'}$ to construct $SA_{y'}$.
	\item Merge $SA_{x'}$ and $SA_{y'}$ to obtain $SA_x$.
\end{enumerate}

The problem of constructing suffix arrays, while similar to the sorting problem, differs as follows. Given two sorted lists of integers, we are guaranteed that after merging them the order of the integers in the original lists is preserved. However, given two strings and their suffix arrays, the order of the suffixes is not necessarily preserved in the suffix array of the concatenated string. For example, the suffix arrays of strings $aaa$ and $aab$ are $[2,1,0]$ and $[0,1,2]$ respectively, but the suffix array of string $aaaaab$ is $[0,1,2,3,4,5]$.

The aim of this paper is to investigate the suffix array construction problem in the Bulk Synchronous Parallel (BSP) model, on a $p$ processor distributed memory system. As in the sequential setting, the naive general solution to the problem is to radix sort all the suffixes of the string. Shi and Shaeffer \cite{ShiSchaeffer} provide a comparison based parallel sorting algorithm, using a technique known as regular sampling, which is then adapted by Chan and Dehne \cite{ChanDehne} for integer sorting. However, using such a technique to sort the suffixes of a given string of size $n$ leads to a parallel algorithm with $O(\frac{n^2}{p})$ local computation cost, $O(n)$ communication cost and requiring $O(1)$ synchronisation steps. Clearly, it is more efficient to simply use a linear time sequential algorithm.

K\"{a}rkk\"{a}inen et al. \cite{KarkkainenSandersBurkhardt} give a brief overview of a BSP suffix array construction algorithm having optimal $O(\frac{n}{p})$ local computation and communication costs and requiring $O(\log^2 p)$ synchronisation steps. They also present similar algorithms in the PRAM model. In this paper we further reduce the number of synchronisation steps required to a near optimal $O(\log \log p)$, while keeping the same optimal local computation and communication costs. The algorithm is based on a technique that we call \emph{accelerated sampling}. This technique was introduced (without a name) by Tiskin \cite{Tiskin} for the parallel selection problem. An accelerated sampling algorithm is a recursive algorithm that samples the data at each level of recursion, changing the sampling frequency at a carefully chosen rate as the algorithm progresses.

\subsection{Paper Structure}

The rest of the paper is structured as follows. The next section provides an overview of the concept of difference covers. The sequential suffix array construction algorithm is given in Section \ref{sec:SeqAlg}. An overview of the BSP model is provided in Section \ref{sec:BSP}, and a description of the parallel suffix array construction algorithm in this model is presented in Section \ref{sec:ParAlg}. The last section offers some concluding views and discusses possible future work.

\section{Sequential Algorithm}
\label{sec:SeqAlg}
K\"{a}rkk\"{a}inen et al. \cite{KarkkainenSandersBurkhardt} present a sequential recursive algorithm that constructs the suffix array of a given string $x$ of size $n$, using a difference cover $D$ of $\mathbb{Z}_v$, for any arbitrary choice of $v \in \frange{3}{n}$, in time $O(vn)$. Clearly, by setting $v = 3$ the running time of the algorithm is $O(n)$, with a small multiplicative constant. As $v$ approaches $n$ the running time approaches $O(n^2)$, and when $v = n$ the algorithm is simply a complex version of the naive suffix array construction algorithm. However, by initially letting $v = 3$ and increasing the value of $v$ at a carefully chosen rate in every subsequent level of recursion, we can reduce the total number of recursion levels required for the algorithm to terminate, while still keeping the total running time linear in the size of the input string. This technique can be used to decrease the number of synchronisation steps required by the parallel suffix array construction algorithm in the BSP model. This is discussed further in Section \ref{sec:ParAlg}. The detailed sequential algorithm proceeds as follows:

\noindent \textit{Recursion base}

We sort $x$ using counting sort, in time $O(n)$. If all the characters of $x$ are distinct we return, for each character, in the sorted order, the index of the character in $x$, i.e.\  $SA_x$. Otherwise, the following steps are performed:\vspace{4mm}

\noindent \textbf{Algorithm 1.} \textit{Sequential Suffix Array Construction}

\noindent \textbf{Parameters:} integer $n$; integer $v \in \frange{3}{n}$

\noindent \textbf{Input:} string $x = x[0] \ldots x[n-1]$ over alphabet $\Sigma = \srange{0}{n}$

\noindent \textbf{Output:} suffix array $SA_x = SA_x[0] \ldots SA_x[n-1]$

\noindent \textbf{Description:}

\noindent \textit{Step 0 - Sample construction and initialisation}

Construct the difference cover $D$ of $\mathbb{Z}_v$ as discussed in Section \ref{sec:DiffCov}. Then, for each $k \in \srange{0}{v}$, define the set $B_k = \{i \in \srange{0}{n} \mid i \bmod v = k\}$. This partitions the set of indices of $x$ into $v$ sets of size about $\frac{n}{v}$. The difference cover sample $C = \bigcup_{k \in D} B_k$ is then constructed. For $i \in C$, we call the characters $x[i]$ \emph{sample characters} and the suffixes $s_i$ \emph{sample suffixes}. We also denote by $S_k$, $k \in \srange{0}{v}$, the set of suffixes $s_i$, $i \in B_k$.

Furthermore, an array $rank$ of size $n+v$ is declared and initialised by $rank[0] = \ldots = rank[n+v-1] = -1$. This array will be used to store the rank of the sample characters of $x$ in the suffix array returned by the recursive call made later in step 1. Only $|C|$ elements of $rank$ will be used, and in fact a smaller array can be used to hold these values. However, we use a larger array to avoid complex indexing schemes relating elements in $rank$ to characters in $x$.

\noindent \textit{Step 1 - Sort sample suffixes}

Let $\overline{\Sigma}$ be an alphabet of super-characters, which are defined to be in 1-1 correspondence with the distinct substrings of $x$ of length $v$: super-character $\overline{x\srange{i}{i+v}}$ corresponds to the substring $x\srange{i}{i+v}$, for all $i \in C$. Therefore, $\overline{\Sigma} \subseteq (\Sigma \cup \{-1\})^v$. Recall from Section \ref{sec:Intro} that, due to the padding convention, any substring $x\srange{i}{j}$ is well-defined, for $i \in \srange{0}{n}$ and $j > i$, and therefore any super-character $\overline{x\srange{i}{j}}$ is also well-defined.

For each $k \in D$, we now define a string of super-characters $X_k$ over $\overline{\Sigma}$, where $X_k = \bigodot_{i \in B_k} \overline{x\srange{i}{i+v}}$ and $|X_k| = \frac{n}{v}$. Then, we construct the string of super-characters $X = \bigodot_{k \in D} X_k$, with $|X| = |D|\frac{n}{v}$. Note that for each $k$, the suffixes of $X_k$ correspond to the set of suffixes $S_k$. The last super-character of $X_k$ ends with one or more $-1$ elements, since $0$ is not allowed to be in the difference cover. Therefore, each suffix of $X$ corresponds to a different sample suffix of $x$, followed by one or more $-1$ characters followed by other characters that do not affect the lexicographic order of the suffixes of $X$. Note that, if $0$ was allowed in the difference cover and $n$ was a multiple of $v$, then the last super-character of $X_k$ would not end with $-1$.

Recall from Section \ref{sec:Intro} that since the input to the algorithm is a string over natural numbers, the string of super-characters $X$ can be encoded as string $X'$ over $\Sigma' = \srange{0}{|X|}$ using radix sorting, in time $O(v|X|)$, where $|X'| = |X| = |D|\frac{n}{v}$. The order of the suffixes of $X$ can then be found by constructing the suffix array of $X$ by recursively calling the algorithm on the string $X'$ over $\Sigma'$, with parameters $|X'|$ and $v'$, where $v'$ can be chosen arbitrarily from the range $\frange{3}{\min \left ( \frac{v^2}{|D|} - 1, |X'| \right )}$. Thus, $v'$ becomes the value of $v$ in the subsequent recursion level. The bound $v' < \frac{v^2}{|D|}$ ensures that the total work performed by the algorithm is still linear in $n$.

Recall from Section \ref{sec:DiffCov} that we require $|D| < v$. This ensures that $|X| < n$, so the algorithm is guaranteed to terminate, since each recursive call is always made on a shorter string. In fact, if the parameter $v$ remains constant over all the levels of the recursion (say $v = 3$), then in each level the size of the string is reduced by a factor of $\frac{|D|}{v}$ (a factor of $\frac{2}{3}$ for $v = 3$, $|D| = 2$). However, by carefully increasing the value $v$ in every round, within the bounds specified above, we can reduce the number of recursion levels of the algorithm by accelerating the rate of string size reduction in each successive level of recursion, as discussed in detail in Section \ref{sec:ParAlg}.

When the recursive call returns with $SA_{X'}$, this holds the ordering of all the suffixes of $X'$, i.e.\  the ordering of the sample suffixes of $x$ within the set of sample suffixes. Then, for $i \in C$, the rank of $s_i$ in $SA_{X'}$ is recorded in $rank[i]$. Note that the order of the sample suffixes within each set $S_k$, $k \in D$, can be found from $SA_{X'}$.

The total cost of this step is dominated by the radix sorting procedure required to encode string $X$ into $X'$ over  $\Sigma' = \srange{0}{|X|}$, which runs in time $O(|D|n)$.

Note that we can now compare any pair of suffixes by the result of Lemma \ref{lem:DiffCov}. However, this is not sufficient to sort the suffixes of $x$ in linear time, since a different value of $l$ would have to be found for each pair of suffixes and linear time sorting would not be possible. Instead, we perform the following steps.

\noindent \textit{Step 2 - Find the order of the non-sample suffixes within each set $S_k$, $k \in \mathbb{Z}_v \setminus D$}

For each $k \in \mathbb{Z}_v \setminus D$, consider any $l_k \in \srange{1}{v}$ such that $(k + l_k) \bmod v \in D$. For every character $x[i]$, $i \in \srange{0}{n} \setminus C$, define the tuple $t_i = (x[i], x[i+1], \ldots, x[i+l_k -1], rank[i+l_k])$, where $k = i \mod v$. Note that $rank[i +l_k]$ is defined for each $i$, since $rank[a]$, for all $a \in C$, has been found in the previous step and $rank[a] = -1$ for all $a \geq n$.

Then, for each set $B_k$, $k \in \mathbb{Z}_v \setminus D$, construct the sequence of tuples $(t_i)_{i \in B_k}$. Each of the $v - |D|$ constructed sequences has about $\frac{n}{v}$ tuples, with each tuple having less than $v$ elements. The order of the suffixes within $S_k$ is then obtained by independently sorting every sequence of tuples $(t_i)_{i \in B_k}$, using radix sorting.

The total computation cost of this step is dominated by the cost of radix sorting all the sequences, i.e.\  $O \left ( \left (v - |D| \right )n \right ) = O(vn)$.

\noindent \textit{Step 3 - Sort all suffixes by first $v$ characters}

Note that in the previous steps the order of every suffix within each set $S_k$, $k \in \srange{0}{v}$, has been found. Now, let $S^{\alpha}$ be the set of suffixes starting with $\alpha$, for $\alpha \in (\Sigma \cup \{-1\})^v$. Then, every set $S^{\alpha}$ is composed of ordered subsets $S^{\alpha}_{k}$, where $S^{\alpha}_{k} = S^{\alpha} \bigcap S_k$.

All the suffixes $s_i$, $i \in \srange{0}{n}$, are partitioned into the sets $S^\alpha$ by representing each suffix by the substring $x\srange{i}{i+v}$, and sorting these substrings using radix sorting in time $O(vn)$.

\noindent \textit{Step 4 - Merge and complete the suffix ordering}

For all $\alpha \in \Sigma^v$, the total order within set $S^\alpha$ can be obtained by merging the subsets $S^{\alpha}_{k}$, $k \in \mathbb{Z}_v$. This comparison-based $v$-way merging step uses the fact that all the suffixes in $x^\alpha$ start with the same substring $\alpha$, in conjunction with Lemma 1. Due to this lemma, a value $l \in \srange{0}{v}$ exists such that for any $i, j$ the comparison of suffixes $s_i$, $s_j$ only requires the comparison of $rank[i + l]$ and $rank[j + l]$. Having already partitioned the suffixes into sets $S^\alpha$ and found the order of the suffixes within each set $S_k$, $k \in [0,v)$, the suffix array can be fully constructed through this merging process in time $O(vn)$. \Square

All the steps of the algorithm can be completed in time $O(vn)$, and the recursive call is made on a string of size at most $\frac{4}{5}n$, which corresponds to $|D| = 4$, $v = 5$. This leads to an overall running time of $O(vn)$.

redpajama_set_name: RedPajamaArXiv


text:
Q: Expiring links and where to store them I currently have a website setup where unique links are generated every time a person loads a page. When a user follows a link that link should expire. That is, they shouldn't be able to hit back on their browser and click that link again.
While I can do this now, I'm not sure where I should be storing the unique link IDs.
There are going to be a lot of links generated since the website involves a lot of clicking through to get to other sections of the site, but the links themselves will expire after 30 minutes.
Should I store them on the database (MySQL) or cache them in memory with xcache?

A: If you do not need to ever reference the links again (ie an audit trail) storing them in memory should be fine, even storing them in session() should be acceptable. If you want an audit trail, I would store them in a more permanent matter, IE a database.


text:
Q: IEnumerable - exclude using an array Does anyone know if it's possible to create a new IEnumerable by using an array parameter to exclude values.
For instance, below is an example of how I imagine it would look.
   class Item
   {
       public int id { get; set; }
       public string name { get; set; }
   }

IEnumerable looks like this:
item1 {id = 1}
item2 {id = 2}
item3 {id = 3}

I want to create a new IEnumerable but exclude the id numbers in the array.
Made up code to suggest idea:
Int32[] arrayList = {1,2};
var newIEnumerable = _exisitingIEnumerable.Where(o => (o.id NOT IN arrayList));

A: Looking at your question again, when the element type of _exisitingIEnumerable is not the same as that of arrayList, you will need to use Where to filter out the elements of arrayList
_exisitingIEnumerable.Where(o => !arrayList.Contains(o.Id))

Original answer:
_exisitingIEnumerable.Except(arrayList)

will return the distinct elements from _exisitingIEnumerable that are not in arrayList
If you need duplicates, you can use
_exisitingIEnumerable.Where(o => !arrayList.Contains(o))

A: What's wrong with the approach you suggested in the question? You can use Where and check if the array contains the value. Below the example using List as a target collection:
var myList = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] myArray = { 1, 2, 3 };

var result = new List<int>(myList.Where(n => !myArray.Contains(n)));