Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
motosat
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Elphel
motosat
Commits
42caa731
Commit
42caa731
authored
Sep 08, 2019
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ported 1d polynomial approximation from Java code
parent
eca9882b
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
476 additions
and
186 deletions
+476
-186
PolynomialApproximation.php
PolynomialApproximation.php
+265
-0
test_01.php
test_01.php
+211
-186
No files found.
PolynomialApproximation.php
0 → 100644
View file @
42caa731
<?php
//require_once ('test-matrix-invert.php'); // matrix inversion
class
PolynomialApproximation
{
// function __construct() {
// }
public
$debugLevel
=
1
;
public
$debugFile
=
null
;
public
function
polynomialApproximation1d
(
$data
,
$N
){
//$my_array = array_fill(0, $size_of_the_array, $some_data);
if
(
$this
->
debugFile
===
null
){
$this
->
debugLevel
=
0
;
}
$S
=
array_fill
(
0
,
2
*
$N
+
1
,
0
);
// new double [2*N+1];
$SF
=
array_fill
(
0
,
$N
+
1
,
0
);
// new double [N+1];
for
(
$i
=
0
;
$i
<
sizeof
(
$data
);
$i
++
){
$wxn
=
(
sizeof
(
$data
[
$i
])
>
2
)
?
$data
[
$i
][
2
]
:
1.0
;
if
(
$wxn
>
0.0
){
// save time on 0.0 that can be used to mask out some samples
$f
=
$data
[
$i
][
1
];
$x
=
$data
[
$i
][
0
];
for
(
$j
=
0
;
$j
<=
$N
;
$j
++
){
$S
[
$j
]
+=
$wxn
;
$SF
[
$j
]
+=
$wxn
*
$f
;
$wxn
*=
$x
;
}
for
(
$j
=
$N
+
1
;
$j
<
2
*
$N
;
$j
++
){
$S
[
$j
]
+=
$wxn
;
$wxn
*=
$x
;
}
$S
[
2
*
$N
]
+=
$wxn
;
if
(
$this
->
debugLevel
>
1
){
if
(
sizeof
(
$data
[
$i
])
>
2
)
fprintf
(
$this
->
debugFile
,
"polynomialApproximation1d() |"
.
$i
.
"|: x=|"
.
$data
[
$i
][
0
]
.
"| f(x)=|"
.
$data
[
$i
][
1
]
.
"| (w=
\t
|"
.
$data
[
$i
][
2
]
.
"|
\t
)"
);
else
fprintf
(
$this
->
debugFile
,
"polynomialApproximation1d() |"
.
$i
,
"|: x=|"
.
$data
[
$i
][
0
]
.
"| f(x)=|"
.
$data
[
$i
][
1
]
.
"|
\t
)"
);
}
}
}
$M
=
$this
->
zeroMatrix
(
$N
+
1
,
$N
+
1
);
$B
=
$this
->
zeroMatrix
(
$N
+
1
,
1
);
for
(
$i
=
0
;
$i
<=
$N
;
$i
++
)
{
$B
[
$i
][
0
]
=
$SF
[
$i
];
for
(
$j
=
0
;
$j
<=
$N
;
$j
++
)
$M
[
$i
][
$j
]
=
$S
[
$i
+
$j
];
}
$N1
=
$N
;
// TODO: use try/catch with solve
if
(
$this
->
debugLevel
>
1
){
fprintf
(
$this
->
debugFile
,
"polynomialApproximation1d(data,"
.
$N
.
") M:
\n
"
);
$this
->
print_matrix
(
$this
->
debugFile
,
$M
);
fprintf
(
$this
->
debugFile
,
"polynomialApproximation1d() B:
\n
"
);
$this
->
print_matrix
(
$this
->
debugFile
,
$B
);
}
// while (!(new LUDecomposition(M)).isNonsingular() && (N1>0)){
$df
=
(
$this
->
debugLevel
>
2
)
?
$this
->
debugFile
:
null
;
while
(
$N1
>=
0
)
{
// make N=0 legal ?
try
{
$M_inv
=
$this
->
matrixInvert
(
$M
,
$df
);
$R
=
$this
->
mmul
(
$M_inv
,
$B
);
if
(
$this
->
debugLevel
>
1
){
fprintf
(
$this
->
debugFile
,
"polynomialApproximation1d() solution=
\n
"
);
$this
->
print_matrix
(
$this
->
debugFile
,
$R
);
}
$result
=
array_fill
(
0
,
$N
+
1
,
0
);
// new double [N+1];
for
(
$i
=
0
;
$i
<=
$N1
;
$i
++
){
$result
[
$i
]
=
$R
[
$i
][
0
];
}
return
$result
;
}
catch
(
Exception
$e
)
{
echo
'Caught exception: '
,
$e
->
getMessage
(),
", reducing polynomial order
\n
"
;
if
(
$N1
<
0
)
{
return
null
;
}
$N1
--
;
$M1
=
$this
->
zeroMatrix
(
$N
+
1
,
$N
+
1
);
$B1
=
$this
->
zeroMatrix
(
$N
+
1
,
1
);
for
(
$i
=
0
;
$i
<=
$N1
;
$i
++
)
{
$B1
[
$i
][
0
]
=
$B
[
$i
][
0
];
for
(
$j
=
0
;
$j
<=
$N1
;
$j
++
){
$M1
[
$i
][
$j
]
=
$M
[
$i
][
$j
];
}
}
$M
=
$M1
;
$B
=
$B1
;
}
}
return
null
;
}
public
function
mmul
(
$A
,
$B
){
$M
=
sizeof
(
$A
);
$N
=
sizeof
(
$A
[
0
]);
if
(
$N
!=
sizeof
(
$B
)){
throw
new
Exception
(
'DImensions mismatch.'
);
}
$K
=
sizeof
(
$B
[
0
]);
$R
=
$this
->
zeroMatrix
(
$M
,
$K
);
for
(
$i
=
0
;
$i
<
$M
;
$i
++
){
for
(
$j
=
0
;
$j
<
$K
;
$j
++
){
for
(
$k
=
0
;
$k
<
$N
;
$k
++
){
$R
[
$i
][
$j
]
+=
$A
[
$i
][
$k
]
*
$B
[
$k
][
$j
];
}
}
}
return
$R
;
}
public
function
zeroMatrix
(
$m
,
$n
=
1
){
$M
=
array_fill
(
0
,
$m
,
null
);
for
(
$i
=
0
;
$i
<
$m
;
$i
++
){
$M
[
$i
]
=
array_fill
(
0
,
$n
,
0.0
);
}
return
$M
;
}
/**
* Inverts a given matrix(downloaded from https://gist.github.com/unix1/7510208 )
*
* @param array $A matrix to invert
* @param string $debugFile if not null - output file for debug info
*
* @return array inverted matrix
*/
public
function
matrixInvert
(
$A
,
$debugFile
=
null
)
{
/// @todo check rows = columns
$n
=
count
(
$A
);
// get and append identity matrix
$I
=
$this
->
identity_matrix
(
$n
);
for
(
$i
=
0
;
$i
<
$n
;
++
$i
)
{
$A
[
$i
]
=
array_merge
(
$A
[
$i
],
$I
[
$i
]);
}
if
(
$debugFile
!==
null
)
{
fprintf
(
$debugFile
,
"
\n
Starting matrix:
\n
"
);
// echo "\nStarting matrix: ";
$this
->
print_matrix
(
$debugFile
,
$A
);
}
// forward run
for
(
$j
=
0
;
$j
<
$n
-
1
;
++
$j
)
{
// for all remaining rows (diagonally)
for
(
$i
=
$j
+
1
;
$i
<
$n
;
++
$i
)
{
// if the value is not already 0
if
(
$A
[
$i
][
$j
]
!==
0
)
{
// adjust scale to pivot row
// subtract pivot row from current
$scalar
=
$A
[
$j
][
$j
]
/
$A
[
$i
][
$j
];
for
(
$jj
=
$j
;
$jj
<
$n
*
2
;
++
$jj
)
{
$A
[
$i
][
$jj
]
*=
$scalar
;
$A
[
$i
][
$jj
]
-=
$A
[
$j
][
$jj
];
}
}
}
// if ($debug) {
if
(
$debugFile
!==
null
)
{
fprintf
(
$debugFile
,
"
\n
Forward iteration
$j
:
\n
"
);
// echo "\nForward iteration $j: ";
$this
->
print_matrix
(
$debugFile
,
$A
);
}
}
// reverse run
for
(
$j
=
$n
-
1
;
$j
>
0
;
--
$j
)
{
for
(
$i
=
$j
-
1
;
$i
>=
0
;
--
$i
)
{
if
(
$A
[
$i
][
$j
]
!==
0
)
{
$scalar
=
$A
[
$j
][
$j
]
/
$A
[
$i
][
$j
];
for
(
$jj
=
$i
;
$jj
<
$n
*
2
;
++
$jj
)
{
$A
[
$i
][
$jj
]
*=
$scalar
;
$A
[
$i
][
$jj
]
-=
$A
[
$j
][
$jj
];
}
}
}
// if ($debug) {
if
(
$debugFile
!==
null
)
{
fprintf
(
$debugFile
,
"
\n
Reverse iteration
$j
:
\n
"
);
// echo "\nReverse iteration $j: ";
$this
->
print_matrix
(
$debugFile
,
$A
);
}
}
// last run to make all diagonal 1s
/// @note this can be done in last iteration (i.e. reverse run) too!
for
(
$j
=
0
;
$j
<
$n
;
++
$j
)
{
if
(
$A
[
$j
][
$j
]
!==
1
)
{
if
(
$A
[
$j
][
$j
]
==
0.0
)
{
// echo "Denominator is zero, throwing exception: \n";
throw
new
Exception
(
'Singular matrix.'
);
}
$scalar
=
1
/
$A
[
$j
][
$j
];
for
(
$jj
=
$j
;
$jj
<
$n
*
2
;
++
$jj
)
{
$A
[
$j
][
$jj
]
*=
$scalar
;
}
}
// if ($debug) {
if
(
$debugFile
!==
null
)
{
fprintf
(
$debugFile
,
"
\n
1-out iteration
$j
:
\n
"
);
// echo "\n1-out iteration $j: ";
$this
->
print_matrix
(
$debugFile
,
$A
);
}
}
// take out the matrix inverse to return
$Inv
=
array
();
for
(
$i
=
0
;
$i
<
$n
;
++
$i
)
{
$Inv
[
$i
]
=
array_slice
(
$A
[
$i
],
$n
);
}
return
$Inv
;
}
/**
* Prints matrix
* @param resource $debugFile debug file or null
* @param array $A matrix
* @param integer $decimals number of decimals
*/
function
print_matrix
(
$debugFile
,
$A
,
$decimals
=
6
)
{
if
(
$debugFile
===
null
){
$debugFile
=
fopen
(
'php://stdout'
,
'w'
);
}
foreach
(
$A
as
$row
)
{
fprintf
(
$debugFile
,
"["
);
foreach
(
$row
as
$i
)
{
fprintf
(
$debugFile
,
"
\t
"
.
sprintf
(
"%01.
{
$decimals
}
f"
,
round
(
$i
,
$decimals
)));
}
fprintf
(
$debugFile
,
"
\t
]
\n
"
);
}
}
/**
* Produces an identity matrix of given size
*
* @param integer $n size of identity matrix
*
* @return array identity matrix
*/
function
identity_matrix
(
$n
)
{
$I
=
array
();
for
(
$i
=
0
;
$i
<
$n
;
++
$i
)
{
for
(
$j
=
0
;
$j
<
$n
;
++
$j
)
{
$I
[
$i
][
$j
]
=
(
$i
==
$j
)
?
1
:
0
;
}
}
return
$I
;
}
}
test_01.php
View file @
42caa731
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment