Akka Stream stages not executing concurrently - akka-stream

I'm starting to learn Akka Streams and am running the first example from here:
http://doc.akka.io/docs/akka/2.4.2/scala/stream/stream-rate.html#stream-rate-scala
import akka.stream.scaladsl._
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
object Main extends App {
implicit val system = ActorSystem("TestSystem")
implicit val mat = ActorMaterializer()
Source(1 to 10)
.map { i => println(s"A: $i"); i }
.map { i => println(s"B: $i"); i }
.map { i => println(s"C: $i"); i }
.runWith(Sink.ignore)
}
Based on the example, the output should be non-deterministic like this:
A: 1
A: 2
B: 1
A: 3
B: 2
C: 1
B: 3
C: 2
C: 3
But when I run it, it never starts processing the next element until the previous is fully processed.
A: 1
B: 1
C: 1
A: 2
B: 2
C: 2
A: 3
B: 3
C: 3
A: 4
B: 4
C: 4
A: 5
B: 5
C: 5
A: 6
B: 6
C: 6
A: 7
B: 7
C: 7
A: 8
B: 8
C: 8
A: 9
B: 9
C: 9
A: 10
B: 10
C: 10
I also tried adding a delay into each stage/map (with Thread.sleep), and only one thing was processed at a time, as if the actor system only has one thread. I was able to confirm that the Akka dispatcher has enough threads.
import system.dispatcher
val start = System.currentTimeMillis()
( 1 to 10 ).map { i => Future { Thread.sleep( 1000 ); println( s"Finished ${i} after ${System.currentTimeMillis() - start}ms" ) }
Output:
Finished 5 after 1004ms
Finished 2 after 1004ms
Finished 6 after 1005ms
Finished 8 after 1004ms
Finished 4 after 1004ms
Finished 9 after 1005ms
Finished 7 after 1004ms
Finished 3 after 1005ms
Finished 1 after 1006ms
Finished 10 after 1009ms
Does something need to be tweaked to get the stages to process concurrently?
I'm using Akka Streams 2.4.2 and Java 1.8.0_65-b17.

I think, that you're observing an Operator Fusion, which means that all three map operations are being executed on the same Actor.
The fusable elements are for example:
all GraphStages (this includes all built-in junctions apart from groupBy)
all Stages (this includes all built-in linear operators)
TCP connections
You can either disable it either by passing configuration parameter akka.stream.materializer.auto-fusing=off which disables it completely (I'm not sure its a good idea in general) or you can disable it in your code by adding async boundaries (see the link I've attached for more details). Everything in a single async boundary gets executed on a single actor.
Source(1 to 10)
.map { i => println(s"A: $i"); i }.async
.map { i => println(s"B: $i"); i }.async
.map { i => println(s"C: $i"); i }.async
.runWith(Sink.ignore)

Related

How to implement a decrementing for loop in Julia?

I know that in python I can do something as follows.
for i in range(10, 0, -1):
print(i)
Which will output:
10
9
8
7
6
5
4
3
2
1
I'm very much new to julia and I know I can create normal loops as follows.
for i=1:10
println(i)
end
Intuitively, I tried something like as follows (since I thought it behaved similar to python's range([start], stop[, step]) function).
for i=10:1:-1
println(i)
end
Although it didn't fail, it didn't print anything either. What am I doing wrong?
Is there an intuitive way to loop backwards in julia?
Try this:
julia> for i=10:-1:1
println(i)
end
10
9
8
7
6
5
4
3
2
1
or this
julia> for i=reverse(1:10)
println(i)
end
10
9
8
7
6
5
4
3
2
1
As #phipsgabler noted you can also use:
julia> range(10, 1, step=-1)
10:-1:1
to get the same result again (note though that you have to use 1 as a second index).
From my practice range is usually more useful with with length keyword argument:
julia> range(10, 1, length=10)
10.0:-1.0:1.0
(notice that in this case you get a vector of Float64 not Int)

Matrix transformation in MATLAB

For example, I have a matrix A (Figure 1). When the variable n = 2, I want it to be transformed to the matrix B. The red rectangle shows the transformation rule of every column. According to this rule, when the n = 3, it can become the matrix C.
I have written a script using a for loop method, but it is a waste of time when the matrix A is very large (e.g. 11688* 140000). Is there an efficient way to solve this problem?
Figure 1:
Here is a way using reshape and implicit expansion:
result = reshape(A((1:size(A,1)-n+1) + (0:n-1).', :), n, []);
For example assume that n = 3. Implicit expansion is used to extract indices of rows:
row_ind = (1:size(A,1)-n+1) + (0:n-1).';
The following matrix is created:
1 2
2 3
3 4
Extract the desired rows of A:
A_expanded = A(row_ind, :)
When the matrix row_ind is used as an index it behaves like a vector:
1
2
1 2 3
2 3 -> 2
3 4 3
4
A_expanded =
3 5 7
6 8 9
2 6 3
6 8 9
2 6 3
1 2 1
Now A_expanded can be reshaped to the desired size:
result = reshape(A_expanded, n, []);
>>result =
3 6 5 8 7 9
6 2 8 6 9 3
2 1 6 2 3 1
If you have the Image Processing Toolbox you can use im2col as follows:
result = im2col(A, [n 1], 'sliding');

matlab making repetitions of data from one array into another array [duplicate]

This question already has answers here:
Element-wise array replication in Matlab
(7 answers)
Closed 6 years ago.
I would appreaciate a lot if you help. I am beginner in programming. I am using Matlab. So, I have an array which is 431x1 type - double; there i have numbers 1 to 6; for ex: 1 4 5 3 2 6 6 3 3 5 4 1 ...; what I want to do is I need to make a new array where I would have each element repeat for 11 times; for ex: a(1:11)=1; a(12:22)=4; a(23:33)=5; or to illustrate differently : a=[1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4...];
I tried doing it in a loop but had some problems, which way could you suggest, do you know any function I could take advantage of?
First of all, it would help if you could format your code is separate blocks to make your question easier to read...
Let's say you had an array of length Nx1 as:
x = [1 2 3 4 5 ...]';
You could construct a loop and concatenate as:
for i = 1 : length(x)
for i = 1: length(x)
y(1 + (i - 1) * 11 : 1 + i * 11) = x(i); % Copy to a moving block
end
y(end) = []; % Delete the superfluous one at the end
You could also look at functions like repmat in the MATLAB help for replicating arrays.
Try this (NRepis how many times you want it repeated):
x = [1, 2, 3, 4, 5];
NRep = 5;
y = reshape(repmat(x,[NRep,1]),[1,length(x)*NRep])
Since it's a little cumbersome to write that out, I also particularly enjoy to use this "hack":
x = [1, 2, 3, 4, 5];
NRep = 5;
y = kron(x, ones(1,NRep));
Hope that helps!
P.S.: This is designed for row vectors only. Though if you need column vectors it's easy to modify.
edit: Of course, if you're post-R2015a you can just use y=repelem(x,NRep). I tend to forget about those because I work on older Matlabs (and sometimes it's not such a bad idea to be a bit backward compatible). Thanks to #rahnema1 for reminding me.

Matlab delete specific elements from an array

I have for example a=[1 2 3 4 5 6 7 8 9 10]; and I have to delete each 2 following numbers from 3.
like at the end it should be a=[1 4 7 10];
How to do this without a for loop.
And also if there is a way to guarantee that at the end the resulting array will have exact number of entries, like here it should be a with 4 entries at the end.
But for example we have b=[1 2 3 4 5 6 7 8 9 ]; and if I want make sure that at the end I still have 4 entries in the rest array, so that b can't be equal to [1 4 7] because I need 4 entries for sure.
You can use indexing for this:
A = 1:10;
B = A(1:3:end)
B =
[1 4 7 10]
Or, if you really want to remove elements:
A = 1:10;
A(2:3:end) = [];
A(3:3:end) = [];
For your second question regarding length checking, it's unclear what you're asking. Would an if comparison be enough ?
if numel(A) ~= 4
% ... Handle unexpected values here
end
Best,
As you mentioned in the question and in the comments that you need 4 elements at the end and if elements are less than 4 then you want to include the last element/s of b, the following should work:-
b=[1 2 3 4 5 6 7 8 9]
b_req=b(1:3:end);
temp=length(b_req);
if temp<4 b_req(end+1:4)=b(end-3+temp:end); % for including the elements of b so that total elements are 4 at the end
elseif temp>4 b_req=b_req(1:4); % for removing the extra elements
end
b_req
Output:-
b =
1 2 3 4 5 6 7 8 9
b_req =
1 4 7 9
and
if instead b=[1 2 3 4 5 6 7 8 9 10]; then the same code gives what you require, i.e. b_req = [1 4 7 10]
This code speaks for itself:
a = 1:15; % some vector
% returns every third element after the first one:
third_elemets = a(1:3:end);
% returns the missing elements for the vector to be in size 4 from the end of a
last_elements = a(end-3+length(third_elemets):end);
% take maximum 4 elements from a
logic_ind = true(min(4,length(third_elemets)),1);
% and concatanate them with last_elements (if there are any)
a = [third_elemets(logic_ind) last_elements]
and under the assumption that whenever there are less than 4 elements you simply take the last one(s) - it should always work.

Compare Values in Array on Specific Indexes in Matlab

how to Compare Values in Array on Specific Indexes in Matlab?
Suppose:
A= [2 2 3 3 3 4 4 4 5 5 6 6 7 8 8]
so i want to Find that
on index 2,3,4,5,6 values or same or not ?
Note: Index can be Dynamically Entered.
Number(length) of Values in Array also can be changed..
To check if they are all equal: use diff to subtract pairs of values, and then check if all those differences are 0.
A = [2 2 3 3 3 4 4 4 5 5 6 6 7 8 8];
ind = [2 3 4 5 6];
result = ~any(diff(A(ind)));
This is faster than using unique. With A and ind as in your example,
>> tic
for cont = 1:1e5
result = ~any(diff(A(ind)));
end
toc
tic
for cont = 1:1e5
result=numel(unique(A(ind)))==1;
end
toc
Elapsed time is 0.371142 seconds.
Elapsed time is 4.754007 seconds.
Hey this should do the trick:
A= [2 2 3 3 3 4 4 4 5 5 6 6 7 8 8];
B= [1,3,5];
C=A(B);
result=numel(unique(C))==1;
Here A is your data.
B is the index vector.
C contains the elements corresponding to the index vector.
result is 1 if all values were the same and 0 otherwise.
You can even "shorten" the code further by joining the two line:
result=numel(unique(A(B)))==1;
There are some ways, it depends on your taste.
For example, if the variable indexing contain the corresponding indexes:
unique(A(indexing));
will give you a vector with the unique elements in the sub-vector A(indexing). Then you just need to check the length:
length(unique(A(indexing))) == 1
I would avoid the use of numel when the function length is available (it is much more clearer what you are trying to achieve).
Other option is to compare the first element to the rest of the element in the sub-vector:
sub_vector = A(indexing);
all(sub_vector == sub_vector(1));
The second option assumes that the sub-vector will never be empty!

Resources