How to deduce left-hand side matrix from vector? - octave

Suppose I have the following script, which constructs a symbolic array, A_known, and a symbolic vector x, and performs a matrix multiplication.
clc; clearvars
try
pkg load symbolic
catch
error('Symbolic package not available!');
end
syms V_l k s0 s_mean
N = 3;
% Generate left-hand-side square matrix
A_known = sym(zeros(N));
for hI = 1:N
A_known(hI, 1:hI) = exp(-(hI:-1:1)*k);
end
A_known = A_known./V_l;
% Generate x vector
x = sym('x', [N 1]);
x(1) = x(1) + s0*V_l;
% Matrix multiplication to give b vector
b = A_known*x
Suppose A_known was actually unknown. Is there a way to deduce it from b and x? If so, how?
Til now, I only had the case where x was unknown, which normally can be solved via x = b \ A.

Mathematically, it is possible to get a solution, but it actually has infinite solutions.
Example
A = magic(5);
x = (1:5)';
b = A*x;
A_sol = b*pinv(x);
which has
>> A
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
but solves A as A_sol like
>> A_sol
A_sol =
3.1818 6.3636 9.5455 12.7273 15.9091
3.4545 6.9091 10.3636 13.8182 17.2727
4.4545 8.9091 13.3636 17.8182 22.2727
3.4545 6.9091 10.3636 13.8182 17.2727
3.1818 6.3636 9.5455 12.7273 15.9091

Related

Failing to solve a simple ODE with Octave

I am new to Octave, so I am trying to make some simple examples work before moving onto more complex projects.
I am trying to resolve the ODE dy/dx = a*x+b, but without success. Here is the code:
%Funzione retta y = a*x + b. Ingressi: vettore valori t; coefficienti a,b
clear all;
%Inizializza argomenti
b = 1;
a = 1;
x = ones(1,20);
function y = retta(a, x, b) %Definisce funzione
y = ones(1,20);
y = a .* x .+ b;
endfunction
%Calcola retta
x = [-10:10];
a = 2;
b = 2;
r = retta(a, x, b)
c = b;
p1 = (a/2)*x.^2+b.*x+c %Sol. analitica di dy/dx = retta %
plot(x, r, x, p1);
% Risolve eq. differenziale dy/dx = retta %
y0 = b; x0 = 0;
p2 = lsode(#retta, y0, x)
And the output is:
retta3code
r =
-18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22
p1 =
Columns 1 through 18:
82 65 50 37 26 17 10 5 2 1 2 5 10 17 26 37 50 65
Columns 19 through 21:
82 101 122
error: 'b' undefined near line 9 column 16
error: called from:
error: retta at line 9, column 4
error: lsode: evaluation of user-supplied function failed
error: lsode: inconsistent sizes for state and derivative vectors
error: /home/fabio/octave_file/retta3code.m at line 21, column 4
So, the function retta works properly the first time, but it fails when used in lsode.
Why does that happen? What needs to be changed to make the code work?
Somehow you still miss some important parts of the story. To solve an ODE y'=f(y,x) you need to define a function
function ydot = f(y,x)
where ydot has the same dimensions as y, both have to be vectors, even f they are of dimension 1. x is a scalar. For some traditional reason, lsode (a FORTRAN code used in multiple solver packages) prefers the less used order (y,x), in most text books and other solvers you find the order (x,y).
Then to get solution samples ylist over sample points xlist you call
ylist = lsode("f", y0, xlist)
where xlist(1) is the initial time.
The internals of f are independent of the sample list list and what size it has. It is a separate issue that you can use multi-evaluation to compute the exact solution with something like
yexact = solexact(xlist)
To pass parameters, use anonymous functions, like in
function ydot = f(y,x,a,b)
ydot = [ a*x+b ]
end
a_val = ...
b_val = ...
lsode(#(y,x) f(y,x,a_val, b_val), y0, xlist)
The code as modified below works, but I'd prefer to be able to define the parameters a and b out of the function and then pass them to rdot as arguments.
x = [-10,10];
a = 1;
b = 0;
c = b;
p1 = (a/2).*(x.^2)+b.*x+c %Sol. analitica di dy/dx = retta %
function ydot = rdot(ydot, x)
a = 1;
b = 0;
ydot = ones(1,21);
ydot = a.*x .+ b;
endfunction
y0 = p1(1); x0 = 0;
p2 = lsode("rdot", y0, x, x0)'
plot(x, p1, "-k", x, p2, ".r");

Big numbers Napier's location arithmetic

I have to represent this equation 2049*(M+N*100)+(M*N)*2800 using John Napier's Location Arithmetic and then calculate it using the notation's characteristic.
So for example I know that 29*11 would be (2*1)(2*1)(9*1)(9*1) = 3 3 10 10 = 4 11 = 24+ 211 = 16 + 2048 = 2064.
With that knowledge I can change most part of equation, but how can I calculate it with a big number like 2800?
Let's say M = 7 and N = 10.

Trying to find index of minimum value in a matrix fails in Octave

So I have this matrix:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34]
lets say I want to find the location of the value closest to 18.9. let A = 18.9
I would do
[r,c] = find(E1==min(min(abs(E1-A))))
This doesn't work. It returns r = "[](0x1)" and c = "[](0x1)"
however,
if I first do:
F = abs(E1-A) and then do
[r,c] = find(F==min(min(F)))
this gives r = 2 and c = 3 which is correct. 19 is the closest value and 19 lives in row 2 column 3.
Why doesnt this work then? F is simply abs(E1-A) so why can I not put abs(E1-A) in place of F in the find formula?
min(min(abs(E1-A)))
ans = 0.10000
This gives you the min over the absolute difference. Then you compare it to E1 which has absolute values. This is complete different from your second formular
[r,c] = find(F==min(min(F)))
where you comapre the minimum difference with the matrix containing the absolute of differences between E1 and A. If you replace in your second formula F with abs(E1-A) you would get
[r,c] = find(abs(E1-A)==min(min(abs(E1-A))))
Which would also work. Nevertheless I would suggest another approach:
E1 = [54 5 2 4;4 5 19 29;31 4 2 9; 1 3 99 34];
A = 18.9;
# get the index ( Column-major order) of the minimum
idx = nthargout (2, #min, abs (E1-A)(:));
# this returns 10
# convert it ro row, column
[r, c] = ind2sub (size (E1), idx)
r = 2
c = 3

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,:);

Convert byte to specific mask with bit hack

I have number with binary representation 0000abcd.
How convert it to 0a0b0c0d with smallest number of operations?
How convert 0a0b0c0d back to 0000abcd?
I was searching for a solution here:
http://graphics.stanford.edu/~seander/bithacks.html and other
Generally the problem a bit more than described.
Given first number a₁b₁c₁d₁a₂b₂c₂d₂ and second number a₃a₄b₃b₄c₃c₄d₃d₄
If (a₁ and a₂ = 0) then clear both a₃ and a₄, if (a₃ and a₄ = 0) then clear both a₁ and a₂, etc.
My solution:
a₁b₁c₁d₁a₂b₂c₂d₂
OR 0 0 0 0 a₁b₁c₁d₁ ( a₁b₁c₁d₁a₂b₂c₂d₂ >> 4)
----------------
0 0 0 0 a b c d
? (magic transformation)
? ? ? ? ? ? ? ?
----------------
0 a 0 b 0 c 0 d
OR a 0 b 0 c 0 d 0 (0 a 0 b 0 c 0 d << 1)
----------------
a a b b c c d d
AND a₃a₄b₃b₄c₃c₄d₃d₄
----------------
A₃A₄B₃B₄C₃C₄D₃D₄ (clear bits)
UPDATED: (thanks for #AShelly)
x = a₁b₁c₁d₁a₂b₂c₂d₂
x = (x | x >> 4) & 0x0F
x = (x | x << 2) & 0x33
x = (x | x << 1) & 0x55
x = (x | x << 1)
y = a₃a₄b₃b₄c₃c₄d₃d₄
y = (y | y >> 1) & 0x55
y = (y | y >> 1) & 0x33
y = (y | y >> 2) & 0x0F
y = (y | y << 4)
work for 32-bit with constants 0x0F0F0F0F, 0x33333333, 0x55555555 (and twice long for 64-bit).
If you're looking for the smallest number of operations, use a look-up table.
I have number with binary
representation 0000abcd. How convert
it to 0a0b0c0d with smallest number of
operations?
Isn't this exactly "Interleave bits of X and Y" where Y is 0? Bit Twiddling Hacks has Multiple Solutions that don't use a lookup table.
How convert 0a0b0c0d back to 0000abcd?
See "How to de-interleave bits (UnMortonizing?)"
You can't do it in one go, you should shift bits on per bit basis:
Pseudo code:
X1 = a₁b₁c₁d₁
X2 = a₂b₂c₂d₂
Bm = 1 0 0 0 // Bit mask
Result = 0;
while (/* some bytes left */)
{
Result += (X1 and Bm) << 1 or (X2 and Bm);
Bm = Bm shr 1
Result = Result shl 2;
}
As a result you will get a1a2b1b2c1c2d1d2
I think it is not possible (without lookup table) to do it in less operations using binary arithmetic and x86 or x64 processor architecture. Correct me if I'm mistaken but your problem is about moving bits. Having the abcd bits you want to get 0a0b0c0d bits in one operation. The problem starts when you will look at how many bits the 'a','b','c' and 'd' has to travel.
'a' was 4-th, became 7-th, distance travelled 3 bits
'b' was 3-rd, became 5-th, distance travelled 2 bits
'c' was 2-nd, became 3-rd, distance travelled 1 bit
'd' was 1-st, became 1-st, distance travelled 0 bits
There is no such processor instruction that will move these bits dynamically to a different distance. Though if you have different input representations of the same number for free, for example you have precomputed several values which you are using in a cycle, than maybe it will be possible to gain some optimization, this is the effect you get when using additional knowledge about the topology. You just have to choose whether it will be:
[4 cycles, n^0 memory]
[2 cycles, n^1 memory]
[1 cycle , n^2 memory]