Treebank Statistics: UD_Scottish_Gaelic-ARCOSG: Features: Foreign
This feature is universal.
It occurs with 1 different values: Yes
.
766 tokens (1%) have a non-empty value of Foreign
.
514 types (7%) occur at least once with a non-empty value of Foreign
.
498 lemmas (9%) occur at least once with a non-empty value of Foreign
.
The feature is used with 10 part-of-speech tags: NOUN (462; 1% instances), X (151; 0% instances), PROPN (43; 0% instances), ADJ (41; 0% instances), CCONJ (18; 0% instances), ADV (16; 0% instances), NUM (16; 0% instances), INTJ (12; 0% instances), DET (4; 0% instances), VERB (3; 0% instances).
NOUN
462 NOUN tokens (2% of all NOUN
tokens) have a non-empty value of Foreign
.
The most frequent other feature values with which NOUN
and Foreign
co-occurred: Case=EMPTY (462; 100%), Gender=EMPTY (462; 100%), Number=EMPTY (462; 100%), VerbForm=EMPTY (462; 100%).
NOUN
tokens may have the following values of Foreign
:
Yes
(462; 100% of non-emptyForeign
): tug-of-war, Shir, contract, council, vet, Radio, point, terrorists, tribunal, vanEMPTY
(18399): bhith, dol, ràdh, duine, fear, chur, fhios, taobh, ais, dhèanamh
Foreign
seems to be lexical feature of NOUN
. 100% lemmas (334) occur only with one value of Foreign
.
X
151 X tokens (39% of all X
tokens) have a non-empty value of Foreign
.
X
tokens may have the following values of Foreign
:
Yes
(151; 100% of non-emptyForeign
): the, a, I, and, in, on, poverty, well, Isles, WesternEMPTY
(241): [?], na, a, a:, ann, b:, cuag, si, ISA, Malpa:
Foreign
seems to be lexical feature of X
. 100% lemmas (123) occur only with one value of Foreign
.
PROPN
43 PROPN tokens (1% of all PROPN
tokens) have a non-empty value of Foreign
.
The most frequent other feature values with which PROPN
and Foreign
co-occurred: Case=EMPTY (43; 100%), Gender=EMPTY (43; 100%).
PROPN
tokens may have the following values of Foreign
:
Yes
(43; 100% of non-emptyForeign
): Sir, Dad, the, Airways, Apprentice, Aquaculture, Backpackers, Boys, British, BusEMPTY
(4173): [Name], [Placename], Alba, Iain, Yugoslavia, Dòmhnall, MacLeish, Malpas, Uibhist, h-Alba
Foreign
seems to be lexical feature of PROPN
. 100% lemmas (31) occur only with one value of Foreign
.
ADJ
41 ADJ tokens (1% of all ADJ
tokens) have a non-empty value of Foreign
.
The most frequent other feature values with which ADJ
and Foreign
co-occurred: Case=EMPTY (41; 100%), Gender=EMPTY (41; 100%), Number=EMPTY (41; 100%).
ADJ
tokens may have the following values of Foreign
:
Yes
(41; 100% of non-emptyForeign
): okay, Celtic, extra, flat, fresh, important, spotless, Agricultural, Giant, JapaneseEMPTY
(3376): eile, bith, sam, ùr, math, beag, mhòr, mòr, cinnteach, faisg
Foreign
seems to be lexical feature of ADJ
. 100% lemmas (33) occur only with one value of Foreign
.
CCONJ
18 CCONJ tokens (1% of all CCONJ
tokens) have a non-empty value of Foreign
.
CCONJ
tokens may have the following values of Foreign
:
Yes
(18; 100% of non-emptyForeign
): soEMPTY
(3388): agus, ‘s, ach, is, no, ’s, oir, neo, ‘s, na
ADV
16 ADV tokens (0% of all ADV
tokens) have a non-empty value of Foreign
.
ADV
tokens may have the following values of Foreign
:
Yes
(16; 100% of non-emptyForeign
): really, exactly, straight, absolutely, alright, forward, full, particular, right, stillEMPTY
(4590): an, a-mach, cho, a, dìreach, suas, cuideachd, ann, math, a-steach
Foreign
seems to be lexical feature of ADV
. 100% lemmas (12) occur only with one value of Foreign
.
NUM
16 NUM tokens (2% of all NUM
tokens) have a non-empty value of Foreign
.
NUM
tokens may have the following values of Foreign
:
Yes
(16; 100% of non-emptyForeign
): and, eighteen, eighty, fifty, five, forty-thousand, hundred, nineteen, ninety, oneEMPTY
(1032): aon, dà, deug, trì, fhichead, fichead, ceithir, chiad, cheud, seachd
Foreign
seems to be lexical feature of NUM
. 100% lemmas (16) occur only with one value of Foreign
.
INTJ
12 INTJ tokens (2% of all INTJ
tokens) have a non-empty value of Foreign
.
INTJ
tokens may have the following values of Foreign
:
Yes
(12; 100% of non-emptyForeign
): Well, okay, right, so, no, really, sorry, thanksEMPTY
(516): uill, ò, àidh, o, och, seadh, uh, ma-thà, eh, mhmm
DET
4 DET tokens (0% of all DET
tokens) have a non-empty value of Foreign
.
The most frequent other feature values with which DET
and Foreign
co-occurred: Case=EMPTY (4; 100%), Definite=EMPTY (4; 100%), Gender=EMPTY (4; 100%), Number=EMPTY (4; 100%), Person=EMPTY (4; 100%), Poss=EMPTY (4; 100%), PronType=EMPTY (4; 100%).
DET
tokens may have the following values of Foreign
:
Yes
(4; 100% of non-emptyForeign
): theEMPTY
(6535): an, na, a’, a, am, a’, nan, sin, seo, ‘n
VERB
3 VERB tokens (0% of all VERB
tokens) have a non-empty value of Foreign
.
The most frequent other feature values with which VERB
and Foreign
co-occurred: Tense=EMPTY (3; 100%).
VERB
tokens may have the following values of Foreign
:
Yes
(3; 100% of non-emptyForeign
): dhifferentiates, sublet, testEMPTY
(9015): tha, bha, robh, eil, bheil, chaidh, bhiodh, fhuair, thuirt, ars’
Relations with Agreement in Foreign
The 10 most frequent relations where parent and child node agree in Foreign
:
NOUN –[flat:foreign]–> NOUN (77; 96%),
X –[flat:foreign]–> X (71; 100%),
NUM –[flat:foreign]–> NUM (7; 100%),
ADJ –[flat:foreign]–> NOUN (6; 100%),
PROPN –[flat:foreign]–> PROPN (4; 100%),
ADV –[flat:foreign]–> X (2; 100%),
DET –[flat:foreign]–> PROPN (2; 100%),
NOUN –[flat:foreign]–> X (2; 100%),
ADJ –[flat:foreign]–> ADJ (1; 100%),
ADV –[flat:foreign]–> ADV (1; 100%).


The engagement photos are an important part of your story and we can capture every breathtaking moment. The best wedding albums include the whole story from the engagement to the wedding. Our photography services will guide you through the entire process. So you can plan the more important details about your wedding stress-free.
It's everyone's dream to have a beautiful wedding and we are fully prepared to capture every moment of it. This time in your life is special and we understand that you want the best photos and the best experience possible! We have helped many achieve the photos of their dreams with our professional wedding photography services.
Your family is #1 let us capture the moments that make your family special. Beautiful outdoor landscapes to the indoor studio we can capture what makes your family special in creative ways. We are not your typical high-end photographers we are fun, creative, and patient enough to get that perfect shot every time!


My New Product Mantra: Start With The Story
My New Product Mantra: Start With The Story
In this weekly series, I opine on how words affect the way we understand the products and services around us. I do this for your entertainment and education (and, of course, to remind you that if you’re looking for a freelance copy, content, product, or technical writer… yada yada, hire me.
Here’s a fun fact about me: I have a thing for good commercials. Okay, a “thing” is a bit of an understatement: I’m obsessed with good commercials. I fawn over them. I force my friends to watch them. I dissect them and discuss them in lengthy diatribes. Don’t even get me started on Susan Glenn.
I believe commercials to be the haiku of modern story-telling, as with similar constraints comes similar functional beauty when done well.
Given this obsession, then, you shouldn’t be surprised that the subject of today’s post is one such commercial: the overview of The Light Phone 2.
Wait, What Are We Talking About?
The Light Phone 2 is an upcoming product that fits neatly into the ongoing resurgence of the dumb phone — so neatly that it has become something of a poster boy for the movement.
While technology-wise the phone is somewhat interesting — its e-ink display and slim form factor are as alluring as its minimalistic operating system — the product is receiving widespread acclaim and adoption for one reason and one reason alone.
It is telling a great story.
What Happens
Most great products are born from customer insights. Great product companies have for decades done everything possible to connect with customers, to discover new problems, and to deliver compelling solutions.
However, for product companies, too often the solution itself becomes the “thing” once those insights are captured.
Product thinkers tend to get obsessed about the form factor, the specs, the user experience or user interface or the line of copy in the app. We get lost in the functional myopia and forget the humanity of the problem the product was born to solve. We expect our products, which check all the boxes, to be discovered and to sell themselves by virtue of their capability.
And yet, the story behind the product is just as if not more important than the product itself.
So what does this have to do with commercials and the Light Phone 2?
Well, first, consider that the Light Phone 2 has already drummed up more attention (and $1MM USD in pre-orders more) than any other dumb phone on the market to date — and it’s not even on the market yet.
Then, consider the relative marketing and R&D investments of Nokia and Motorola, who each have heavily invested in the dumb phone market and have the powerful tool of nostalgia at their disposal.
The Result
How, then, did the Light Phone 2 become such a rousing success? It happened with a single commercial.
In one minute and forty-seven seconds, the makers of the Light Phone 2 manage to tell a crisp, clearly-articulated, and compelling story — a story that demonstrates a keen understanding of the customer it’s targeting and the problem it’s trying to solve for that customer.
What makes the Light Phone 2 video so effective? It perfectly executes on structured story-telling:
- The protagonist is introduced and clearly related to the audience (read: angsty millennials).
- The protagonist is set in a distant but weirdly-relatable environment of discomfort (read: generic metro areas and tableaus)
- The protagonist faces a challenge we can relate to (read: smartphone obsession and feeling disconnected from life)
- The protagonist finds a way to overcome the challenge (insert product here)
- The protagonist overcomes adversity and succeeds (insert happy montage of tech liberation)
Most importantly, like any great commercial, there remain enough questions to warrant further time investment yet in its audience it accrued enough emotional investment to drive a call-to-action (in this case, a pre-order).
Is the Light Phone 2 the best phone on the market? Absolutely not. Will it be easy to fix once broken? Definitely not. Will the company behind it even exist in 10 years? Probably not.
But what the team behind the Light Phone 2 has done so well is connect what it’s building to the story it wants to tell, and the impact of that story-telling on its success is clear.
In many ways, it’s hard to separate the story from the product: they were designed together, and that’s what makes the entire offering so appealing — and effective.
The Takeaway
I think that notion—that a product should have a story and that its story should be inseperable from itself—is one we should as product developers take note of.
We should know what story our product is trying to tell before we even build it, because it is the story that will ultimately drive adoption of the products we build, not just the features themselves.
In many ways, the arc of a story ties very neatly into our lean canvases and our value proposition designs. Why then do so few of us take the time to plan for that story from day one?
We as product folk should take more pride in those stories. We should be working with our go-to-market teams way before we build a thing; we should be aligning on the story we want to tell and then working to deliver on that story, not building a feature and then trying to wrap a story around it.
I know Simon Sinek has the monopoly on “Start With Why”, but we need a new product mantra: we need to start with the story.
Why? Because building great product is way easier when you start with the story.
Prioritization is easier. You can prioritize based on the impact the feature has on your ability to tell your story.
Validation is easier. You can get the market to validate what you’re planning to build by asking for a commitment after telling them your story.
Launch is easier. You know when to pull the trigger and how to go to market: when you are confident you have delivered on your story.
In the end, driving adoption and moving business metrics related to your product will be the reward for telling your story well.
TL;DR
Your product should be able to tell a great story about why it exists, and you should know what that story is going to be before you build the product.
So, the next time you’re looking at a new feature or product, start with the story. Just be sure it’s an inspiring one, because if it isn’t, you’re unlikely to inspire anyone else—not your investors, nor your teams, nor, most crucially, your buyers.
What about you? Agree? Disagree? Respond away. And if you’d like to learn more about me or my business, visit http://www.frankcaron.com.


| GTK+ 3 Reference Manual |
|---|
As a consequence of the RC format going away, calling gtk_rc_parse()
or
gtk_rc_parse_string()
won't have any effect on a widgets appearance.
The way to replace these calls is using a custom GtkStyleProvider,
either for an individual widget through gtk_style_context_add_provider()
or for all widgets on a screen through gtk_style_context_add_provider_for_screen()
.
Typically, the provider will be a GtkCssProvider, which parse CSS
information from a file or from a string.
Example 125. Using a custom GtkStyleProvider
1 2 3 4 5 6 7 8 9 10 11 12 13 |
GtkStyleContext *context; GtkCssProvider *provider; context = gtk_widget_get_style_context (widget); provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider), ".frame1 {\n" " border-image: url('gradient1.png') 10 10 10 10 stretch;\n" "}\n", -1, NULL); gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref (provider); |
Notice that you can also get style information from custom resources by implementing the GtkStyleProvider interface yourself. This is an advanced feature that should be rarely used.


