Is there a programmatic way to elaborate the 'half-winds' in raku? - raku

I have this working:
my %pnt = %( cardinal => <N E S W>,
ordinal => <N NE E SE S SW W NW>,
half-winds => <N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW>,
);
and I thought it may be possible to create the half-winds array programatically.
However, my pathetic attempts seem to be more long-winded:
my #cards = <N E S W>;
my #odds = <NE SE SW NW>;
my #ords = ( #cards Z #odds ).flat;
my #mids = ( ( #cards Z~ #odds ) Z ( #cards.rotate(1) Z~ #odds ) ).flat;
my #halfs = ( #ords Z #mids ).flat;
say #cards; #[N E S W]
say #ords; #[N NE E SE S SW W NW]
say #mids; #[NNE ENE ESE SSE SSW WSW WNW NNW]
say #halfs; #[N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW]
Is there a better / more concise alternative?
viz. https://en.wikipedia.org/wiki/Points_of_the_compass
-- bonus points for quarter winds!

FWIW, in this case I would go for readability of the code, which I think your original code is the most readable you can get.
But if you want to get algorithmic, I would work off of the #halfs using an array slice using a sequence:
my #halfs = <N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW>;
my #mids = #halfs[1,3...*];
my #ords = #halfs[0,2...*];
my #cards = #halfs[0,4...*];
say #cards; #[N E S W]
say #ords; #[N NE E SE S SW W NW]
say #mids; #[NNE ENE ESE SSE SSW WSW WNW NNW]
say #halfs; #[N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW]
Leaving the quarter winds as an exercise for the reader, but basically that would be using the quarter winds as the base, and work off of that in a similar fashion.

Assuming we have the principal winds to hand:
my #principals = <N NE E SE S SW W NW>;
Then we can follow the definition a la Wikipedia:
The name of each half-wind is constructed by combining the names of the principal winds to either side
This means we want to take principal winds in overlapping pairs, which rotor could do fairly neatly:
say #principals.rotor(2 => -1);
Which gives us:
((N NE) (NE E) (E SE) (SE S) (S SW) (SW W) (W NW))
Which sadly has an off by one problem, because it misses (NW, N). OK, we can include N again, at the cost of a little beauty:
say #principals[*,0].flat.rotor(2 => -1)
Giving:
((N NE) (NE E) (E SE) (SE S) (S SW) (SW W) (W NW) (NW N))
If we join them:
say #principals[*,0].flat.rotor(2 => -1).map(*.join)
We get:
(NNE NEE ESE SES SSW SWW WNW NWN)
Which isn't right yet, because the next thing the article says is:
with the cardinal wind coming first and the intercardinal wind second
The cardinal winds are the one character ones, which can be fixed with a sort:
say #principals[*,0].flat.rotor(2 => -1).map(*.sort(*.chars).join)
Which finally looks about right:
(NNE ENE ESE SSE SSW WSW WNW NNW)
Except that the half winds are these placed between the principal winds, which can be solved with zipping them and flattening the result:
say flat #principals Z #principals[*,0].flat.rotor(2 => -1).map(*.sort(*.chars).join)
Finally giving us:
(N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW)
If we want it shorter, the duplicate mention of #principals can go away with a given:
say flat $_ Z .[*,0].flat.rotor(2 => -1).map(*.sort(*.chars).join) given #principals
The .join can just become list stringification:
say flat $_ Z .[*,0].flat.rotor(2 => -1).map(~*.sort(*.chars)) given #principals:
And the inner flattening can be replaced with a use of the | slip operator:
say flat $_ Z (|$_,.[0]).rotor(2 => -1).map(~*.sort(*.chars)) given #principals;
Which is still longer than just listing them out in the first place, which is what I'd probably do, but it was fun trying to beat that anyway...

