Read a binary array with mixed types - octave

I am writing a function similar to this to read in binary formatted .ply files.
The linked function reads the header and the skips to the binary array, reading that in with numpy and I would like to do the same in Octave.
My code for reading the header is
fid = fopen('/path/to/file.ply');
tline = fgetl(fid); % read first line
len = 0;
prop = {};
dtype = {};
fmt = 'binary';
while ~strcmp(tline, "end_header")
len = len + length(tline) + 1; % increase header length, +1 includes EOL
tline = strsplit(tline); % split string
if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % test whether file is ascii
fmt = 'ascii';
end
if strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % number of points
N = tline{3};
end
if strcmp('property', tline{1}) % identify fields
dtype = [dtype, tline{2}];
prop = [prop, tline{3}];
end
tline = fgetl(fid);
end
len = len + length(tline) + 1; % add 'end_header' to len
So I have arrays of data types
dtype =
{
[1,1] = float
[1,2] = float
[1,3] = float
[1,4] = int
[1,5] = int
[1,6] = int
[1,7] = float
[1,8] = float
[1,9] = float
}
and I know the shape of the array.
N = 61415
Is there a function that replicates numpy's fromfile and can I seek to the right location in my file (I know where the binary data starts in the file as I have len)
Following #tasos-papastylianou answer I tried
fseek(fid, len);
fread(fid, 3, 'float')
Which returns the correct 3 values, but the next value is an integer and therefore gives the incorrect answer.
fread(fid, 4, 'float')
arr =
-1.4298e+00
-5.3943e+00
1.6623e+01
1.5274e-43 <<<< should be 109
My solution
function pts = read_ply(fn)
fid = fopen(fn);
tline = fgetl(fid); % read first line
len = 0;
prop = {};
% dtype_map = {'float': 'f4', 'uchar': 'B', 'int':'i'}
dtype = {};
fmt = 'binary';
while ~strcmp(tline, "end_header")
len = len + length(tline) + 1; % increase header length, +1 includes EOL
tline = strsplit(tline); % split string
if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % test whether file is ascii
fmt = 'ascii';
elseif strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % number of points
N = str2num(tline{3});
elseif strcmp('property', tline{1}) % identify fields
dtype = [dtype, tline{2}];
prop = [prop, tline{3}];
endif
tline = fgetl(fid);
endwhile
len = len + length(tline) + 1; % add 'end_header
% total file length minus header
fseek(fid, 0, 1);
file_length = ftell(fid) - len;
types = struct('float', 4, 'int', 4, 'float64', 8);
pts = struct();
seek_plus = 0;
for i = 1:length(prop)
fseek(fid, len + seek_plus);
dt = types.(dtype{i}); % dtype for field
pts.(prop{i}) = fread(fid, N, dtype{i}, int32(file_length / N) - dt);
seek_plus = seek_plus + dt;
endfor
This does not answer my original question as it involves a loop, but it seems fairly efficient. Arrays can be constructed as so.
xyz = [pts.x, pts.y, pts.z];

Your question confuses me a bit towards the end, since the most direct equivalent to numpy's saving an array in a numpy-specific binary format is octave's save which saves an array to an octave-specific binary format.
Having said that, this doesn't sound like what you want so I'm assuming the fromfile reference is a red herring.
In general if you have a binary file you want to open, read, or seek (i.e. place the cursor at a particular position), you can use the fopen, fread, and fseek commands. Also useful, ftell, frewind, etc.
These are all fairly simple commands. Just have a look at their documentation in the terminal (e.g. help fseek ).

Related

Where is the error in my below code for approximate solution of poisson boundary value problem?