[how to] is a community for people who like to make things.
Come explore, share, and make your next project with us!
learn
With over 65,000 members, [how to] will enhance your next project with community, support and broad visibility.
share
We connect people who share interests. This allow's the community to share feedback and grow organically. You can be both a learner and a teacher.
connect
Add team members to your projects and work together in a private collaboration space. Discuss code snippets, project images, ideas and project details before committing changes to project logs.
Have an idea for a new art project, hardware hack or startup? Find related projects and build on the shoulders of giants.
learn
People like you make it easy to learn how to make anything, one step at a time.
100’s of hours of video that explores new worlds, teaches creative skills, and helps you discover new passions.
From the stovetop to the workshop, you are sure to be inspired by the awesome projects that are shared everyday.
share
Share your ideas with others or find the perfect idea built by people like you.
Share ideas and how-to created by you. No matter who you are, we all have secret skills to share.
Come join our community of curious innovators, teachers, and life long learners who love to share what they make.
connect
Find a partner, become a teacher, or discover a student of the craft you love.
Making things makes people happy. We can't prove it, but we know it to be true.
Find your happy place, and join one of the friendliest online communities anywhere.


IOTOP
Section: Misc. Reference Manual Pages (1)Updated: April 2009
Index Return to Main Contents
NAME
iotop - simple top-like I/O monitorSYNOPSIS
iotop [OPTIONS]DESCRIPTION
iotop watches I/O usage information output by the Linux kernel (requires 2.6.20 or later) and displays a table of current I/O usage by processes or threads on the system. At least the CONFIG_TASK_DELAY_ACCT and CONFIG_TASK_IO_ACCOUNTING options need to be enabled in your Linux kernel build configuration, these options depend on CONFIG_TASKSTATS.iotop displays columns for the I/O bandwidth read and written by each process/thread during the sampling period. It also displays the percentage of time the thread/process spent while swapping in and while waiting on I/O. For each process, its I/O priority (class/level) is shown. In addition, the total I/O bandwidth read and written during the sampling period is displayed at the top of the interface.
Use the left and right arrows to change the sorting, r to reverse the sorting order, o to toggle the --only option, p to toggle the --processes option, a to toggle the --accumulated option, q to quit or i to change the priority of a thread or a process' thread(s). Any other key will force a refresh.
OPTIONS
- --version
- Show the version number and exit
- -h, --help
- Show usage information and exit
- -o, --only
- Only show processes or threads actually doing I/O, instead of showing all processes or threads. This can be dynamically toggled by pressing o.
- -b, --batch
- Turn on non-interactive mode. Useful for logging I/O usage over time.
- -n NUM, --iter=NUM
- Set the number of iterations before quitting (never quit by default). This is most useful in non-interactive mode.
- -d SEC, --delay=SEC
- Set the delay between iterations in seconds (1 second by default). Accepts non-integer values such as 1.1 seconds.
- -p PID, --pid=PID
- A list of processes/threads to monitor (all by default).
- -u USER, --user=USER
- A list of users to monitor (all by default)
- -P, --processes
- Only show processes. Normally iotop shows all threads.
- -a, --accumulated
- Show accumulated I/O instead of bandwidth. In this mode, iotop shows the amount of I/O processes have done since iotop started.
- -k, --kilobytes
- Use kilobytes instead of a human friendly unit. This mode is useful when scripting the batch mode of iotop. Instead of choosing the most appropriate unit iotop will display all sizes in kilobytes.
- -t, --time
- Add a timestamp on each line (implies --batch). Each line will be prefixed by the current time.
- -q, --quiet
-
suppress some lines of header (implies --batch). This option can be specified up to three times to remove header lines.
-
- -q
- column names are only printed on the first iteration,
- column names are never printed,
- -qqq
- the I/O summary is never printed.
-
SEE ALSO
ionice(1), top(1), vmstat(1)AUTHOR
iotop was written by Guillaume Chazarain.This manual page was started by Paul Wise for the Debian project and is placed in the public domain.
Index
This document was created by man2html, using the manual pages.
Time: 05:29:05 GMT, December 24, 2015


UPMA
Rava / Sooji Upma is one of the most favourite south Indian breakfast. A huge number of variations of Upma are made with whole or refined ground wheat and rice of varied grain size, vermicelli or wheat semolina. A wide range of vegetables may be added, and may be garnished with a variety of beans (raw or sprouted), cashew and peanuts. For a variation called masala upma (known as ‘Kharabath’ in Karnataka), sambhar masala or garam masala is added along with red chilli powder, instead of green chillies.
IDLI
Idli with sambar is one of the most favourite south Indian breakfast.
Idli are a type of savory rice cake, originating from the Indian subcontinent, popular as breakfast
foods in southern India and northern Sri Lanka. The cakes are made by steaming a batter consisting of
fermented black lentils(de-husked) and rice. The fermentation process breaks down the starches so that
they are more readily metabolized by the body.
This South Indian food made with fermented rice and black gram, it’s a great source of carbohydrates and proteins. The fermentation increases proteins and enhances the vitamin B content of the food. As it is steamed, fat content is low and it is easily digestible. Use of black gram and rice in idli is a good combination as the amino acids in them complement each other. Idli is nutritious as it is a rich source of carbohydrates, fibres and proteins.
VADA
Vada is one of the most favourite south Indian breakfast.
Vada is a very popular savory deep fried fritter type of snack from Southern India. It is a typical street food in the Indian subcontinent and Sri Lanka. They are also prepared at most homes especially during some festivals or functions.
Vada a category of savory fried snacks from India. Different types of vadas can be described variously as fritters, doughnuts, or dumplings
The various types of vadas are made from different ingredients, ranging from legumes (such as medu vada of South India) to potatoes(such as batata vada of West India). They are often served as a breakfast item or a snack, and also used in other food preparations (such as dahi vada and vada pav).
DOSA
DOSA is another favourite south Indian breakfast. Dosa is a type of pancake originating from the Indian subcontinent, made from a fermented batter. Its main ingredients are rice and black gram. Dosa is a typical part of the Southern Indian but is now popular all over the Indian subcontinent. The masala dosa is served with a yummy stuffed potato curry, coconut chutney and sambar. Dosa is high in carbohydrates and contains no added sugars or saturated fats. As its key ingredients are rice and black gram, it is also a good source of protein. The fermentation process increases the vitamin B and vitamin C content.
SAMOSA
SAMOSA is favourite Indian snack. Samosas were brought to the Indian subcontinent by various Muslim merchants, and patronized under various Islamic dynasties in the region.
The Indian style, often accompanied by chutney is probably the most widely-known of a broad family of recipes from Africa to China, which have origins in medieval times or earlier. Samosas are a popular entrée, appetizer, or snack in the local cuisines of the Indian subcontinent, Western Asia, Southeast Asia, the Mediterranean, the Horn of Africa, North Africa, and Southern Africa.
The samosa is made with all-purpose flour , shell stuffed with some filling, generally a mixture of mashed boiled potato, onions, green peas, lentils, spices and green chili, or fruits. The entire pastry is then deep-fried in vegetable oil or rarely ghee to a golden brown color. It is served hot and is often eaten with fresh green chutney, such as mint, coriander, or tamarind.
CHOLE BATHURA
CHOLE BATHURA is favourite North Indian snack and breakfast.
Chole bhature is a dish from the Punjab region in the northern part of the Indian subcontinent. This dish is a combination of chana masala (spicy white chickpeas) and bhatura, a fried bread made from all-purpose/maida flour.
Chola Bhatura or Chole Bhature is an extremely popular and super-delicious main dish recipe that Punjabis love to eat in breakfast, and can be prepared on any occasion.
Chole bhature sometimes accompanied with lassi, however, it can also be a street food or a complete meal, and may be accompanied by, for example, onions, carrot pickle, green chutney and achaar.


* What speeded up my Glosa most, was in attempting to use the language to get the particular meaning I wanted. This happened when I attempted to retell well-known children's stories in Glosa.
* When writing a sentence aim for balance in your style and a good sound in the words: a well written sentence should flow, and the relationship of the parts of the sentence should be immediately apparent to a reader.
* Edit what you have written: it should look, feel and sound good. On reading your Glosa sentence out aloud, it should sound good and remind you of the thoughts that were in your mind when you wrote it.
* When choosing words, to express your ideas, Glosa works best if you avoid derivative and metphoric vocabulary, and select the actual root words that express the particular idea.
* Is it too much to say that, in Glosa, cliched thinking and national language idiom are out? Such non-literal language varies from culture to culture, and does not translate well; in the arena of global communication cliche and idiom are just bad style. If non-literal language cannot be avoided, it can be marked off using an agreed convention, such as placing asterisks around it:
e.g. Yesterday, it was raining cats and dogs, and we got wet through. Pa-di, u meteo pa pluvi *plu felis e plu kanis* e na pa gene kompleti ge-hidro.
Address (expired): Robin F. Gaskell Tel. 61-2-9726 0952
PO Box 21, Cabramatta NSW 2166, Australia
The Glosa Educational Organisation is a Registered Charity in the UK.
Address: (R Clark &) W Ashby, GEO
35 Wingfield Road; Kingston Upon Thames; Surrey KT2 5LR; ENGLAND.
www.glosa.org, last modified 2011-05-12.


WARNING! Read the conditions for the problems in this set very carefully!
Assume for a directed graph with numV vertices and numE edges that a vertex index requires vertB bytes, and a pointer requires pointerB bytes. The graph is unweighted, so assume that each matrix element stores one byte to represent the edge. Calculate the byte requirements for an adjacency matrix.
ANS
The matrix is |V| by |V|
Each position of the matix needs 1 byte
V^2 * 1 bytes = ANS


SUBROUTINE DLARRE( RANGE, N, VL, VU, IL, IU, D, E, E2, $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M, $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN, $ WORK, IWORK, INFO ) IMPLICIT NONE * * -- LAPACK auxiliary routine (version 3.1) -- * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. * November 2006 * * .. Scalar Arguments .. CHARACTER RANGE INTEGER IL, INFO, IU, M, N, NSPLIT DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU * .. * .. Array Arguments .. INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ), $ INDEXW( * ) DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ), $ W( * ),WERR( * ), WGAP( * ), WORK( * ) * .. * * Purpose * ======= * * To find the desired eigenvalues of a given real symmetric * tridiagonal matrix T, DLARRE sets any "small" off-diagonal * elements to zero, and for each unreduced block T_i, it finds * (a) a suitable shift at one end of the block's spectrum, * (b) the base representation, T_i - sigma_i I = L_i D_i L_i^T, and * (c) eigenvalues of each L_i D_i L_i^T. * The representations and eigenvalues found are then used by * DSTEMR to compute the eigenvectors of T. * The accuracy varies depending on whether bisection is used to * find a few eigenvalues or the dqds algorithm (subroutine DLASQ2) to * conpute all and then discard any unwanted one. * As an added benefit, DLARRE also outputs the n * Gerschgorin intervals for the matrices L_i D_i L_i^T. * * Arguments * ========= * * RANGE (input) CHARACTER * = 'A': ("All") all eigenvalues will be found. * = 'V': ("Value") all eigenvalues in the half-open interval * (VL, VU] will be found. * = 'I': ("Index") the IL-th through IU-th eigenvalues (of the * entire matrix) will be found. * * N (input) INTEGER * The order of the matrix. N > 0. * * VL (input/output) DOUBLE PRECISION * VU (input/output) DOUBLE PRECISION * If RANGE='V', the lower and upper bounds for the eigenvalues. * Eigenvalues less than or equal to VL, or greater than VU, * will not be returned. VL < VU. * If RANGE='I' or ='A', DLARRE computes bounds on the desired * part of the spectrum. * * IL (input) INTEGER * IU (input) INTEGER * If RANGE='I', the indices (in ascending order) of the * smallest and largest eigenvalues to be returned. * 1 <= IL <= IU <= N. * * D (input/output) DOUBLE PRECISION array, dimension (N) * On entry, the N diagonal elements of the tridiagonal * matrix T. * On exit, the N diagonal elements of the diagonal * matrices D_i. * * E (input/output) DOUBLE PRECISION array, dimension (N) * On entry, the first (N-1) entries contain the subdiagonal * elements of the tridiagonal matrix T; E(N) need not be set. * On exit, E contains the subdiagonal elements of the unit * bidiagonal matrices L_i. The entries E( ISPLIT( I ) ), * 1 <= I <= NSPLIT, contain the base points sigma_i on output. * * E2 (input/output) DOUBLE PRECISION array, dimension (N) * On entry, the first (N-1) entries contain the SQUARES of the * subdiagonal elements of the tridiagonal matrix T; * E2(N) need not be set. * On exit, the entries E2( ISPLIT( I ) ), * 1 <= I <= NSPLIT, have been set to zero * * RTOL1 (input) DOUBLE PRECISION * RTOL2 (input) DOUBLE PRECISION * Parameters for bisection. * An interval [LEFT,RIGHT] has converged if * RIGHT-LEFT.LT.MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) ) * * SPLTOL (input) DOUBLE PRECISION * The threshold for splitting. * * NSPLIT (output) INTEGER * The number of blocks T splits into. 1 <= NSPLIT <= N. * * ISPLIT (output) INTEGER array, dimension (N) * The splitting points, at which T breaks up into blocks. * The first block consists of rows/columns 1 to ISPLIT(1), * the second of rows/columns ISPLIT(1)+1 through ISPLIT(2), * etc., and the NSPLIT-th consists of rows/columns * ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N. * * M (output) INTEGER * The total number of eigenvalues (of all L_i D_i L_i^T) * found. * * W (output) DOUBLE PRECISION array, dimension (N) * The first M elements contain the eigenvalues. The * eigenvalues of each of the blocks, L_i D_i L_i^T, are * sorted in ascending order ( DLARRE may use the * remaining N-M elements as workspace). * * WERR (output) DOUBLE PRECISION array, dimension (N) * The error bound on the corresponding eigenvalue in W. * * WGAP (output) DOUBLE PRECISION array, dimension (N) * The separation from the right neighbor eigenvalue in W. * The gap is only with respect to the eigenvalues of the same block * as each block has its own representation tree. * Exception: at the right end of a block we store the left gap * * IBLOCK (output) INTEGER array, dimension (N) * The indices of the blocks (submatrices) associated with the * corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue * W(i) belongs to the first block from the top, =2 if W(i) * belongs to the second block, etc. * * INDEXW (output) INTEGER array, dimension (N) * The indices of the eigenvalues within each block (submatrix); * for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the * i-th eigenvalue W(i) is the 10-th eigenvalue in block 2 * * GERS (output) DOUBLE PRECISION array, dimension (2*N) * The N Gerschgorin intervals (the i-th Gerschgorin interval * is (GERS(2*i-1), GERS(2*i)). * * PIVMIN (output) DOUBLE PRECISION * The minimum pivot in the Sturm sequence for T. * * WORK (workspace) DOUBLE PRECISION array, dimension (6*N) * Workspace. * * IWORK (workspace) INTEGER array, dimension (5*N) * Workspace. * * INFO (output) INTEGER * = 0: successful exit * > 0: A problem occured in DLARRE. * < 0: One of the called subroutines signaled an internal problem. * Needs inspection of the corresponding parameter IINFO * for further information. * * =-1: Problem in DLARRD. * = 2: No base representation could be found in MAXTRY iterations. * Increasing MAXTRY and recompilation might be a remedy. * =-3: Problem in DLARRB when computing the refined root * representation for DLASQ2. * =-4: Problem in DLARRB when preforming bisection on the * desired part of the spectrum. * =-5: Problem in DLASQ2. * =-6: Problem in DLASQ2. * * Further Details * The base representations are required to suffer very little * element growth and consequently define all their eigenvalues to * high relative accuracy. * =============== * * Based on contributions by * Beresford Parlett, University of California, Berkeley, USA * Jim Demmel, University of California, Berkeley, USA * Inderjit Dhillon, University of Texas, Austin, USA * Osni Marques, LBNL/NERSC, USA * Christof Voemel, University of California, Berkeley, USA * * ===================================================================== * * .. Parameters .. DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD, $ MAXGROWTH, ONE, PERT, TWO, ZERO PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, $ TWO = 2.0D0, FOUR=4.0D0, $ HNDRD = 100.0D0, $ PERT = 8.0D0, $ HALF = ONE/TWO, FOURTH = ONE/FOUR, FAC= HALF, $ MAXGROWTH = 64.0D0, FUDGE = 2.0D0 ) INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG PARAMETER ( MAXTRY = 6, ALLRNG = 1, INDRNG = 2, $ VALRNG = 3 ) * .. * .. Local Scalars .. LOGICAL FORCEB, NOREP, USEDQD INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO, $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM, $ WBEGIN, WEND DOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS, $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL, $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM, $ TAU, TMP, TMP1 * .. * .. Local Arrays .. INTEGER ISEED( 4 ) * .. * .. External Functions .. LOGICAL LSAME DOUBLE PRECISION DLAMCH EXTERNAL DLAMCH, LSAME * .. * .. External Subroutines .. EXTERNAL DCOPY, DLARNV, DLARRA, DLARRB, DLARRC, DLARRD, $ DLASQ2 * .. * .. Intrinsic Functions .. INTRINSIC ABS, MAX, MIN * .. * .. Executable Statements .. * INFO = 0 * * Decode RANGE * IF( LSAME( RANGE, 'A' ) ) THEN IRANGE = ALLRNG ELSE IF( LSAME( RANGE, 'V' ) ) THEN IRANGE = VALRNG ELSE IF( LSAME( RANGE, 'I' ) ) THEN IRANGE = INDRNG END IF M = 0 * Get machine constants SAFMIN = DLAMCH( 'S' ) EPS = DLAMCH( 'P' ) * Set parameters RTL = SQRT(EPS) BSRTOL = SQRT(EPS) * Treat case of 1x1 matrix for quick return IF( N.EQ.1 ) THEN IF( (IRANGE.EQ.ALLRNG).OR. $ ((IRANGE.EQ.VALRNG).AND.(D(1).GT.VL).AND.(D(1).LE.VU)).OR. $ ((IRANGE.EQ.INDRNG).AND.(IL.EQ.1).AND.(IU.EQ.1)) ) THEN M = 1 W(1) = D(1) * The computation error of the eigenvalue is zero WERR(1) = ZERO WGAP(1) = ZERO IBLOCK( 1 ) = 1 INDEXW( 1 ) = 1 GERS(1) = D( 1 ) GERS(2) = D( 1 ) ENDIF * store the shift for the initial RRR, which is zero in this case E(1) = ZERO RETURN END IF * General case: tridiagonal matrix of order > 1 * * Init WERR, WGAP. Compute Gerschgorin intervals and spectral diameter. * Compute maximum off-diagonal entry and pivmin.  EMAX ) THEN EMAX = EABS END IF TMP1 = EABS + EOLD GERS( 2*I-1) = D(I) - TMP1 GL = MIN( GL, GERS( 2*I - 1)) GERS( 2*I ) = D(I) + TMP1 GU = MAX( GU, GERS(2*I) ) EOLD = EABS 5 CONTINUE * The minimum pivot allowed in the Sturm sequence for T PIVMIN = SAFMIN * MAX( ONE, EMAX**2 ) * Compute spectral diameter. The Gerschgorin bounds give an * estimate that is wrong by at most a factor of SQRT(2) SPDIAM = GU - GL * Compute splitting points CALL DLARRA( N, D, E, E2, SPLTOL, SPDIAM, $ NSPLIT, ISPLIT, IINFO ) * Can force use of bisection instead of faster DQDS. * Option left in the code for future multisection work. FORCEB = .FALSE. IF( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ) THEN * Set interval [VL,VU] that contains all eigenvalues VL = GL VU = GU ELSE * We call DLARRD to find crude approximations to the eigenvalues * in the desired range. In case IRANGE = INDRNG, we also obtain the * interval (VL,VU] that contains all the wanted eigenvalues. * An interval [LEFT,RIGHT] has converged if * RIGHT-LEFT.LT.RTOL*MAX(ABS(LEFT),ABS(RIGHT)) * DLARRD needs a WORK of size 4*N, IWORK of size 3*N CALL DLARRD( RANGE, 'B', N, VL, VU, IL, IU, GERS, $ BSRTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT, $ MM, W, WERR, VL, VU, IBLOCK, INDEXW, $ WORK, IWORK, IINFO ) IF( IINFO.NE.0 ) THEN INFO = -1 RETURN ENDIF * Make sure that the entries M+1 to N in W, WERR, IBLOCK, INDEXW are 0 DO 14 I = MM+1,N W( I ) = ZERO WERR( I ) = ZERO IBLOCK( I ) = 0 INDEXW( I ) = 0 14 CONTINUE END IF *** * Loop over unreduced blocks IBEGIN = 1 WBEGIN = 1 DO 170 JBLK = 1, NSPLIT IEND = ISPLIT( JBLK ) IN = IEND - IBEGIN + 1 * 1 X 1 block IF( IN.EQ.1 ) THEN IF( (IRANGE.EQ.ALLRNG).OR.( (IRANGE.EQ.VALRNG).AND. $ ( D( IBEGIN ).GT.VL ).AND.( D( IBEGIN ).LE.VU ) ) $ .OR. ( (IRANGE.EQ.INDRNG).AND.(IBLOCK(WBEGIN).EQ.JBLK)) $ ) THEN M = M + 1 W( M ) = D( IBEGIN ) WERR(M) = ZERO * The gap for a single block doesn't matter for the later * algorithm and is assigned an arbitrary large value WGAP(M) = ZERO IBLOCK( M ) = JBLK INDEXW( M ) = 1 WBEGIN = WBEGIN + 1 ENDIF * E( IEND ) holds the shift for the initial RRR E( IEND ) = ZERO IBEGIN = IEND + 1 GO TO 170 END IF * * Blocks of size larger than 1x1 * * E( IEND ) will hold the shift for the initial RRR, for now set it =0 E( IEND ) = ZERO * * Find local outer bounds GL,GU for the block GL = D(IBEGIN) GU = D(IBEGIN) DO 15 I = IBEGIN , IEND GL = MIN( GERS( 2*I-1 ), GL ) GU = MAX( GERS( 2*I ), GU ) 15 CONTINUE SPDIAM = GU - GL IF(.NOT. ((IRANGE.EQ.ALLRNG).AND.(.NOT.FORCEB)) ) THEN * Count the number of eigenvalues in the current block. MB = 0 DO 20 I = WBEGIN,MM IF( IBLOCK(I).EQ.JBLK ) THEN MB = MB+1 ELSE GOTO 21 ENDIF 20 CONTINUE 21 CONTINUE IF( MB.EQ.0) THEN * No eigenvalue in the current block lies in the desired range * E( IEND ) holds the shift for the initial RRR E( IEND ) = ZERO IBEGIN = IEND + 1 GO TO 170 ELSE * Decide whether dqds or bisection is more efficient USEDQD = ( (MB .GT. FAC*IN) .AND. (.NOT.FORCEB) ) WEND = WBEGIN + MB - 1 * Calculate gaps for the current block * In later stages, when representations for individual * eigenvalues are different, we use SIGMA = E( IEND ). SIGMA = ZERO DO 30 I = WBEGIN, WEND - 1 WGAP( I ) = MAX( ZERO, $ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) ) 30 CONTINUE WGAP( WEND ) = MAX( ZERO, $ VU - SIGMA - (W( WEND )+WERR( WEND ))) * Find local index of the first and last desired evalue. INDL = INDEXW(WBEGIN) INDU = INDEXW( WEND ) ENDIF ENDIF IF(( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ).OR.USEDQD) THEN * Case of DQDS * Find approximations to the extremal eigenvalues of the block CALL DLARRK( IN, 1, GL, GU, D(IBEGIN), $ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO ) IF( IINFO.NE.0 ) THEN INFO = -1 RETURN ENDIF ISLEFT = MAX(GL, TMP - TMP1 $ - HNDRD * EPS* ABS(TMP - TMP1)) CALL DLARRK( IN, IN, GL, GU, D(IBEGIN), $ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO ) IF( IINFO.NE.0 ) THEN INFO = -1 RETURN ENDIF ISRGHT = MIN(GU, TMP + TMP1 $ + HNDRD * EPS * ABS(TMP + TMP1)) * Improve the estimate of the spectral diameter SPDIAM = ISRGHT - ISLEFT ELSE * Case of bisection * Find approximations to the wanted extremal eigenvalues ISLEFT = MAX(GL, W(WBEGIN) - WERR(WBEGIN) $ - HNDRD * EPS*ABS(W(WBEGIN)- WERR(WBEGIN) )) ISRGHT = MIN(GU,W(WEND) + WERR(WEND) $ + HNDRD * EPS * ABS(W(WEND)+ WERR(WEND))) ENDIF * Decide whether the base representation for the current block * L_JBLK D_JBLK L_JBLK^T = T_JBLK - sigma_JBLK I * should be on the left or the right end of the current block. * The strategy is to shift to the end which is "more populated" * Furthermore, decide whether to use DQDS for the computation of * the eigenvalue approximations at the end of DLARRE or bisection. * dqds is chosen if all eigenvalues are desired or the number of * eigenvalues to be computed is large compared to the blocksize. IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN * If all the eigenvalues have to be computed, we use dqd USEDQD = .TRUE. * INDL is the local index of the first eigenvalue to compute INDL = 1 INDU = IN * MB = number of eigenvalues to compute MB = IN WEND = WBEGIN + MB - 1 * Define 1/4 and 3/4 points of the spectrum S1 = ISLEFT + FOURTH * SPDIAM S2 = ISRGHT - FOURTH * SPDIAM ELSE * DLARRD has computed IBLOCK and INDEXW for each eigenvalue * approximation. * choose sigma IF( USEDQD ) THEN S1 = ISLEFT + FOURTH * SPDIAM S2 = ISRGHT - FOURTH * SPDIAM ELSE TMP = MIN(ISRGHT,VU) - MAX(ISLEFT,VL) S1 = MAX(ISLEFT,VL) + FOURTH * TMP S2 = MIN(ISRGHT,VU) - FOURTH * TMP ENDIF ENDIF * Compute the negcount at the 1/4 and 3/4 points IF(MB.GT.1) THEN CALL DLARRC( 'T', IN, S1, S2, D(IBEGIN), $ E(IBEGIN), PIVMIN, CNT, CNT1, CNT2, IINFO) ENDIF IF(MB.EQ.1) THEN SIGMA = GL SGNDEF = ONE ELSEIF( CNT1 - INDL .GE. INDU - CNT2 ) THEN IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN SIGMA = MAX(ISLEFT,GL) ELSEIF( USEDQD ) THEN * use Gerschgorin bound as shift to get pos def matrix * for dqds SIGMA = ISLEFT ELSE * use approximation of the first desired eigenvalue of the * block as shift SIGMA = MAX(ISLEFT,VL) ENDIF SGNDEF = ONE ELSE IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN SIGMA = MIN(ISRGHT,GU) ELSEIF( USEDQD ) THEN * use Gerschgorin bound as shift to get neg def matrix * for dqds SIGMA = ISRGHT ELSE * use approximation of the first desired eigenvalue of the * block as shift SIGMA = MIN(ISRGHT,VU) ENDIF SGNDEF = -ONE ENDIF * An initial SIGMA has been chosen that will be used for computing * T - SIGMA I = L D L^T * Define the increment TAU of the shift in case the initial shift * needs to be refined to obtain a factorization with not too much * element growth. IF( USEDQD ) THEN * The initial SIGMA was to the outer end of the spectrum * the matrix is definite and we need not retreat. TAU = SPDIAM*EPS*N + TWO*PIVMIN ELSE IF(MB.GT.1) THEN CLWDTH = W(WEND) + WERR(WEND) - W(WBEGIN) - WERR(WBEGIN) AVGAP = ABS(CLWDTH / DBLE(WEND-WBEGIN)) IF( SGNDEF.EQ.ONE ) THEN TAU = HALF*MAX(WGAP(WBEGIN),AVGAP) TAU = MAX(TAU,WERR(WBEGIN)) ELSE TAU = HALF*MAX(WGAP(WEND-1),AVGAP) TAU = MAX(TAU,WERR(WEND)) ENDIF ELSE TAU = WERR(WBEGIN) ENDIF ENDIF * DO 80 IDUM = 1, MAXTRY * Compute L D L^T factorization of tridiagonal matrix T - sigma I. * Store D in WORK(1:IN), L in WORK(IN+1:2*IN), and reciprocals of * pivots in WORK(2*IN+1:3*IN) DPIVOT = D( IBEGIN ) - SIGMA WORK( 1 ) = DPIVOT DMAX = ABS( WORK(1) ) J = IBEGIN DO 70 I = 1, IN - 1 WORK( 2*IN+I ) = ONE / WORK( I ) TMP = E( J )*WORK( 2*IN+I ) WORK( IN+I ) = TMP DPIVOT = ( D( J+1 )-SIGMA ) - TMP*E( J ) WORK( I+1 ) = DPIVOT DMAX = MAX( DMAX, ABS(DPIVOT) ) J = J + 1 70 CONTINUE * check for element growth IF( DMAX .GT. MAXGROWTH*SPDIAM ) THEN NOREP = .TRUE. ELSE NOREP = .FALSE. ENDIF IF( USEDQD .AND. .NOT.NOREP ) THEN * Ensure the definiteness of the representation * All entries of D (of L D L^T) must have the same sign DO 71 I = 1, IN TMP = SGNDEF*WORK( I ) IF( TMP.LT.ZERO ) NOREP = .TRUE. 71 CONTINUE ENDIF IF(NOREP) THEN * Note that in the case of IRANGE=ALLRNG, we use the Gerschgorin * shift which makes the matrix definite. So we should end up * here really only in the case of IRANGE = VALRNG or INDRNG. IF( IDUM.EQ.MAXTRY-1 ) THEN IF( SGNDEF.EQ.ONE ) THEN * The fudged Gerschgorin shift should succeed SIGMA = $ GL - FUDGE*SPDIAM*EPS*N - FUDGE*TWO*PIVMIN ELSE SIGMA = $ GU + FUDGE*SPDIAM*EPS*N + FUDGE*TWO*PIVMIN END IF ELSE SIGMA = SIGMA - SGNDEF * TAU TAU = TWO * TAU END IF ELSE * an initial RRR is found GO TO 83 END IF 80 CONTINUE * if the program reaches this point, no base representation could be * found in MAXTRY iterations. INFO = 2 RETURN 83 CONTINUE * At this point, we have found an initial base representation * T - SIGMA I = L D L^T with not too much element growth. * Store the shift. E( IEND ) = SIGMA * Store D and L. CALL DCOPY( IN, WORK, 1, D( IBEGIN ), 1 ) CALL DCOPY( IN-1, WORK( IN+1 ), 1, E( IBEGIN ), 1 ) IF(MB.GT.1 ) THEN * * Perturb each entry of the base representation by a small * (but random) relative amount to overcome difficulties with * glued matrices. * DO 122 I = 1, 4 ISEED( I ) = 1 122 CONTINUE CALL DLARNV(2, ISEED, 2*IN-1, WORK(1)) DO 125 I = 1,IN-1 D(IBEGIN+I-1) = D(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(I)) E(IBEGIN+I-1) = E(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(IN+I)) 125 CONTINUE D(IEND) = D(IEND)*(ONE+EPS*FOUR*WORK(IN)) * ENDIF * * Don't update the Gerschgorin intervals because keeping track * of the updates would be too much work in DLARRV. * We update W instead and use it to locate the proper Gerschgorin * intervals. * Compute the required eigenvalues of L D L' by bisection or dqds IF ( .NOT.USEDQD ) THEN * If DLARRD has been used, shift the eigenvalue approximations * according to their representation. This is necessary for * a uniform DLARRV since dqds computes eigenvalues of the * shifted representation. In DLARRV, W will always hold the * UNshifted eigenvalue approximation. DO 134 J=WBEGIN,WEND W(J) = W(J) - SIGMA WERR(J) = WERR(J) + ABS(W(J)) * EPS 134 CONTINUE * call DLARRB to reduce eigenvalue error of the approximations * from DLARRD DO 135 I = IBEGIN, IEND-1 WORK( I ) = D( I ) * E( I )**2 135 CONTINUE * use bisection to find EV from INDL to INDU CALL DLARRB(IN, D(IBEGIN), WORK(IBEGIN), $ INDL, INDU, RTOL1, RTOL2, INDL-1, $ W(WBEGIN), WGAP(WBEGIN), WERR(WBEGIN), $ WORK( 2*N+1 ), IWORK, PIVMIN, SPDIAM, $ IN, IINFO ) IF( IINFO .NE. 0 ) THEN INFO = -4 RETURN END IF * DLARRB computes all gaps correctly except for the last one * Record distance to VU/GU WGAP( WEND ) = MAX( ZERO, $ ( VU-SIGMA ) - ( W( WEND ) + WERR( WEND ) ) ) DO 138 I = INDL, INDU M = M + 1 IBLOCK(M) = JBLK INDEXW(M) = I 138 CONTINUE ELSE * Call dqds to get all eigs (and then possibly delete unwanted * eigenvalues). * Note that dqds finds the eigenvalues of the L D L^T representation * of T to high relative accuracy. High relative accuracy * might be lost when the shift of the RRR is subtracted to obtain * the eigenvalues of T. However, T is not guaranteed to define its * eigenvalues to high relative accuracy anyway. * Set RTOL to the order of the tolerance used in DLASQ2 * This is an ESTIMATED error, the worst case bound is 4*N*EPS * which is usually too large and requires unnecessary work to be * done by bisection when computing the eigenvectors RTOL = LOG(DBLE(IN)) * FOUR * EPS J = IBEGIN DO 140 I = 1, IN - 1 WORK( 2*I-1 ) = ABS( D( J ) ) WORK( 2*I ) = E( J )*E( J )*WORK( 2*I-1 ) J = J + 1 140 CONTINUE WORK( 2*IN-1 ) = ABS( D( IEND ) ) WORK( 2*IN ) = ZERO CALL DLASQ2( IN, WORK, IINFO ) IF( IINFO .NE. 0 ) THEN * If IINFO = -5 then an index is part of a tight cluster * and should be changed. The index is in IWORK(1) and the * gap is in WORK(N+1) INFO = -5 RETURN ELSE * Test that all eigenvalues are positive as expected DO 149 I = 1, IN IF( WORK( I ).LT.ZERO ) THEN INFO = -6 RETURN ENDIF 149 CONTINUE END IF IF( SGNDEF.GT.ZERO ) THEN DO 150 I = INDL, INDU M = M + 1 W( M ) = WORK( IN-I+1 ) IBLOCK( M ) = JBLK INDEXW( M ) = I 150 CONTINUE ELSE DO 160 I = INDL, INDU M = M + 1 W( M ) = -WORK( I ) IBLOCK( M ) = JBLK INDEXW( M ) = I 160 CONTINUE END IF DO 165 I = M - MB + 1, M * the value of RTOL below should be the tolerance in DLASQ2 WERR( I ) = RTOL * ABS( W(I) ) 165 CONTINUE DO 166 I = M - MB + 1, M - 1 * compute the right gap between the intervals WGAP( I ) = MAX( ZERO, $ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) ) 166 CONTINUE WGAP( M ) = MAX( ZERO, $ ( VU-SIGMA ) - ( W( M ) + WERR( M ) ) ) END IF * proceed with next block IBEGIN = IEND + 1 WBEGIN = WEND + 1 170 CONTINUE * RETURN * * end of DLARRE * END