TL;DR For no good reason, this nanswer goes after just the bonus points.
my \quadrant = <N NbE NNE NEbN NE NEbE ENE EbN E>;
my #quarts = |quadrant,
|quadrant.reverse.map( *.trans: 'NE'=>'SE'),
|quadrant\ .map( *.trans: 'NE'=>'SW'),
|quadrant.reverse.map( *.trans: 'NE'=>'NW');
#quarts .=unique .batch(8) .map: *.say;
# (N NbE NNE NEbN NE NEbE ENE EbN)
# (E EbS ESE SEbE SE SEbS SSE SbE)
# (S SbW SSW SWbS SW SWbW WSW WbS)
# (W WbN WNW NWbW NW NWbN NNW NbW)
Perhaps I get some bonus points for explaining the above:
Prefix | "slips" the value on its right; the net effect of using it on each of the four quadrants is that the resulting list contains 32 elements rather than 4.
.reverse reverses a list, corresponding to the way the wind points notation reverses between NE/SW and SE/NW.
.map(...) applies a function or lambda to each element in its invocant list.
*.trans: 'NE'=>'SE' is a lambda that transliterates each N character to S and each E to E. The redundant E is there for the first transliteration because it felt a bit clearer than dropping it; I could also have added *.trans: 'NE'=>'NE' for the first quadrant but that felt less clear. NB. I use trans because it's succinct, but subst can always do the same stuff a trans does, even if it takes a lot more lines, and in Rakudo 2020.12 subst is around 5x-10x faster for almost all cases.
The \ in |quadrant\ .map... is an "unspace", a way to indicate to the compiler that it should parse the code as if the slash and whitespace wasn't there. Without it the | takes just quadrant as its operand. The unspace makes it take the whole quadrant.map( *.trans: 'NE'=>'SW') expression as its operand. (In my original version of this answer my code was wrong because I lined up the .map without the unspace.)
The .= in .=unique applies a method and then assigns the result back to its invocant, mutating it in place.
unique removes any elements of a list that are repeated. Without it there would be repeats of the four cardinal points (<N E S W>).
.batch(8) batches the points back up into groups of 8 corresponding to the four quadrants ready for pretty printing.
Bonus points
The rest of this answer is merely justification of my shameless bonus point scavenging.
From your Q:
bonus points for quarter winds!
From Liz's answer:
Leaving the quarter winds as an exercise for the reader
The 32 points of "quarter winds"
As Liz notes, a simple superset solution that includes hers and quarter winds would just entail:
using the quarter winds as the base, and work off of that in a similar fashion
In other words, doing the quarter winds bonus exercise could just entail the trivial to write, easily comprehensible, and sensibly maintainable thing, namely writing out the 32 points in the quarter wind list just as Liz did for the 16 points of the half winds. (But then I'd get no bonus points.)
Extending this to what are confusingly called half points (64 points) and quarter points (128), the sensible thing to do for them would also be to just write them out by hand, complete with Unicode fraction characters, which any PL that supports Unicode source code and a "quote words" like feature (eg Raku) makes trivial. I'm pretty sure anyone reading your code will thank you for keeping it simple if you do that.
But I wanted to have some fun, and stick with your programmatic theme, and try scavenge some "bonus points". Hence my code at the start.
I leave creation of even more unnecessarily complex cryptic cumbersome computational constructions of half/quarter points (complete with support for aliases and the differing conventions used around the world for these finer compasses) as an exercise for readers...

ended up with this ...
my #all-points = <N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW>;
my %pnt-count = %( cardinal => 4, ordinal => 8, half-winds => 16 );
my $iter = %pnt-count{$dec};
my $step = 360 / $iter;
my $rvc = ( $.value + $step/2 ) % 360; #rotate value clockwise by half-step
for 0..^$iter -> $i {
my $port = $step * $i;
my $star = $step * ($i+1);
if $port < $rvc <= $star { #using slice to sample #all-points
return #all-points[0,(16/$iter)...*][$i]
}
}

I tried starting with the Cardinal winds (NESW), but soon discovered that it was better to simply start with abcd, since regarding the 8-wind compass rose (per Wikipedia):
-- In Bulgarian, Catalan, Czech, Danish, Dutch, English, Esperanto, French, Galician, German, Greek, Hungarian, Ido, Italian, Japanese
(usually), Macedonian, Norwegian (both Bokmal and Nynorsk), Polish,
Portuguese, Romansch, Russian, Serbian, Croatian, Spanish, Swedish and
Welsh the part meaning north or south precedes the part meaning east
or west.
-- In Chinese, Gaelic and less commonly in Japanese, the part meaning east or west precedes the other.
First create a 16-point rose:
my #cardinal = <a b c d>;
my #intercard = ((#cardinal Z #cardinal[1..*-1,0].flat)>>.join); #between cardinal
my #pre_half = ((#cardinal Z #intercard)>>.join).flat;
my #post_half = (#intercard Z #cardinal[1..*-1,0].flat)>>.join;
my #half = ((#cardinal Z #intercard).flat Z ([Z] #pre_half, #post_half).flat).flat;
say #half;
[a aab ab abb b bbc bc bcc c ccd cd cdd d dda da daa]
Now transform to the proper letters (NESW). In the 16-wind compass rose, rearrange 3-letter winds with <same> letters at the end to move the last letter to the first, and finally re-order winds to English ordering (North/South precedes East/West), with intercardinal winds placed last, e.g. S-SE not SE-S:
#half.=map(*.trans("abcd" => "NESW"));
#half.=map({ S:g/ <((NE|ES|SW|WN)<same>(.))>$ /$1$0/});
#half.=map(*.subst(:g, "ES","SE"));
#half.=map(*.subst(:g, "WN","NW"));
say #half;
[N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW]
(...broken into two steps, just in case #p6steve wants to localize his code for Chinese, Gaelic and Japanese speakers).
Note: Once you've generated the 16-point ("half-wind") Compass rose, it's trivial to grep out the 8-point ("ordinal") Compass rose:
#half[(0..15).grep(not * % 2)].put;
N NE E SE S SW W NW
HTH.
https://en.m.wikipedia.org/wiki/Compass_rose#/media/File%3ABrosen_windrose.svg

Related

Confusing Labels for Function Generators and Oscilloscopes in Tinkercad

In Tinkercad, amplitude definition for Function Generators and scale definition for Oscilloscopes are quite confusing. Here is an ss from Tinkercad's function generator:
On the device 6.20 V is represented as peak-to-peak voltage, look at the red-lines I've marked. But on the panel right-hand-side, we input it as the amplitude, look at the green line I've marked. Which one is true?
And I cannot deduce the answer using an oscilloscope, because there is not enough info about oscilloscope. (At least, I couldn't find enough info.) Here is the input signal from the function generator above:
Answer is not obvious, because the meaning of 10 V placed on y_axis is ambiguous. Is it +/- 10 V as in 20 V in total, i.e. the voltage-per-division is 2 V (first explanation)? Or, is it +/- 5 V as in 10 V in total, i.e. voltage-per-division is 1 V (second explanation)? In some Youtube lectures the explanation is first one. But, I'm not quite sure. Because, if 6.2 V is amplitude and voltage-per-division is 2 V, then this is noncontradictory. But if 6.2 V is peak-to-peak voltage and voltage-per-division is 1 V, then this, too, is noncontradictory. Again, which one is true?
And also, while studying, I've realise that a real life experiment indicates that the second explanation should be true. Let me explain the experiment step by step.
Theory: Full Wave Rectifier Circuits
Assume we apply V_in as the amplitude, the peak-peak voltage is, V_peaktopeak = 2 * V_in. And for output signal we have,
V_out = (V_in - n * V_diode) * R_L / (R_L + r_d),
where n is the number of diode in conduction, V_diode is bias of a diode and R_L is load resistor. Load resistor is choosen big enough so that R_L >> r_d and we get,
V_out = V_in - n * V_diode.
In a real experiment r_d is in between 1 \ohm and 25 \ohm, and we choose R_L on the order of kilo \ohm. Therefore, we can ignore R_L / (R_L + r_d) part, safely.
And for DC voltage corresponding to the output signal we have,
V_DC = 2 * V_out / \pi = 0.637 * V_out.
Sheme of Circuit in an Experiment
Here is circuit scheme,
As you may see, for positive half-periode only two of four diode is in conduction. And for negative half-periode, the other two is in conduction. Thus n is 2 for this circuit. Let's construct this experiment on Tinkercad. I didn't use breadboard to show more similarity between the scheme of circuit and the circuit built in Tinkercad.
Scenerio #1 - Theoretical Expectations
Let's assume 6.2 V to be the amplitude. Then, V_in=6.2 V. And V_peaktopeak is 12.4 V. As output signal we calculate,
V_out = V_in - n * V_diode = 6.2 V - 2 * 0.7 V = 4.8 V.
And for DC equivalent we theoretically get,
V_DC = 0.637 * V_out = 3.06 V.
But in multimeter, we see 1.06 V. This indicates nearly %60 percantage error.
Scenerio #2 - Theoretical Expectations
Let's assume 6.2 V to be the peak-to-peak voltage. Then, V_in=3.1 V. And V_peaktopeak is 6.2 V. As output signal we calculate,
V_out = V_in - n * V_diode = 3.1 V - 2 * 0.7 V = 1.7 V.
And for DC equivalent we theoretically get,
V_DC = 0.637 * V_out = 1.08 V.
And in multimeter, we see 1.06 V. There values are pretty close to each other.
Conclusion
Based on these results, we may conclude that 6.2 V is peak-to-peak voltage, scheme on the function generator is true, the tag "Amplitude" in the description of function generator is wrong and the y-scale of an oscilloscope represents the total voltage half of which is positive and the other half is negative.
BUT
I cannot be sure, and since I'll teach this material in my electronic laboratory class, I really need to be sure about this conclusion. Therefore, here I'm asking you about your opinions, conclusions or maybe other references that I've missed.
TinkerCAD refers to peak-to-peak voltage as amplitude for some reason. I believe the second explanation (+/- 5V, 10 V total) is correct, based on the x axis and frequency value.

Finding out Force from Torque and Distance

I have solid object that is spinning with a torque W, and I want to calculate the force F applied on a certain point that's D units away from the center of the object. All these values are represented in Vector3 format (x, y, z)
I know until now that W = D x F, where x is the cross product, so by expanding this I get:
Wx = Dy*Fz - Dz*Fy
Wy = Dz*Fx - Dx*Fz
Wz = Dx*Fy - Dy*Fx
So I have this equation, and I need to find (Fx, Fy, Fz), and I'm thinking of using the Simplex method to solve it.
Since the F vector can also have negative values, I split each F variable into 2 (F = G-H), so the new equation looks like this:
Wx = Dy*Gz - Dy*Hz - Dz*Gy + Dz*Hy
Wy = Dz*Gx - Dz*Hx - Dx*Gz + Dx*Hz
Wz = Dx*Gy - Dx*Hy - Dy*Gx + Dy*Hx
Next, I define the simplex table (we need <= inequalities, so I duplicate each equation and multiply it by -1.
Also, I define the objective function as: minimize (Gx - Hx + Gy - Hy + Gz - Hz).
The table looks like this:
Gx Hx Gy Hy Gz Hz <= RHS
============================================================
0 0 -Dz Dz Dy -Dy <= Wx = Gx
0 0 Dz -Dz -Dy Dy <= -Wx = Hx
Dz -Dz 0 0 Dx -Dx <= Wy = Gy
-Dz Dz 0 0 -Dx Dx <= -Wy = Hy
-Dy Dy Dx -Dx 0 0 <= Wz = Gz
Dy -Dy -Dx Dx 0 0 <= -Wz = Hz
============================================================
1 -1 1 -1 1 -1 0 = Z
The problem is that when I run it through an online solver I get Unbounded solution.
Can anyone please point me to what I'm doing wrong ?
Thanks in advance.
edit: I'm sure I messed up some signs somewhere (for example the Z should be defined as a max), but I'm sure I'm wrong when defining something more important.
There exists no unique solution to the problem as posed. You can only solve for the tangential projection of the force. This comes from the properties of the vector (cross) product - it is zero for collinear vectors and in particular for the vector product of a vector by itself. Therefore, if F is a solution of W = r x F, then F' = F + kr is also a solution for any k:
r x F' = r x (F + kr) = r x F + k (r x r) = r x F
since the r x r term is zero by the definition of vector product. Therefore, there is not a single solution but rather a whole linear space of vectors that are solutions.
If you restrict the solution to forces that have zero projection in the direction of r, then you could simply take the vector product of W and r:
W x r = (r x F) x r = -[r x (r x F)] = -[(r . F)r - (r . r)F] = |r|2F
with the first term of the expansion being zero because the projection of F onto r is zero (the dot denotes scalar (inner) product). Therefore:
F = (W x r) / |r|2
If you are also given the magnitude of F, i.e. |F|, then you can compute the radial component (if any) but there are still two possible solutions with radial components in opposing directions.
Quick dirty derivation...
Given D and F, you get W perpendicular to them. That's what a cross product does.
But you have W and D and need to find F. This is a bad assumption, but let's assume F was perpendicular to D. Call it Fp, since it's not necessarily the same as F. Ignoring magnitudes, WxD should give you the direction of Fp.
This ignoring magnitudes, so fix that with a little arithmetic. Starting with W=DxF applied to Fp:
mag(W) = mag(D)*mag(Fp) (ignoring geometry; using Fp perp to D)
mag(Fp) = mag(W)/mag(D)
Combining the cross product bit for direction with this stuff for magnitude,
Fp = WxD / mag(WxD) * mag(Fp)
Fp = WxD /mag(W) /mag(D) *mag(W) /mag(D)
= WxD / mag(D)^2.
Note that given any solution Fp to W=DxF, you can add any vector proportional to D to Fp to obtain another solution F. That is a totally free parameter to choose as you like.
Note also that if the torque applies to some sort of axle or object constrained to rotate about some axis, and F is applied to some oddball lever sticking out at a funny angle, then vector D points in some funny direction. You want to replace D with just the part perpendicular to the axle/axis, otherwise the "/mag(D)" part will be wrong.
So from your comment is clear that all rotations are spinning around center of gravity
in that case
F=M/r
F force [N]
M torque [N/m]
r scalar distance between center of rotation [m]
this way you know the scalar size of your Force
now you need the direction
it is perpendicular to rotation axis
and it is the tangent of the rotation in that point
dir=r x axis
F = F * dir / |dir|
bolds are vectors rest is scalar
x is cross product
dir is force direction
axis is rotation axis direction
now just change the direction according to rotation direction (signum of actual omega)
also depending on your coordinate system setup
so ether negate F or not
but this is in 3D free rotation very unprobable scenario
the object had to by symmetrical from mass point of view
or initial driving forces was applied in manner to achieve this
also beware that after first hit with any interaction Force this will not be true !!!
so if you want just to compute Force it generate on certain point if collision occurs is this fine
but immediately after this your spinning will change
and for non symmetric objects the spinning will be most likely off the center of gravity !!!
if your object will be disintegrated then you do not need to worry
if not then you have to apply rotation and movement dynamics
Rotation Dynamics
M=alpha*I
M torque [N/m]
alpha angular acceleration
I quadratic mass inertia for actual rotation axis [kg.m^2]
epislon''=omega'=alpha
' means derivation by time
omega angular speed
epsilon angle

BFS (Breadth First Search) Time complexity at every step

BFS(G,s)
1 for each vertex u ∈ G.V-{s}
2 u.color = WHITE
3 u.d = ∞
4 u.π = NIL
5 s.color = GRAY
6 s.d = 0
7 s.π = NIL
8 Q ≠ Ø
9 ENQUEUE(Q, s)
10 while Q ≠ Ø
11 u = DEQUEUE(Q)
12 for each v ∈ G.Adj[u]
13 if v.color == WHITE
14 v.color = GRAY
15 v.d = u.d + 1
16 v.π = u
17 ENQUEUE(Q, v)
18 u.color = BLACK
The above Breadth First Search code is represented using adjacency lists.
Notations -
G : Graph
s : source vertex
u.color : stores the color of each vertex u ∈ V
u.π : stores predecessor of u
u.d = stores distance from the source s to vertex u computed by the algorithm
Understanding of the code (help me if I'm wrong) -
1. As far as I could understand, the ENQUEUE(Q, s) and DEQUEUE(Q) operations take O(1) time.<br>
2. Since the enqueuing operation occurs for exactly one time for one vertex, it takes a total O(V) time.
3. Since the sum of lengths of all adjacency lists is |E|, total time spent on scanning adjacency lists is O(E).
4. Why is the running time of BFS is O(V+E)?.
Please do not refer me to some website, I've gone through many articles to understand but I'm finding it difficult to understand.
Can anyone please reply to this code by writing the time complexity of each of the 18 lines?
Lines 1-4: O(V) in total
Lines 5-9: O(1) or O(constant)
Line 11: O(V) for all operations of line 11 within the loop (each vertice can only be dequeued once)
Lines 12-13: O(E) in total as you will check through every possible edge once. O(2E) if the edges are bi-directional.
Lines 14-17: O(V) in total as out of the E edges you check, only V vertices will be white.
Line 18: O(V) in total
Summing the complexities gives you
O(4V + E + 1) which simplifies to O(V+E)
New:
It is not O(VE) because at each iteration of the loop starting at line 10, lines 12-13 will only loop through the edges the current node is linked to, not all the edges in the entire graph. Thus, looking from the point of view of the edges, they will only be looped at most twice in a bi-directional graph, once by each node it connects with.

Optimizing partial computation in Haskell

I'm curious how to optimize this code :
fun n = (sum l, f $ f0 l, g $ g0 l)
where l = map h [1..n]
Assuming that f, f0, g, g0, and h are all costly, but the creation and storage of l is extremely expensive.
As written, l is stored until the returned tuple is fully evaluated or garbage collected. Instead, length l, f0 l, and g0 l should all be executed whenever any one of them is executed, but f and g should be delayed.
It appears this behavior could be fixed by writing :
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
Or the very similar :
fun n = (a,b,c) `deepSeq` (a, f b, g c)
where ...
We could perhaps specify a bunch of internal types to achieve the same effects as well, which looks painful. Are there any other options?
Also, I'm obviously hoping with my inlines that the compiler fuses sum, f0, and g0 into a single loop that constructs and consumes l term by term. I could make this explicit through manual inlining, but that'd suck. Are there ways to explicitly prevent the list l from ever being created and/or compel inlining? Pragmas that produce warnings or errors if inlining or fusion fail during compilation perhaps?
As an aside, I'm curious about why seq, inline, lazy, etc. are all defined to by let x = x in x in the Prelude. Is this simply to give them a definition for the compiler to override?
If you want to be sure, the only way is to do it yourself. For any given compiler version, you can try out several source-formulations and check the generated core/assembly/llvm byte-code/whatever whether it does what you want. But that could break with each new compiler version.
If you write
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
or the deepseq version thereof, the compiler might be able to merge the computations of a, b and c to be performed in parallel (not in the concurrency sense) during a single traversal of l, but for the time being, I'm rather convinced that GHC doesn't, and I'd be surprised if JHC or UHC did. And for that the structure of computing b and c needs to be simple enough.
The only way to obtain the desired result portably across compilers and compiler versions is to do it yourself. For the next few years, at least.
Depending on f0 and g0, it might be as simple as doing a strict left fold with appropriate accumulator type and combining function, like the famous average
data P = P {-# UNPACK #-} !Int {-# UNPACK #-} !Double
average :: [Double] -> Double
average = ratio . foldl' count (P 0 0)
where
ratio (P n s) = s / fromIntegral n
count (P n s) x = P (n+1) (s+x)
but if the structure of f0 and/or g0 doesn't fit, say one's a left fold and the other a right fold, it may be impossible to do the computation in one traversal. In such cases, the choice is between recreating l and storing l. Storing l is easy to achieve with explicit sharing (where l = map h [1..n]), but recreating it may be difficult to achieve if the compiler does some common subexpression elimination (unfortunately, GHC does have a tendency to share lists of that form, even though it does little CSE). For GHC, the flags fno-cse and -fno-full-laziness can help avoiding unwanted sharing.

Modular arithmetic

I'm new to cryptography and modular arithmetic. So, I'm sure it's a silly question, but I can't help it.
How do I calculate a from
pow(a,q) = 1 (mod p),
where p and q are known? I don't get the "1 (mod p)" part, it equals to 1, doesn't it? If so, than what is "mod p" about?
Is this the same as
pow(a,-q) (mod p) = 1?
The (mod p) part refers not to the right hand side, but to the equality sign: it says that modulo p, pow(a,q) and 1 are equal. For instance, "modulo 10, 246126 and 7868726 are equal" (and they are also both equal to 6 modulo 10): two numbers x and y are equal modulo p if they have the same remainder on dividing by p, or equivalently, if p divides x-y.
Since you seem to be coming from a programming perspective, another way of saying it is that pow(a,q)%p=1, where "%" is the "remainder" operator as implemented in several languages (assuming that p>1).
You should read the Wikipedia article on Modular arithmetic, or any elementary number theory book (or even a cryptography book, since it is likely to introduce modular arithmetic).
To answer your other question: there is no general formula for finding such an a (to the best of my knowledge) in general. Assuming that p is prime, and using Fermat's little theorem to reduce q modulo p-1, and assuming that q divides p-1 (or else no such a exists), you can produce such an a by taking a primitive root of p and raising it to the power (p-1)/q. [And more generally, when p is not prime, you can reduce q modulo φ(p), then assuming it divides φ(p) and you know a primitive root (say r) mod p, you can take r to the power of φ(p)/q, where φ is the totient function -- this comes from Euler's theorem.]
Not silly at all, as this is the basis for public-key encryption. You can find an excellent discussion on this at http://home.scarlet.be/~ping1339/congr.htm#The-equation-a%3Csup%3Ex.
PKI works by choosing p and q that are large and relatively prime. One (say p) becomes your private key and the other (q) is your public key. The encryption is "broken" if an attacker guesses p, given aq (the encrypted message) and q (your public key).
So, to answer your question:
aq = 1 mod p
This means aq is a number that leaves a remainder of 1 when divided by p. We don't care about the integer portion of the quotient, so we can write:
aq / p = n + 1/p
for any integer value of n. If we multiply both sides of the equation by p, we have:
aq = np + 1
Solving for a we have:
a = (np+1)1/q
The final step is to find a value of n that generates the original value of a. I don't know of any way to do this other than trial and error -- which equates to a "brute force" attempt to break the encryption.