I have to solve the following boundary value problem which is
also it is defined in my Matlab code below, but my code doesn't work. I mean I didn't get the approximate solution of my system.
I want to know where is the problem in my code or just the version of matlab that I have can't compile the kind of function I have used , Thanks
Explanation of method I have used : I have used the finite element method or what we called Galerkin Method based on investigation about assembly matrix and stiffness matrix. I have multiplied the system by weight function which satisfies the boundary condition then I have integrated over elements (integration of elementary matrix over the range ]-1,1[). I have four elementary matrix. For more information about that Method I used please check this paper(page:6,7,8)
Note The error I have got upon the compilation of my code is
The current use of "MatElt2Nd" is inconsistent with it previous use or definition in line 7
Code
function [U] = EquaDiff2(n)
% ----------------------------------
% -d²u/dx² + 6*u = (-4*x^2-6)exp(x^2)
% u(-1) = 0 u(1)= 0
%----------------------------------
function [Ke, Fe] = MatElt2Nd(x1,x2)
% déclaration de la fonction,
% function of computing matrix and elementary matrix (assembly matrix)
% ----------------------------------
x = [-1:2/n:1]'; % modification d1 of bound d’intégration
K = zeros(n+1) ;
F = zeros(n+1,1) ;
for i = 1:n
j = i+1;
t = [i j];
x1 = x(i);
x2 = x(j);
[Ke,Fe] = MatElt2Nd(x1,x2);
K(t,t) = K(t,t) + Ke;
F(t) = F(t) + Fe;
end;
K(1,:) = [];
K(:,1) = [];
F(1) = [];
U = K\F;
U = [0.0;U];
t = 0:0.01:1;
return
%-------------------------------------------
% calculation of matrix Ke and vector Fe
%-------------------------------------------
function [Ke,Fe] = MatElt2Nd0(x1,x2)
% NEWly named nested function is introduced
Ke1 = 1/(x2-x1)*[ 1 -1 % no modification done
-1 1 ] ; % essentiellement que les matrices
Ke2 =(x2-x1)* [ 2 1 % élémentaires
1 2 ] ;
N = [(x-x2)/(x1-x2) (x-x1)/(x2-x1)] % function of form
Fe =simple( int(N' * (-4*x^2-6)*exp(x^2) , x, x1, x2) ) % vecteur Fe ;
Ke = Ke1 + 6*Ke2 ;
return
Edit I have got a general code for that but I can't do changes in the general code to solve my system , Any help ?
General Code
% au'(x)+bu"(x)=0 for 0<=x<=d
% BC: u(0)=0 and u(d)=h
%==============================================================
% ======Example======
% Finding an approximate solution to the following BVP using 4 elements of
% equal length.
% u'(x)-u"(x)=0 : 0<=x<=1
% BC: u(0)=0 and u(1)=1
% Solution:
% >> Galerkin(4,1,-1,1,1)
% ==============================================================
% The output of this program is
% 1- The approximate solution (plotted in blue)
% 2- The exact solution (plotted in red)
% 3- The percentage error (plotted in magenta)
%=======================Program Begin==========================
function Galerkin(ne1,a,b,d,h) % Declare function
clc % Clear workspace
% Define the Coefficients of the exact solution
% The Exact solution is : u(x)=C1+C2*exp(-ax/b)
% where C2=h/(exp(-a*d/b)-1)and C1=-C2
C2=h/((exp(-a*d/b))-1);
C1=-C2;
% Define element length
le = d/ne1;
% Define x matrix
x = zeros (ne1+1,1); %
for i=2:ne1 +1
x(i,1) = x(i-1,1)+le;
end
% K1 matrix corresponding to the diffusion term (u"(x))
K1 = (b/le) * [1,-1;-1,1]
% K2 matrix corresponding to the convection term (u'(x))
K2 = a*[-1/2 1/2;-1/2 1/2]
% Element stiffness Matrix
Ke = K1+K2
% Global stiffness matrix
%********************Begin Assembly***************************
k = zeros(ne1+1);
for i=1:ne1+1
for j=1:ne1 +1
if (i==j)
if(i==1)
k(i,j)=Ke(1,1);
elseif(i==ne1+1)
k(i,j)=Ke(2,2);
else
k(i,j)=Ke(1,1)+Ke(2,2);
end
elseif(i==j+1)
k(i,j)=Ke(1,2);
elseif(j==i+1)
k(i,j)=Ke(2,1);
else
k(i,j)=0;
end
end
end
%********************End Assembly*****************************
%The Global f Matrix
f = zeros(ne1+1,1);
%BC apply u(0) = 0
f(1,1) = 0;
%BC apply u(d) = h
f(ne1+1,1) = h;
% Display the Global stifness matrix before striking row
K_Global=k
%Striking first row (u1=0)
k(1,1) = 1;
for i=2:ne1+1
k(1,i) = 0;
k(ne1+1,i) = 0;
end
k(ne1+1,ne1+1) = 1;
% Display the solvable stifness matrix
K_strike=k
%solving the result and finding the displacement matrix, {u}
u=inv(k)*f
hold on
% ======Calculating Approximate Solution and plotting============
syms X
U_sym=sym(zeros(ne1,1));
dU_sym=sym(zeros(ne1,1));
for i=1:ne1
N1x=1-((X-x(i))/le);
N2x=(X-x(i))/le;
U_X=(u(i)*N1x)+(u(i+1)*N2x);
U_sym(i)=U_X;
dU_sym(i)=diff(U_sym(i));
subplot(3,1,1)
hold on
ezplot(U_sym(i),[x(i) x(i+1)])
subplot(3,1,2)
hold on
% du/dx approximate
ezplot(dU_sym(i),[x(i) x(i+1)])
end

How do I get nbit types from fread?

I have a file that is a concatenation of K, 17-bit, little endian, unsigned integers. In Matlab I am able to use fread(fd, K, 'bit17', 'ieee-le'). How do I read 17 bits off of a file descriptor in octave?
You can read the file byte by byte then use bitget to get the binary representation of data and then convert the binary representation to decimal numbers.
nbits = 17;
fd = fopen("myfile","rb");
bytes = fread(fd,Inf,"uint8=>uint8");
n = numel(bytes);
bits = false(8, n);
for k = 1:8
bits(k,:)=bitget(bytes,k);
end
count = floor(n * 8/nbits);
val = 2.^(0:nbits-1) * reshape(bits(1:count*nbits),nbits,[]);

BNF grammar definition for file path wildcard (glob)

I'm searching for some widely extended dialect (like this one https://github.com/vmeurisse/wildmatch + globstar **) described with BFN rules.
In any format or language. OMeta or PEG would be great.
I'm not sure to understand your question since the grammar for file path wildcard can be reduced to a simple regular expression. This grammar is defined by the Unix Shell.
You can find the BNF for Bash here: http://my.safaribooksonline.com/book/operating-systems-and-server-administration/unix/1565923472/syntax/lbs.appd.div.3
In Python programming language, a definition of the glob.glob() function is available in the documentation. This function use the fnmatch.fnmatch() function to perform the pattern matching. The documentation is available here: https://docs.python.org/2/library/fnmatch.html#fnmatch.fnmatch.
The fnmatch.fnmatch function translate a file path wildcard pattern to a classic regular expression, like this:
def translate(pat):
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.
"""
i, n = 0, len(pat)
res = ''
while i < n:
c = pat[i]
i = i+1
if c == '*':
res = res + '.*'
elif c == '?':
res = res + '.'
elif c == '[':
j = i
if j < n and pat[j] == '!':
j = j+1
if j < n and pat[j] == ']':
j = j+1
while j < n and pat[j] != ']':
j = j+1
if j >= n:
res = res + '\\['
else:
stuff = pat[i:j].replace('\\','\\\\')
i = j+1
if stuff[0] == '!':
stuff = '^' + stuff[1:]
elif stuff[0] == '^':
stuff = '\\' + stuff
res = '%s[%s]' % (res, stuff)
else:
res = res + re.escape(c)
return res + '\Z(?ms)'
That can help you to write de BNF grammar...
EDIT
Here is a very simple grammar:
wildcard : expr
| expr wildcard
expr : WORD
| ASTERIX
| QUESTION
| neg_bracket_expr
| pos_bracket_expr
pos_bracket_expr : LBRACKET WORD RBRACKET
neg_bracket_expr : LBRACKET EXCLAMATION WORD RBRACKET
A list of popular grammars parsed by the famous ANTLR tool is available here: http://www.antlr3.org/grammar/list.html.

How to count the number of lines in a text file in Octave?

And don't say fskipl because it doesn't work!!!
fskipl undefined.
Do you have fgetl? If so, you can do this little loop:
f = fopen('myfile.txt', 'rt');
ctr = 0;
ll = fgetl(f);
while (!isnumeric(ll)) %# fgetl returns -1 when it hits eof. But you can't do ll != -1 because blank lines make it barf
ctr = ctr+1;
ll = fgetl(f);
end
fclose(f);
Otherwise, you could do some hack like:
f = fopen('myfile.txt', 'rb');
ctr = 0;
[x, bytes] = fread(f, 8192); %# use an 8k intermediate buffer, change this value as desired
while (bytes > 0)
ctr = ctr + sum(x == 10); %# 10 is '\n'
[x, bytes] = fread(f, 8192);
end
fclose(f);
10 is the ASCII code for the newline character. But this seems unreliable, especially if you come across a file that uses carriage return instead of newline.

How to use Newton-Raphson method in matlab to find an equation root?

I am a new user of MATLAB. I want to find the value that makes f(x) = 0, using the Newton-Raphson method. I have tried to write a code, but it seems that it's difficult to implement Newton-Raphson method. This is what I have so far:
function x = newton(x0, tolerance)
tolerance = 1.e-10;
format short e;
Params = load('saved_data.mat');
theta = pi/2;
zeta = cos(theta);
I = eye(Params.n,Params.n);
Q = zeta*I-Params.p*Params.p';
% T is a matrix(5,5)
Mroot = Params.M.^(1/2); %optimization
T = Mroot*Q*Mroot;
% Find the eigenvalues
E = real(eig(T));
% Find the negative eigenvalues
% Find the smallest negative eigenvalue
gamma = min(E);
% Now solve for lambda
M_inv = inv(Params.M); %optimization
zm = Params.zm;
x = x0;
err = (x - xPrev)/x;
while abs(err) > tolerance
xPrev = x;
x = xPrev - f(xPrev)./dfdx(xPrev);
% stop criterion: (f(x) - 0) < tolerance
err = f(x);
end
% stop criterion: change of x < tolerance % err = x - xPrev;
end
The above function is used like so:
% Calculate the functions
Winv = inv(M_inv+x.*Q);
f = #(x)( zm'*M_inv*Winv*M_inv*zm);
dfdx = #(x)(-zm'*M_inv*Winv*Q*M_inv*zm);
x0 = (-1/gamma)/2;
xRoot = newton(x0,1e-10);
The question isn't particularly clear. However, do you need to implement the root finding yourself? If not then just use Matlab's built in function fzero (not based on Newton-Raphson).
If you do need your own implementation of the Newton-Raphson method then I suggest using one of the answers to Newton Raphsons method in Matlab? as your starting point.
Edit: The following isn't answering your question, but is just a note on coding style.
It is useful to split your program up into reusable chunks. In this case your root finding should be separated from your function construction. I recommend writing your Newton-Raphson method in a separate file and call this from the script where you define your function and its derivative. Your source would then look some thing like:
% Define the function (and its derivative) to perform root finding on:
Params = load('saved_data.mat');
theta = pi/2;
zeta = cos(theta);
I = eye(Params.n,Params.n);
Q = zeta*I-Params.p*Params.p';
Mroot = Params.M.^(1/2);
T = Mroot*Q*Mroot; %T is a matrix(5,5)
E = real(eig(T)); % Find the eigen-values
gamma = min(E); % Find the smallest negative eigen value
% Now solve for lambda (what is lambda?)
M_inv = inv(Params.M);
zm = Params.zm;
Winv = inv(M_inv+x.*Q);
f = #(x)( zm'*M_inv*Winv*M_inv*zm);
dfdx = #(x)(-zm'*M_inv*Winv*Q*M_inv*zm);
x0 = (-1./gamma)/2.;
xRoot = newton(f, dfdx, x0, 1e-10);
In newton.m you would have your implementation of the Newton-Raphson method, which takes as arguments the function handles you define (f and dfdx). Using your code given in the question, this would look something like
function root = newton(f, df, x0, tol)
root = x0; % Initial guess for the root
MAXIT = 20; % Maximum number of iterations
for j = 1:MAXIT;
dx = f(root) / df(root);
root = root - dx
% Stop criterion:
if abs(dx) < tolerance
return
end
end
% Raise error if maximum number of iterations reached.
error('newton: maximum number of allowed iterations exceeded.')
end
Notice that I avoided using an infinite loop.