jQuery API
Table of Content
Accessing
HTML Content
Form Element Content
Image Content
Style
Behavior
ACCESSING
This is the
first
step when developing a DHTML
This is the last paragraph


in AWS, deep learning AMI with source code, ubuntu, CUDA8. N. Virginia server was chosen.
%reset
# Check for a GPU
import tensorflow as tf
print(tf.test.gpu_device_name())
%%bash
pwd
In this project, you'll use generative adversarial networks to generate new images of faces.
You'll be using two datasets in this project:
Since the celebA dataset is complex and you're doing GANs in a project for the first time, we want you to test your neural network on MNIST before CelebA. Running the GANs on MNIST will allow you to see how well your model trains sooner.
If you're using FloydHub, set data_dir
to "/input" and use the FloydHub data ID "R5KrjnANiKVhLWAkpXhNBe".
data_dir = 'data'
# FloydHub - Use with data ID "R5KrjnANiKVhLWAkpXhNBe"
#data_dir = '/input'
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import helper
helper.download_extract('mnist', data_dir)
helper.download_extract('celeba', data_dir)
show_n_images = 25
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
%matplotlib inline
import os
from glob import glob
from matplotlib import pyplot
mnist_images = helper.get_batch(glob(os.path.join(data_dir, 'mnist/*.jpg'))[:show_n_images], 28, 28, 'L')
# Note: because of a version problem with matplot lib, the following line of code doesn't work in this workspace.
pyplot.imshow(helper.images_square_grid(mnist_images, 'L'), cmap='gray')
The CelebFaces Attributes Dataset (CelebA) dataset contains over 200,000 celebrity images with annotations. Since you're going to be generating faces, you won't need the annotations. You can view the first number of examples by changing show_n_images
.
show_n_images = 25
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
mnist_images = helper.get_batch(glob(os.path.join(data_dir, 'img_align_celeba/*.jpg'))[:show_n_images], 28, 28, 'RGB')
pyplot.imshow(helper.images_square_grid(mnist_images, 'RGB'))
Since the project's main focus is on building the GANs, we'll preprocess the data for you. The values of the MNIST and CelebA dataset will be in the range of -0.5 to 0.5 of 28x28 dimensional images. The CelebA images will be cropped to remove parts of the image that don't include a face, then resized down to 28x28.

