How to multiply two rows or columns? - octave

a = [1, 2, 3];
b = [3, 2, 1];
c = a * b;
yields
error: operator *: nonconformant arguments (op1 is 1x3, op2 is 1x3)
Why can I not multiply these two rows of the same size?
I shouldn't have to run a for loop for this, but I don't know of another way...
I saw section 1.2.3 here, which indicates (to me at least) that I should be able to do it.

You made 2 rows, which can't be multiplied together.
The general form of matrix multiplication is "Row-Dot-Column", which means take the dot product of each row with each column. In your case you have 1 row, but 3 columns (which doesn't work!).
a = [1, 2, 3];
b = [3, 2, 1];
c = a' * b;
ans =
3 2 1
6 4 2
9 6 3

I see now that there is a .* operator. I did not know where to find that in the documentation, and it does what I want.

Related

Compute the mean of each element, the previous and the next in a row vector, for all elements starting from the second one - vectorized implementation

I'd like to compute the mean of each element, the previous and the next in a row vector, for all elements starting from the second one, and I'd like to do it with a vectorized implementation.
Suppose I have this row vector:
a = [4, 7, 1, 3, 2];
what I want to obtain is:
b = [4, 3.66, 2, 1.66];
which is, in turn, the mean of the subsequent triplets:
[4 7 1], [7 1 3], [1 3 2], [3 2 0] (the zero is conventional).
By the way, approximation to two figures is irrelevant here, it's just for the sake of the example.
I have come up with this code:
a = [4 7 1 3 2];
function shifted = generateShiftedValues(rowVec)
shifted = rowVec;
for i=2:3
shifted(i, :) = [rowVec(1, i:end), zeros(1, i-1)];
endfor
endfunction
b = mean(generateShiftedValues(a)(:, 1:end-1), 1)
but what I'd like to have is a fully vectorized implementation.
Is that possible? Any ideas?
Thank you very much indeed.
Convolution is the key to success.
I would go for this:
a = [4 7 1 3 2]
n = 3;
b = conv(a, ones(n, 1)) / n;
b = b(3:end-1)
a =
4 7 1 3 2
b =
4.00000 3.66667 2.00000 1.66667
One could easily build a generalized solution for any number of elements to be averaged and arbitrary "starting point". If you need such, maybe provide a general description in your question. If that "special case" is sufficient, that's all.
Hope that helps!

how to define dynamic nested loop python function

a = [1]
b = [2,3]
c = [4,5,6]
d = [a,b,c]
for x0 in d[0]:
for x1 in d[1]:
for x2 in d[2]:
print(x0,x1,x2)
Result:
1 2 4
1 2 5
1 2 6
1 3 4
1 3 5
1 3 6
Perfect, now my question is how to define this to function, considering ofcourse there could be more lists with values. The idea is to get function, which would dynamicaly produce same result.
Is there a way to explain to python: "do 8 nested loops for example"?
You can use itertools to calculate the products for you and can use the * operator to convert your list into arguments for the itertools.product() function.
import itertools
a = [1]
b = [2,3]
c = [4,5,6]
args = [a,b,c]
for combination in itertools.product(*args):
print combination
Output is
(1, 2, 4)
(1, 2, 5)
(1, 2, 6)
(1, 3, 4)
(1, 3, 5)
(1, 3, 6)

How do you perform conditional assignment in arrays in Julia?

In Octave, I can do
octave:1> A = [1 2; 3 4]
A =
1 2
3 4
octave:2> A(A>1) -= 1
A =
1 1
2 3
but in Julia, the equivalent syntax does not work.
julia> A = [1 2; 3 4]
2x2 Array{Int64,2}:
1 2
3 4
julia> A[A>1] -= 1
ERROR: `isless` has no method matching isless(::Int64, ::Array{Int64,2})
in > at operators.jl:33
How do you conditionally assign values to certain array or matrix elements in Julia?
Your problem isn't with the assignment, per se, it's that A > 1 itself doesn't work. You can use the elementwise A .> 1 instead:
julia> A = [1 2; 3 4];
julia> A .> 1
2×2 BitArray{2}:
false true
true true
julia> A[A .> 1] .-= 1000;
julia> A
2×2 Array{Int64,2}:
1 -998
-997 -996
Update:
Note that in modern Julia (>= 0.7), we need to use . to say that we want to broadcast the action (here, subtracting by the scalar 1000) to match the size of the filtered target on the left. (At the time this question was originally asked, we needed the dot in A .> 1 but not in .-=.)
In Julia v1.0 you can use the replace! function instead of logical indexing, with considerable speedups:
julia> B = rand(0:20, 8, 2);
julia> #btime (A[A .> 10] .= 10) setup=(A=copy($B))
595.784 ns (11 allocations: 4.61 KiB)
julia> #btime replace!(x -> x>10 ? 10 : x, A) setup=(A=copy($B))
13.530 ns ns (0 allocations: 0 bytes)
For larger matrices, the difference hovers around 10x speedup.
The reason for the speedup is that the logical indexing solution relies on creating an intermediate array, while replace! avoids this.
A slightly terser way of writing it is
replace!(x -> min(x, 10), A)
There doesn't seem to be any speedup using min, though.
And here's another solution that is almost as fast:
A .= min.(A, 10)
and that also avoids allocations.
To make it work in Julia 1.0 one need to change = to .=. In other words:
julia> a = [1 2 3 4]
julia> a[a .> 1] .= 1
julia> a
1×4 Array{Int64,2}:
1 1 1 1
Otherwise you will get something like
ERROR: MethodError: no method matching setindex_shape_check(::Int64, ::Int64)

Outputs of a program

I am new to programming and I would like to know how to solve questions like this. I was told to expect questions like this on the exam. Can someone please tell me how I would go about solving something like this? Thanks.
x = 0
for num in range(5):
if num % 2 == 0:
x = x + 2
else:
x = x + 1
print(x)
You need to work on a skill which is to "be the compiler", in the sense that you should be able to run code in your head. Step through line by line and make sure you know what is happening. In you code example, you have
for num in range(5) means you will be iterating with num being 0,1,2,3 and 4. Inside the for loop, the if statement num % 2 == 0 is true when num/2 does not have a remainder (how % mods work). So if the number is divisible by 2, x = x+2 will execute. The only numbers divisible by 2 from the for loop are 0,2 and 4. so x=x+2 will execute twice. The else statement x = x +1 runs for all other numbers (1,3) which will execute 2 times.
Stepping through the for loop:
num = 0 //x=x+2, x is now 2
num = 1 //x=x+1, x is now 3, print(x) prints 3
num = 2 //x=x+2, x is now 5
num = 3 //x=x+1, x is now 6, print(x) prints 6
num = 4 //x+x+2, x is now 8
Therefore the answer is that 3 and 6 will be printed
In my opinion,
Whatever language you are using, you need to learn some common elements of the modern programming languages, such as flow-control (if...else in your case), loop(for, in your case)
Some common used functions, in your case, you need to what does range do in Python,
docs.python.org is a good place for you.
As you are new to programming, you can go with the flow in you mind or draw it on the paper.
Using x to store our final result
loop through every item in [0, 1, 2, 3, 4] <- range(5)
a. if
the number is divisible by 2
then increase x by adding 2 to it.
b. else
increase x by adding 1 and print it out
So the result would be :
3
6

Iterating through matrix rows in Octave without using an index or for loop

I am trying to understand if it's possible to use Octave more efficiently by removing the for loop I'm using to calculate a formula on each row of a matrix X:
myscalar = 0
for i = 1:size(X, 1),
myscalar += X(i, :) * y(i) % y is a vector of dimension size(X, 1)
...
The formula is more complicate than adding to a scalar. The question here is really how to iterate through X rows without an index, so that I can eliminate the for loop.
Yes, you can use broadcasting for this (you will need 3.6.0 or later). If you know python, this is the same (an explanation from python). Simply multiply the matrix by the column. Finnaly, cumsum does the addition but we only want the last row.
newx = X .* y;
myscalars = cumsum (newx, 1) (end,:);
or in one line without temp variables
myscalars = cumsum (X .* y, 1) (end,:);
If the sizes are right, broadcasting is automatically performed. For example:
octave> a = [ 1 2 3
1 2 3
1 2 3];
octave> b = [ 1 0 2];
octave> a .* b'
warning: product: automatic broadcasting operation applied
ans =
1 0 6
1 0 6
1 0 6
octave> a .* b
warning: product: automatic broadcasting operation applied
ans =
1 2 3
0 0 0
2 4 6
The reason for the warning is that it's a new feature that may confuse users and is not existent in Matlab. You can turn it off permanentely by adding warning ("off", "Octave:broadcast") to your .octaverc file
For anyone using an older version of Octave, the same can be accomplished by calling bsxfun directly.
myscalars = cumsum (bsxfun (#times, X, y), 1) (end,:);