You'll build the components necessary to build a GANs by implementing the following functions below:
model_inputs
discriminator
generator
model_loss
model_opt
train
This will check to make sure you have the correct version of TensorFlow and access to a GPU
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
from distutils.version import LooseVersion
import warnings
import tensorflow as tf
# Check TensorFlow Version
assert LooseVersion(tf.__version__) >= LooseVersion('1.0'), 'Please use TensorFlow version 1.0 or newer. You are using {}'.format(tf.__version__)
print('TensorFlow Version: {}'.format(tf.__version__))
# Check for a GPU
if not tf.test.gpu_device_name():
warnings.warn('No GPU found. Please use a GPU to train your neural network.')
else:
print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))
Implement the model_inputs
function to create TF Placeholders for the Neural Network. It should create the following placeholders:
image_width
, image_height
, and image_channels
.z_dim
.Return the placeholders in the following the tuple (tensor of real input images, tensor of z data)
import problem_unittests as tests
def model_inputs(image_width, image_height, image_channels, z_dim):
"""
Create the model inputs
:param image_width: The input image width
:param image_height: The input image height
:param image_channels: The number of image channels
:param z_dim: The dimension of Z
:return: Tuple of (tensor of real input images, tensor of z data, learning rate)
"""
# TODO: Implement Function
inputs_real = tf.placeholder(tf.float32, (None, image_width, image_height,image_channels), name='input_real')
inputs_z = tf.placeholder(tf.float32, (None, z_dim), name='input_z')
learning_rate=tf.placeholder(tf.float32, name='learning_rate')
return inputs_real, inputs_z, learning_rate
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_inputs(model_inputs)
Implement discriminator
to create a discriminator neural network that discriminates on images
. This function should be able to reuse the variables in the neural network. Use tf.variable_scope
with a scope name of "discriminator" to allow the variables to be reused. The function should return a tuple of (tensor output of the discriminator, tensor logits of the discriminator).
1) Leaky ReLU activation function helps with the gradient flow and alleviate the problem of sparse gradients (almost 0 gradients). Max pooling generates sparse gradients, which affects the stability of GAN training. That’s the reason, you chose not to use pooling.
2) You have used batch normalization to stabilize GAN training by reducing internal covariant shift. You can go to this link[http://kratzert.github.io/2016/02/12/understanding-the-gradient-flow-through-the-batch-normalization-layer.html] for further understanding Batch norm.
3) You have used Sigmoid as the activation function for the output layer which produces probability-like values between 0 and 1.
Improvement to make: 1) Use custom weight initialization. For example Xavier weight initialization to help converge faster by breaking symmetry or you can also use truncated_normal_initializer with stddev=0.02, which improve overall generated image quality, like in DCGAN paper.
2) Experiment with various values of alpha (slope of the leaky Relu as stated in DCGAN paper) between 0.06 and 0.18 and compare your results.
3) Experiment with dropout layers for discriminator, applying dropout will decrease hyper learning distrib. If discriminator end up dominating generator, we must reduce discriminator learning rate and increase dropout.
</font>
Ref: F. Chollet, "Deep Learning with Python" chapt 8.32".
Use:
dp_layer = tf.nn.dropout(l_relu_output, keep_prob =0.8) or
dp_layer = tf.layer.dropout(l_relu_output, rate =0.2)
#https://discussions.udacity.com/t/discriminator-variable-scope-reuse/662468
depth = 64 #==filters=the dimensionality of the output space(i.e. the number of filters in the convolution).
kernel_size=5 # kernel_size=height and width of the 2D convolution window
strides=2
alpha=0.06 #if this is not within this variable_scope, can not pass test: assert mock_variable_scope.call_args == mock.call('discriminator', reuse=True)
#tf.variable_scope called with wrong arguments in Discriminator Inference(reuse=True)
#Reviewer#1: Experiment with various values of alpha (slope of the leaky Relu as stated in DCGAN paper) between 0.06 and 0.18 and compare your results.
def discriminator(images, reuse=False):
"""
Create the discriminator network
:param images: Tensor of input image(s)
:param reuse: Boolean if the weights should be reused
:return: Tuple of (tensor output of the discriminator, tensor logits of the discriminator)
"""
# TODO: Implement Function
with tf.variable_scope('discriminator', reuse=reuse) :
# Hidden layer #1: Input layer is 28x28x3
h1 = tf.layers.conv2d(images, filters=depth, kernel_size = kernel_size, strides=strides, padding='same', \
kernel_initializer=tf.contrib.layers.xavier_initializer())
relu1 = tf.maximum(alpha * h1, h1)
relu1_dropout = tf.nn.dropout(relu1, keep_prob =0.8)
# 14x14x64 now
# Hidden layer #2:
h2 = tf.layers.conv2d(relu1_dropout, filters=depth*2, kernel_size = kernel_size, strides=strides, padding='same',\
kernel_initializer=tf.contrib.layers.xavier_initializer())
bn2 = tf.layers.batch_normalization(h2, training=True)
relu2 = tf.maximum(alpha * bn2, bn2)
relu2_dropout = tf.nn.dropout(relu2, keep_prob =0.8)
# 7x7x128 now
# Hidden layer #3:
h3 = tf.layers.conv2d(relu2, filters=depth*4, kernel_size = kernel_size, strides=strides, padding='same',\
kernel_initializer=tf.contrib.layers.xavier_initializer())
bn3 = tf.layers.batch_normalization(h3, training=True)
relu3 = tf.maximum(alpha * bn3, bn3)
relu3_dropout = tf.nn.dropout(relu3, keep_prob =0.8)
# 3x3x256 now
# Flatten it
flat = tf.reshape(relu3, (-1, 4*4*depth*4))
logits = tf.layers.dense(flat, 1)
isFakeReal = tf.nn.sigmoid(logits)
return isFakeReal, logits
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_discriminator(discriminator, tf)
Implement generator
to generate an image using z
. This function should be able to reuse the variables in the neural network. Use tf.variable_scope
with a scope name of "generator" to allow the variables to be reused. The function should return the generated 28 x 28 x out_channel_dim
images.
You have used Tanh as the last layer of the generator output, so you will normalize the input images to be between -1 and 1 in train function.
You have met the basic requirements, but I recommend you to work on the below tips and comment on the improvements you see in the generated image.
1) Experiment with more conv2d_transpose layers in generator block so that there're enough parameters in the network to learn the concepts of the input images. DCGAN models produce better results when generator is bigger than discriminator.
Suggestion: 1024->512->256->128->out_channel_dim (Use stride as 1 to increase the number of layers without changing the size of the output image). ==> instead, first input depth is increased from 1024 to 2048
2) Experiment with different slope values for leaky_relu as told in discriminator.
3) Experiment dropout in generator, so that it is less prone to learning the data distribution and avoid generating images that look like noise.
(CONV/FC -> BatchNorm -> ReLu(or other activation) -> Dropout -> CONV/FC)
</font>
import math
z=100
int(math.sqrt(z))
reshape_d=5
def generator(z, out_channel_dim, is_train=True):
"""
Create the generator network
:param z: Input z
:param out_channel_dim: The number of channels in the output image
:param is_train: Boolean if generator is being used for training
:return: The tensor output of the generator
"""
# TODO: Implement Function
with tf.variable_scope('generator', reuse=not is_train):
#Using the reverse process of the discriminator
# First fully connected layer #1:
h1 = tf.layers.dense(z, reshape_d*reshape_d*1024) # First fully connected layer, 256
#(?, 256) now
#Input to reshape is a tensor with z*56 values, but the requested shape requires a multiple of reshape_d**2 * 1024
#Input to reshape is a tensor with 8192 values, but the requested shape requires a multiple of 25600
print("z=", z)
h1 = tf.reshape(h1, (-1, reshape_d, reshape_d, 1024)) #this 1024 is my choice upon paper. reshape_d comes from
h1 = tf.layers.batch_normalization(h1, training=is_train)
h1 = tf.maximum(alpha * h1, h1)
h1_dropout = tf.nn.dropout(h1, keep_prob =0.8)
#(?, 7,7,1024) now
# Hidden layer #2:
h2 = tf.layers.conv2d_transpose(h1_dropout, 512, kernel_size = kernel_size, \
strides=2, padding='same', \
kernel_initializer=tf.contrib.layers.xavier_initializer())
print("h2 (?, , , 512)=", h2.get_shape())
h2 = tf.layers.batch_normalization(h2, training=is_train)
h2 = tf.maximum(alpha * h2, h2)
h2_dropout = tf.nn.dropout(h2, keep_prob =0.8)
#(?, 7, 7, 512)
# Hidden layer #3:
h3 = tf.layers.conv2d_transpose(h2_dropout, 256, kernel_size = kernel_size, \
strides=2, padding='same', \
kernel_initializer=tf.contrib.layers.xavier_initializer())
print("h3 (?, , , 256)=", h3.get_shape()) #
h3 = tf.layers.batch_normalization(h3, training=is_train)
h3 = tf.maximum(alpha * h3, h3)
h3_dropout = tf.nn.dropout(h3, keep_prob =0.8)
#(?, 7, 7, 256)
# Hidden layer #4:
h4 = tf.layers.conv2d_transpose(h3_dropout, 128, kernel_size = kernel_size, \
strides=1, padding='valid',\
kernel_initializer=tf.contrib.layers.xavier_initializer())
print("h4 (?, , , 128)=", h4.get_shape())
h4 = tf.layers.batch_normalization(h4, training=is_train)
h4 = tf.maximum(alpha * h4, h4)
h4_dropout = tf.nn.dropout(h4, keep_prob =0.8)
#(?, 14, 14, 128)
#final layer #5:
logits = tf.layers.conv2d_transpose(h4_dropout, out_channel_dim, kernel_size = kernel_size, \
strides=1, padding='valid',\
kernel_initializer=tf.contrib.layers.xavier_initializer())
print("out_channel_dim=",out_channel_dim)
print("logits (?, 28, 28, 5) =", logits.get_shape())
fake_image = tf.tanh(logits)
#(?, 28, 28, 5)
return fake_image
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_generator(generator, tf)
Implement model_loss
to build the GANs for training and calculate the loss. The function should return a tuple of (discriminator loss, generator loss). Use the following functions you implemented:
discriminator(images, reuse=False)
generator(z, out_channel_dim, is_train=True)
Experiment with label smoothing for discriminator loss, it prevents discriminator from being too strong and to generalize in a better way. Refer https://arxiv.org/abs/1606.03498
Below is a starter code,
d_loss_real = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, labels=tf.ones_like(d_model_real) * (1 - smooth)))
smooth=0.1
def model_loss(input_real, input_z, out_channel_dim):
"""
Get the loss for the discriminator and generator
:param input_real: Images from the real dataset
:param input_z: Z input
:param out_channel_dim: The number of channels in the output image
:return: A tuple of (discriminator loss, generator loss)
"""
# TODO: Implement Function
# Initializing Variables with predictions
g_model = generator(input_z, out_channel_dim)
d_model_real, d_logits_real = discriminator(input_real)
d_model_fake, d_logits_fake = discriminator(g_model, reuse=True)
# Calculate the Losses for it real, fake & generated models
#label smoothing for discriminator loss, it prevents discriminator from being too strong
d_loss_real = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, \
labels=tf.ones_like(d_model_real)*(1 - smooth)))
d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
logits=d_logits_fake, labels=tf.zeros_like(d_model_fake)))
g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
logits=d_logits_fake, labels=tf.ones_like(d_model_fake)))
# The Discriminator Loss is the amount of it fake img loss + it real img loss
d_loss = d_loss_real + d_loss_fake
return d_loss, g_loss
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_loss(model_loss)
Implement model_opt
to create the optimization operations for the GANs. Use tf.trainable_variables
to get all the trainable variables. Filter the variables with names that are in the discriminator and generator scope names. The function should return a tuple of (discriminator training operation, generator training operation).
To avoid internal covariant shift during training, you use batch norm. But in tensorflow **when is_train is true and you have used batch norm, mean and variance needs to be updated before optimization**. So, you add control dependency on the update ops before optimizing the network.
More Info here
def model_opt(d_loss, g_loss, learning_rate, beta1):
"""
Get optimization operations
:param d_loss: Discriminator loss Tensor
:param g_loss: Generator loss Tensor
:param learning_rate: Learning Rate Placeholder
:param beta1: The exponential decay rate for the 1st moment in the optimizer
:return: A tuple of (discriminator training operation, generator training operation)
"""
# TODO: Implement Function
# Empty TF TrainableVariables
t_vars = tf.trainable_variables()
# Append var to D & G vars arraies if it starts with the "prefix" for on it name
d_vars = [var for var in t_vars if var.name.startswith('discriminator')]
g_vars = [var for var in t_vars if var.name.startswith('generator')]
# optimization
d_train_opt = tf.train.AdamOptimizer(learning_rate, beta1=beta1).minimize(d_loss, var_list=d_vars)
g_train_opt = tf.train.AdamOptimizer(learning_rate).minimize(g_loss, var_list=g_vars)
# UPDATE OPS GraphKeys:Ensures that we execute the update_ops before performing \
# the train_step. Ref:http://ruishu.io/2016/12/27/batchnorm/
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
#print("update_ops=", update_ops, type(update_ops))
#Tensor("generator/batch_normalization/AssignMovingAvg:0", shape=(1024,), dtype=float32_ref)
# type: <class 'tensorflow.python.framework.ops.Tensor'>
# ensor("generator/batch_normalization/AssignMovingAvg:0", shape=(1024,), dtype=float32_ref) \
#generator/batch_normalization/AssignMovingAvg:0 <class 'str'>
g_updates = [opt for opt in update_ops if opt.name.startswith('generator')]
with tf.control_dependencies(g_updates):
g_train_opt = tf.train.AdamOptimizer(learning_rate, beta1).minimize(g_loss, var_list=g_vars)
return d_train_opt, g_train_opt
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_model_opt(model_opt, tf)
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import numpy as np
def show_generator_output(sess, n_images, input_z, out_channel_dim, image_mode):
"""
Show example output for the generator
:param sess: TensorFlow session
:param n_images: Number of Images to display
:param input_z: Input Z Tensor
:param out_channel_dim: The number of channels in the output image
:param image_mode: The mode to use for images ("RGB" or "L")
"""
cmap = None if image_mode == 'RGB' else 'gray'
z_dim = input_z.get_shape().as_list()[-1]
example_z = np.random.uniform(-1, 1, size=[n_images, z_dim])
samples = sess.run(
generator(input_z, out_channel_dim, False),
feed_dict={input_z: example_z})
images_grid = helper.images_square_grid(samples, image_mode)
pyplot.imshow(images_grid, cmap=cmap)
pyplot.show()
Implement train
to build and train the GANs. Use the following functions you implemented:
model_inputs(image_width, image_height, image_channels, z_dim)
model_loss(input_real, input_z, out_channel_dim)
model_opt(d_loss, g_loss, learning_rate, beta1)
Use the show_generator_output
to show generator
output while you train. Running show_generator_output
for every batch will drastically increase training time and increase the size of the notebook. It's recommended to print the generator
output every 100 batches.
Great work combining all the functions together and making it a DCGAN.
Good job scaling the input images to the same scale as the generated ones using batch_images *= 2.0 .
Tip:
Execute the optimization for generator twice. This ensures that the discriminator loss does not go to 0 and impede learning.
Extra:
1) Talk on “How to train a GAN” by one of the author of original DCGAN paper here..https://www.youtube.com/watch?v=X1mUN6dD8uE
2) Here is a post on Gan hacks, https://github.com/soumith/ganhacks
3) Plot discriminator and generator loss for better understanding. You can utilize the below code snippet to plot the loss graph to get a better understanding.
d,_ = sess.run(…)
g,_ = sess.run(…)
d_loss_vec.append(d)
g_loss_vec.append(g)
At the end, you can include the below code to plot the final array:
Discriminator_loss, = plt.plot(d_loss_vec, color='b', label='Discriminator loss')
Genereator_loss, = plt.plot(g_loss_vec, color='r', label='Generator loss')
plt.legend(handles=[ Discriminator_loss, Genereator_loss])
import matplotlib.pyplot as plt
%matplotlib inline
def train(epochs, batch_size, z_dim, learning_rate, beta1, get_batches, data_shape, data_image_mode):
"""
Train the GAN
:param epochs: Number of epochs
:param batch_size: Batch Size
:param z_dim: Z dimension
:param learning_rate: Learning Rate
:param beta1: The exponential decay rate for the 1st moment in the optimizer
:param get_batches: Function to get batches
:param data_shape: Shape of the data
:param data_image_mode: The image mode to use for images ("RGB" or "L")
"""
# TODO: Build Model
_, img_width, img_height, img_channels = data_shape # 28x28x3 or 28x28x1
real_input_img, z_input, lr = model_inputs(img_width, img_height, img_channels, z_dim)
d_loss, g_loss = model_loss(real_input_img, z_input, img_channels)
d_opt, g_opt = model_opt(d_loss, g_loss, learning_rate, beta1)
steps = 0
samples, losses = [], []
n_images = 25
print_every = 20
show_every = 100
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for e in range(epochs):
for batch_images in get_batches(batch_size):
# TODO: Train Model
steps += 1
batch_images *= 2.0
# Sample random "noise vector" for generator
z_sample = np.random.uniform(-1, 1, (batch_size, z_dim))
# Run optimizers
_ = sess.run(d_opt, feed_dict={real_input_img: batch_images, \
z_input: z_sample, \
lr: learning_rate})
_ = sess.run(g_opt, feed_dict={z_input: z_sample, \
lr: learning_rate})
if steps % print_every == 0:
# At the end of each epoch, get the losses and print them out
train_loss_d = d_loss.eval({z_input: z_sample, \
real_input_img: batch_images})
train_loss_g = g_loss.eval({z_input: z_sample})
print("Epoch {}/{}...".format(e+1, epochs),
"Discriminator Loss: {:.4f}...".format(train_loss_d),
"Generator Loss: {:.4f}".format(train_loss_g))
# Save losses to view after training
losses.append((train_loss_d, train_loss_g))
# Showing the generator image output for every = show_every step
if steps % show_every == 0:
show_generator_output(sess, n_images, z_input, img_channels, data_image_mode)
return losses
Test your GANs architecture on MNIST. After 2 epochs, the GANs should be able to generate images that look like handwritten digits. Make sure the loss of the generator is lower than the loss of the discriminator or close to 0.
The hyperparameters chosen are correct. You can further improve the quality of the generated image by experimenting with the parameters and the tips I provided in discriminator, generator and model loss. Below are a few extra tips on choosing the hyperparameters for starters...
Tips: 1) Try using different values of learning rate between 0.0002 and 0.0008, this DCGAN architectural structure remains stable within that range.
2) Experiment with different values of beta1 between 0.2 and 0.5 and compare your results. Here's a good post explaining the importance of beta values and which value might be empirically better. http://ruder.io/optimizing-gradient-descent/index.html#adam.
3) An important point to note is, batch size and learning rate are linked. If the batch size is too small then the gradients will become more unstable and would need to reduce the learning rate and vice versa. Start point for experimenting on batch size would be somewhere between 16 to 32.
Extra: You can also go through Population based training of neural networks, https://deepmind.com/blog/population-based-training-neural-networks/ it is a new method for training neural networks which allows an experimenter to quickly choose the best set of hyperparameters and model for the task.
batch_size = 32 # Reviewer#1 Start point for experimenting on batch size would be somewhere between 16 to 32.
z_dim = 128
learning_rate = 0.0002
beta1 = 0.5 # AdamOptimizer.  It will take around 20 minutes on the average GPU to run one epoch. You can run the whole epoch or stop when it starts to generate realistic faces.
If you want to generate varied face shapes, experiment with the value of z_dim (probably in the range 128 - 256).
"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
epochs = 1
celeba_dataset = helper.Dataset('celeba', glob(os.path.join(data_dir, 'img_align_celeba/*.jpg')))
with tf.Graph().as_default():
losses=train(epochs, batch_size, z_dim, learning_rate, beta1, celeba_dataset.get_batches,
celeba_dataset.shape, celeba_dataset.image_mode)
fig, ax = plt.subplots()
losses = np.array(losses)
plt.plot(losses.T[0], color='b', label='Discriminator loss')
plt.plot(losses.T[1], color='r', label='Generator loss')
plt.title("Training Losses")
plt.legend()
fig, ax = plt.subplots()
losses = np.array(losses)
plt.plot(losses.T[0], color='b', label='Discriminator loss')
plt.plot(losses.T[1], color='r', label='Generator loss')
plt.title("Training Losses")
ax.set_ylim(0,2.5)
plt.legend()
celeba_dataset = helper.Dataset('celeba', glob(os.path.join(data_dir, 'img_align_celeba/*.jpg')))
celeba_dataset.shape
When submitting this project, make sure to run all the cells before saving the notebook. Save the notebook file as "dlnd_face_generation.ipynb" and save it as a HTML file under "File" -> "Download as". Include the "helper.py" and "problem_unittests.py" files in your submission.


Alyssa Page
Home
Portfolio
Resume
Blog
Contact
Blog Title
Date /
# comments
Author
caption
Lorem ipsum
Lorem ipsum


I looked into the "Pomodoro Technique" and also read about meditation and growth vs. fixed mindsets.
I found the pomodoro technique interesting, this could be a good way for me to schedule breaks rather than just taking random ones. I often find myself getting frustrated with something if I dont take more regular breaks so this could be a good strategy to impliment. Also the fixed vs growth mindset blog was facinating, I think I was able to develop into a growth mindset during my unversity studies through developing good work habits.
I think the meditation technique would suit me best, I need to unwind completely and clear my mind otherwise during breaks I would keep thinking about the work I just completed or have yet to attempt.
I think I will try to implement the Pomodoro technique and see how I go with more regular breaks but I feel like meditation will be most beneficial to my learning style.


You can add controls to a list that are hidden until you drag the row open. You can also tell the controls to open on row click.


Before Change
wrap_patch(SparkSession, "__init__", __init__)
active_session = _get_active_spark_session()
if active_session is not None:
// We know SparkContext exists here already, so get it
sc = SparkContext.getOrCreate()
_listen_for_spark_activity(sc)
def _get_repl_id():
Get a unique REPL ID for a PythonSubscriber instance. This is used to distinguish between
REPLs in multitenant, REPL-aware environments where multiple Python processes may share the
After Change
def autolog():
Implementation of Spark datasource autologging
global _spark_table_info_listener
if _get_current_listener() is None:
active_session = _get_active_spark_session()
if active_session is None:
raise MlflowException(
"No active SparkContext found, refusing to enable Spark datasource "
"autologging. Please create a SparkSession e.g. via "
"SparkSession.builder.getOrCreate() (see API docs at "
"https://spark.apache.org/docs/latest/api/python/"
"pyspark.sql.html//pyspark.sql.SparkSession) "
"before attempting to enable autologging"
)
// We know SparkContext exists here already, so get it
sc = SparkContext.getOrCreate()
if _get_spark_major_version(sc) < 3:
raise MlflowException("Spark autologging unsupported for Spark versions < 3")
gw = active_session.sparkContext._gateway
params = gw.callback_server_parameters
callback_server_params = CallbackServerParameters(
address=params.address,
port=params.port,
daemonize=True,
daemonize_connections=True,
eager_load=params.eager_load,
ssl_context=params.ssl_context,
accept_timeout=params.accept_timeout,
read_timeout=params.read_timeout,
auth_token=params.auth_token,
)
gw.start_callback_server(callback_server_params)
event_publisher = _get_jvm_event_publisher()
try:
event_publisher.init(1)
_spark_table_info_listener = PythonSubscriber()
_spark_table_info_listener.register()
except Exception as e:
raise MlflowException(
"Exception while attempting to initialize JVM-side state for "
"Spark datasource autologging. Please ensure you have the "
"mlflow-spark JAR attached to your Spark session as described "
"in http://mlflow.org/docs/latest/tracking.html//"
"automatic-logging-from-spark-experimental. Exception:\n%s" % e
)
// Register context provider for Spark autologging
from mlflow.tracking.context.registry import _run_context_provider_registry
_run_context_provider_registry.register(SparkAutologgingContext)
def _get_repl_id():
Get a unique REPL ID for a PythonSubscriber instance. This is used to distinguish between
REPLs in multitenant, REPL-aware environments where multiple Python processes may share the


---
layout: post
title: SaaS APIs are Retro – You Know, Just Like EDI
date: '2009-11-26T08:06:04-08:00'
tags:
tumblr_url: http://alexhwilliams.tumblr.com/post/258360098/saas-apis-are-retro-you-know-just-like-edi
---
SaaS APIs are Retro – You Know, Just Like EDI


We talked in a previous post about Microsoft Pex and how it choose values to explore your code through symbolically executing it and getting all its paths. A code path is the represented by all the conditions that have to be satisfied in order to make the code execution go to this path. Your code conditional statements will lead to different paths according to different input values. Test cases generated by Pex represents the code behavior for specific input values that lead to specific code path.
Within the parameterized unit test You can use the method GetPathConditionString of the PexSymbolicValue class to obtain a textual representation of the current path condition, a predicate (condition) that characterizes an execution path (below, column with title Condition) .
Methods ToRawString and GetRawPathConditionString of the PexSymbolicValue class return expressions representing symbolic values and the path condition, formatted as S-expressions.
As we know, Pex uses the Z3 SMT solver behind the scenes. If you want to get the path conditions before being passed to Z3, do the following:
Now, Pex will create *.z3 files in subdirectories in the z3_logdir you specified in step 1. These files are in Z3 native format and can be later passed to Z3. For more information about this format, refer to Z3 online documentation.
In future posts we will talk more about the Z3 native format and what we can do with it.


{% extends 'layouts/base.html' %} {% import 'macros/form_macros.html' as f %} {% block content %} {% set flashes = { 'success': get_flashed_messages(category_filter=['form-success']) } %}
As the independent financial watchdog for the City of Philadelphia, it is the mission of the City Controller to promote the effective and efficient operation of Philadelphia government by identifying cost savings, recommending best practices and modernization, and exposing fraud and mismanagement. Under City Controller Rebecca Rhynhart, the office is committed to transparency, accountability and good government.


A web map to help find peaks in the Alps.
Version
Leaflet
using esri-leaflet plugin
Version
API arcgis for JS
Point clustering has been implemented in this sample with a custom layer named extras.ClusterLayer.


Warming Stripes
A temperature anomaly indicates how much warmer or colder it is than normal for a particular place and time.
The visualisation below takes inspiration from the ones created by climate scientist Ed Hawkins. The data is taken from NASA.
Global Temperature Anomalies: 1880 - 2018
Hover over a stripe to see the year.


Element Selector
Markup
Test & Confirm
Found
0
Easy
Advanced
Title Options
Set
Content
Link Options
Set
Content
Image Options
Set
Content
Class Name
Title xPath
Link xPath
Image xPath
Test Web Scrape
Confirm and Save


Behaviours: gen_server.
Authors: Igor Kopestenski<EMAIL_ADDRESS>[web site: https://github.com/achlysproject/achlys/].
See also: Pmod_NAV .
The Pmod_NAV worker server. The general purpose of this worker is to gather and process sensor data from one of the 3 components available on the Pmod_NAV :
- Accelerometer => acc - Gyroscope => alt - Magnetometer => mag
Data can be retrieved as follows :
[Temperature] = pmod_nav:read(acc, [out_temp]).
Where acc is the component providing the data and [out_temp] is the list of registers that is read.task() = #{name => atom(), targets => task_targets(), execution_type => task_execution_type(), function => function()}
task_execution_type() = bitstring()
task_targets() = [node()] | bitstring()
| code_change/3 | |
| get_crdt/1 | Returns the current view of the contents in the temperatures Lasp variable. |
| get_table/1 | Returns the current view of the contents in the temperatures Lasp variable. |
| handle_continue/2 | |
| handle_info/2 | fetches the values from the pmod_nav sensor
and stores them in the corresponding ETS table. |
| run/0 | declares a Lasp variable for temperature aggregates and sets triggers for handlers after intervals have expired. |
| start_link/0 | starts the pmod_nav process using the configuration given in the sys.config file. |
| terminate/2 |
code_change(OldVsn, State, Extra) -> any()
get_crdt(Name::atom()) -> list()
Returns the current view of the contents in the temperatures Lasp variable. -spec get_crdt() -> crdt().
get_table(Name::atom()) -> ok
Returns the current view of the contents in the temperatures Lasp variable.
handle_continue(Continue, State) -> any()
handle_info(Info, State) -> any()
fetches the values from the pmod_nav
sensor
and stores them in the corresponding ETS table. It is paired with
the erlang:monotonic_time/0
to guarantee unique keys.
The first call is used to redirect towards implemented handlers
e.g. temperature, pressure.
For large amounts of sensor data
e.g. accumulated for a long time and being larger than
the maximum available memory, an alternative would be to use the
dets
storage module. They can also be combined as described
below.
From OTP documentation :
Dets tables provide efficient file-based Erlang term storage. They are used together with ETS tables when fast access needs to be complemented with persistency.run() -> ok
declares a Lasp variable for temperature aggregates and sets triggers for handlers after intervals have expired.
start_link() -> {ok, pid()} | ignore | {error, {already_started, pid()} | term()}
starts the pmod_nav process using the configuration given in the sys.config file.
terminate(Reason, State) -> any()
Generated by EDoc


# Copyright (c) 2012-2019 by the GalSim developers team on GitHub
# https://github.com/GalSim-developers
#
# This file is part of GalSim: The modular galaxy image simulation toolkit.
# https://github.com/GalSim-developers/GalSim
#
# GalSim is free software: redistribution and use in source and binary forms,
# with or without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions, and the disclaimer given in the accompanying LICENSE
# file.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the disclaimer given in the documentation
# and/or other materials provided with the distribution.
#
from past.builtins import basestring
import numpy as np
import os
"""
@file wfirst_psfs.py
Part of the WFIRST module. This file includes routines needed to define a realistic PSF for WFIRST.
"""
# Define a default set of bandpasses for which this routine works.
default_bandpass_list = ['J129', 'F184', 'W149', 'Y106', 'Z087', 'H158']
# Prefix for files containing information about Zernikes for each SCA for cycle 7.
zemax_filepref = "WFIRST_Phase-A_SRR_WFC_Zernike_and_Field_Data_170727"
zemax_filesuff = '.txt'
zemax_wavelength = 1293. #nm
[docs]def getPSF(SCA, bandpass,
SCA_pos=None, approximate_struts=False, n_waves=None, extra_aberrations=None,
logger=None, wavelength=None, high_accuracy=False, gsparams=None):
"""Get a single PSF for WFIRST observations.
The user must provide the SCA and bandpass; the latter is used when setting up the pupil
plane configuration and when interpolating chromatic information, if requested.
This routine carries out linear interpolation of the aberrations within a given SCA, based on
the WFIRST Cycle 7 specification of the aberrations as a function of focal plane position.
The default is to do the calculations using the full specification of the WFIRST pupil plane,
which is a costly calculation in terms of memory. For this, we use the provided pupil plane for
long- and short-wavelength bands for Cycle 7 (the list of bands associated with each pupil plane
is stored in ``galsim.wfirst.longwave_bands`` and ``galsim.wfirst.shortwave_bands``).
To avoid using the full pupil plane configuration, use the optional keyword
``approximate_struts``. In this case, the pupil plane will have the correct obscuration and
number of struts, but the struts will be purely radial and evenly spaced instead of the true
configuration. The simplicity of this arrangement leads to a much faster calculation, and
somewhat simplifies the configuration of the diffraction spikes. Also note that currently the
orientation of the struts is fixed, rather than rotating depending on the orientation of the
focal plane. Rotation of the PSF can easily be affected by the user via::
psf = galsim.wfirst.getPSF(...).rotate(angle)
which will rotate the entire PSF (including the diffraction spikes and any other features).
The calculation takes advantage of the fact that the diffraction limit and aberrations have a
simple, understood wavelength-dependence. (The WFIRST project webpage for Cycle 7 does in fact
provide aberrations as a function of wavelength, but the deviation from the expected chromatic
dependence is sub-percent so we neglect it here.) For reference, the script used to parse the
Zernikes given on the webpage and create the files in the GalSim repository can be found in
``devel/external/parse_wfirst_zernikes_1217.py``. The resulting chromatic object can be used to
draw into any of the WFIRST bandpasses, though the pupil plane configuration will only be
correct for those bands in the same range (i.e., long- or short-wavelength bands).
For applications that require very high accuracy in the modeling of the PSF, with very limited
aliasing, the ``high_accuracy`` option can be set to True. When using this option, the MTF has
a value below 1e-4 for all wavenumbers above the band limit when using
``approximate_struts=True``, or below 3e-4 when using ``approximate_struts=False``. In
contrast, when ``high_accuracy=False`` (the default), there are some bumps in the MTF above the
band limit that reach an amplitude of ~1e-2.
By default, no additional aberrations are included above the basic design. However, users can
provide an optional keyword ``extra_aberrations`` that will be included on top of those that are
part of the design. This should be in the same format as for the ChromaticOpticalPSF class,
with units of waves at the fiducial wavelength, 1293 nm. Currently, only aberrations up to order
22 (Noll convention) are simulated. For WFIRST, the current tolerance for additional
aberrations is a total of 90 nanometers RMS:
http://wfirst.gsfc.nasa.gov/science/sdt_public/wps/references/instrument/README_AFTA_C5_WFC_Zernike_and_Field_Data.pdf
distributed largely among coma, astigmatism, trefoil, and spherical aberrations (NOT defocus).
This information might serve as a guide for reasonable ``extra_aberrations`` inputs.
Jitter and charge diffusion are, by default, not included. Users who wish to include these can
find some guidelines for typical length scales of the Gaussians that can represent these
effects, and convolve the ChromaticOpticalPSF with appropriate achromatic Gaussians.
The PSFs are always defined assuming the user will specify length scales in arcsec.
Users may find they do not have to call `getPSF` for all objects in their simulations; for a
given SCA and position within the SCA, and a given pupil plane configuration and wavelength
information, it should be possible to reuse the PSFs.
Parameters:
SCA: Single value specifying the SCA for which the PSF should be
loaded.
bandpass: Single string specifying the bandpass to use when defining the
pupil plane configuration and/or interpolation of chromatic PSFs.
If ``approximate_struts`` is True (which means we do not use a
realistic pupil plane configuration) and ``n_waves`` is None (no
interpolation of chromatic PSFs) then 'bandpass' can be None. It
is also possible to pass a string 'long' or 'short' for this
argument; in that case, the correct pupil plane configuration
will be used for long- or short-wavelength bands as defined using
``galsm.wfirst.longwave_bands`` and
``galsim.wfirst.shortwave_bands``, respectively (but no
interpolation can be used, since it is defined using the extent
of the chosen bandpass).
SCA_pos: Single galsim.PositionD indicating the position within the SCA
for which the PSF should be created. If None, the exact center of
the SCA is chosen. [default: None]
approximate_struts: Should the routine use an approximate representation of the pupil
plane, with 6 equally-spaced radial struts, instead of the exact
representation of the pupil plane? Setting this parameter to
True will lead to faster calculations, with a slightly less
realistic PSFs. [default: False]
n_waves: Number of wavelengths to use for setting up interpolation of the
chromatic PSF objects, which can lead to much faster image
rendering. If None, then no interpolation is used. Note that
users who want to interpolate can always set up the interpolation
later on even if they do not do so when calling `getPSF`.
[default: None]
extra_aberrations: Array of extra aberrations to include in the PSF model, on top of
those that are part of the WFIRST design. These should be
provided in units of waves at the fiducial wavelength of 1293 nm,
as an array of length 23 with entries 4 through 22 corresponding
to defocus through the 22nd Zernike in the Noll convention.
[default: None]
logger: A logger object for output of progress statements if the user
wants them. [default: None]
wavelength: An option to get an achromatic PSF for a single wavelength, for
users who do not care about chromaticity of the PSF. If None,
then the fully chromatic PSF is returned. Alternatively the user
should supply either (a) a wavelength in nanometers, and they
will get achromatic OpticalPSF objects for that wavelength, or
(b) a bandpass object, in which case they will get achromatic
OpticalPSF objects defined at the effective wavelength of that
bandpass. [default: False]
high_accuracy: If True, make higher-fidelity representations of the PSF in
Fourier space, to minimize aliasing (see plots on
https://github.com/GalSim-developers/GalSim/issues/661 for more
details). This setting is more expensive in terms of time and
RAM, and may not be necessary for many applications.
[default: False]
gsparams: An optional GSParams argument. See the docstring for GSParams
for details. [default: None]
Returns:
A single PSF object (either a ChromaticOpticalPSF or an OpticalPSF depending on the
inputs).
"""
from .. import PositionD
from .. import GalSimValueError
from . import n_pix, longwave_bands, shortwave_bands
# Deal with inputs:
# SCA_pos: if None, then all should just be center of the SCA.
if SCA_pos is None:
SCA_pos = PositionD(n_pix/2, n_pix/2)
# Parse the bandpasses to see which pupil plane image is needed, if approximate_struts is False
# (otherwise just say None).
pupil_plane_type = None
if not approximate_struts:
if bandpass in longwave_bands or bandpass=='long':
pupil_plane_type = 'long'
elif bandpass in shortwave_bands or bandpass=='short':
pupil_plane_type = 'short'
else:
raise GalSimValueError("Bandpass not a valid WFIRST bandpass or 'short'/'long'.",
bandpass, default_bandpass_list)
else:
# Sanity checking:
# If we need to use bandpass info, require that it be one of the defaults.
# If we do not need to use bandpass info, allow it to be None.
if n_waves is not None:
if bandpass not in default_bandpass_list+['short','long']:
raise GalSimValueError("Bandpass not a valid WFIRST bandpass or 'short'/'long'.",
bandpass, default_bandpass_list)
else:
if bandpass not in default_bandpass_list+['short','long'] and bandpass is not None:
raise GalSimValueError("Bandpass not a valid WFIRST bandpass or 'short'/'long'.",
bandpass, default_bandpass_list)
# If bandpass is 'short'/'long', then make sure that interpolation is not called for, since that
# requires an actual bandpass.
if bandpass in ['short','long'] and n_waves is not None:
raise GalSimValueError("Cannot use bandpass='short'/'long' with interpolation.", bandpass)
# Now call _get_single_PSF().
psf = _get_single_PSF(SCA, bandpass, SCA_pos, approximate_struts,
n_waves, extra_aberrations, logger, wavelength,
high_accuracy, pupil_plane_type, gsparams)
return psf
def _get_single_PSF(SCA, bandpass, SCA_pos, approximate_struts,
n_waves, extra_aberrations, logger, wavelength,
high_accuracy, pupil_plane_type, gsparams):
"""Routine for making a single PSF. This gets called by `getPSF` after it parses all the
options that were passed in. Users will not directly interact with this routine.
"""
from .. import fits
from .. import Image, OpticalPSF, ChromaticOpticalPSF
from . import pupil_plane_file_longwave, pupil_plane_file_shortwave, pupil_plane_scale
from . import diameter, obscuration
from .wfirst_bandpass import getBandpasses
# Deal with some accuracy settings.
if high_accuracy:
if approximate_struts:
oversampling = 3.5
else:
oversampling = 2.0
# In this case, we need to pad the edges of the pupil plane image, so we cannot just use
# the stored file.
if pupil_plane_type == 'long':
tmp_pupil_plane_im = fits.read(pupil_plane_file_longwave)
else:
tmp_pupil_plane_im = fits.read(pupil_plane_file_shortwave)
old_bounds = tmp_pupil_plane_im.bounds
new_bounds = old_bounds.withBorder((old_bounds.xmax+1-old_bounds.xmin)/2)
pupil_plane_im = Image(bounds=new_bounds)
pupil_plane_im[old_bounds] = tmp_pupil_plane_im
pupil_plane_scale = pupil_plane_scale
else:
if approximate_struts:
oversampling = 1.5
else:
oversampling = 1.2
if pupil_plane_type == 'long':
pupil_plane_im = pupil_plane_file_longwave
else:
pupil_plane_im = pupil_plane_file_shortwave
pupil_plane_scale = pupil_plane_scale
# Start reading in the aberrations for that SCA
if logger: logger.debug('Beginning to get the PSF aberrations for SCA %d.'%SCA)
aberrations, x_pos, y_pos = _read_aberrations(SCA)
# Do bilinear interpolation, unless we're exactly at the center (default).
use_aberrations = _interp_aberrations_bilinear(aberrations, x_pos, y_pos, SCA_pos)
if extra_aberrations is not None:
use_aberrations += extra_aberrations
# We don't want to use piston, tip, or tilt aberrations. The former doesn't affect the
# appearance of the PSF, and the latter cause centroid shifts. So, we set the first 4
# numbers (corresponding to a place-holder, piston, tip, and tilt) to zero.
use_aberrations[0:4] = 0.
# Now set up the PSF, including the option to simplify the pupil plane.
if wavelength is None:
if approximate_struts:
PSF = ChromaticOpticalPSF(lam=zemax_wavelength,
diam=diameter, aberrations=use_aberrations,
obscuration=obscuration, nstruts=6,
oversampling=oversampling, gsparams=gsparams)
else:
PSF = ChromaticOpticalPSF(lam=zemax_wavelength,
diam=diameter, aberrations=use_aberrations,
obscuration=obscuration,
pupil_plane_im=pupil_plane_im,
pupil_plane_scale=pupil_plane_scale,
oversampling=oversampling, pad_factor=2., gsparams=gsparams)
if n_waves is not None:
# To decide the range of wavelengths to use, check the bandpass.
bp_dict = getBandpasses()
bp = bp_dict[bandpass]
PSF = PSF.interpolate(waves=np.linspace(bp.blue_limit, bp.red_limit, n_waves),
oversample_fac=1.5)
else:
if not isinstance(wavelength, float):
raise TypeError("wavelength should either be a Bandpass, float, or None.")
tmp_aberrations = use_aberrations * zemax_wavelength / wavelength
if approximate_struts:
PSF = OpticalPSF(lam=wavelength, diam=diameter,
aberrations=tmp_aberrations,
obscuration=obscuration, nstruts=6,
oversampling=oversampling, gsparams=gsparams)
else:
PSF = OpticalPSF(lam=wavelength, diam=diameter,
aberrations=tmp_aberrations,
obscuration=obscuration,
pupil_plane_im=pupil_plane_im,
pupil_plane_scale=pupil_plane_scale,
oversampling=oversampling, pad_factor=2., gsparams=gsparams)
return PSF
def _read_aberrations(SCA):
"""
This is a helper routine that reads in aberrations for a particular SCA and wavelength (given as
galsim.wfirst.wfirst_psfs.zemax_wavelength) from stored files, and returns them along with the
field positions.
Parameters:
SCA: The identifier for the SCA, from 1-18.
Returns:
NumPy arrays containing the aberrations, and x and y field positions.
"""
from .. import meta_data
from . import pixel_scale, n_pix
# Construct filename.
sca_str = '_%02d'%SCA
infile = os.path.join(meta_data.share_dir,
zemax_filepref + sca_str + zemax_filesuff)
# Read in data.
dat = np.loadtxt(infile)
# It actually has 5 field positions, not just 1, to allow us to make position-dependent PSFs
# within an SCA eventually. Put it in the required format: an array of length (5 field
# positions, 23 Zernikes), with the first entry empty (Zernike polynomials are 1-indexed so we
# use entries 1-22). The units are waves.
aberrations = np.zeros((5,23))
aberrations[:,1:] = dat[:,5:]
# Also get the field position. The file gives it in arcsec with respect to the center, but we
# want it in pixels with respect to the corner.
x_sca_pos = dat[:,1]/pixel_scale + n_pix/2
y_sca_pos = dat[:,2]/pixel_scale + n_pix/2
return aberrations, x_sca_pos, y_sca_pos
def _interp_aberrations_bilinear(aberrations, x_pos, y_pos, SCA_pos):
"""
This is a helper routine to do bilinear interpolation of aberrations defined at 4 field
positions: the four corners. Note that we also have aberrations at the center position,
but these are generally quite close (within a few percent) of what would come from this bilinear
interpolation. So for simplicity, we just do the bilinear interpolation.
"""
min_x = np.min(x_pos)
min_y = np.min(y_pos)
max_x = np.max(x_pos)
max_y = np.max(y_pos)
x_frac = (SCA_pos.x - min_x) / (max_x - min_x)
y_frac = (SCA_pos.y - min_y) / (max_y - min_y)
lower_x_lower_y_ab = aberrations[(x_pos==min_x) & (y_pos==min_y), :]
lower_x_upper_y_ab = aberrations[(x_pos==min_x) & (y_pos==max_y), :]
upper_x_lower_y_ab = aberrations[(x_pos==max_x) & (y_pos==min_y), :]
upper_x_upper_y_ab = aberrations[(x_pos==max_x) & (y_pos==max_y), :]
interp_ab = (1.0-x_frac)*(1.0-y_frac)*lower_x_lower_y_ab + \
(1.0-x_frac)*y_frac*lower_x_upper_y_ab + \
x_frac*(1.0-y_frac)*upper_x_lower_y_ab + \
x_frac*y_frac*upper_x_upper_y_ab
return interp_ab.flatten()