NMinimize- objective function should be scalar-valued - wolfram-mathematica

I get the following error when trying to use the NMinimize function. See image for full code.
NMinimize::objfs: The objective function {{a (0.000081 a-0.0000169425 b-2.78856*10^-6 c)+b (-0.00001692 a+0.000025 b+0.0000113 c)+(-2.78856*10^-6 a+0.0000113 b+0.000064 c) c}} should be scalar-valued.
Okay so I figured out what the problem is but not how to fix it. The matrix multiplication happens correctly, but instead of returning a scalar, Mathematica returns a list with one item which causes an error with ArgMin. Is there any way around this without adding another function to return the first (only) item of the list? I'd rather have the matrix-vector operations return a scalar value.
enter image description here

To use your linear algebra formula define Y as a single row 2d matrix:
Y={{a,b,c}}
then you can do Y.r.Transpose[Y] . The result is a single element depth 2 array, so to get your scalar result:
(Y.r.Transpose[Y])[[1,1]]
a (0.000081 a - 0.0000169425 b - 0.0000278856 c) +
b (-0.00001692 a + 0.000025 b + 0.0000113 c) + (-2.78856*10^-6 a +
0.0000113 b + 0.000064 c) c
(This is same result as approach in comment.)

Related

Write {(+/3<?⍵⍴6)×100÷⍵}1000 tacitly

Inspired by some Conor Hoekstra YouTube videos, I tried doing some baby steps in APL and also convert my small lines to point-free style. But for this (percentage of rolls of 4, 5, or 6 in 1000 die-6 rolls) I can't wrap my head around how to eliminate the omega before the reshape.
{(+/3<?⍵⍴6)×100÷⍵}1000
Let's take it step by step:
{(+/3<?⍵⍴6)×100÷⍵}
First we need to express every part of the function that uses the argument, as a function of the argument. The multiplication combines the two main parts:
{+/3<?⍵⍴6}×{100÷⍵}
In the rightmost part, {100÷⍵}, we need the argument. There are a couple of ways we can deal with this:
We can use an identity function ⊢ to represent it: 100÷⊢
We can bind (a.k.a. curry) the left argument, 100, to the function ÷ yielding a monadic function: 100∘÷
Let's take the last approach:
{+/3<?⍵⍴6}×100∘÷
In the left part, {+/3<?⍵⍴6}, we can do the same, but need to watch out for two things, and each can be dealt with in a few different ways:
We have a constant, 6, as the rightmost part of our function.
We can change the constant into a constant function: 6⍨
We can commute (a.k.a. swap or switch) the arguments of ⍴ and use an identity function: 6⍴⍨⊢
We can bind the right argument, 6, to the function ⍴ yielding a monadic function: ⍴∘6
We have a monadic function, ?, in the middle.
We can compose ? atop ⍴: ?⍤⍴
We can compose ? beside <: <∘?
Let's take the last approach for each problem:
(+/3<∘?⍴∘6)×100∘÷
This is a fully tacit equivalent to the monadic function {(+/3<?⍵⍴6)×100÷⍵}. However, there's one more trick we can use to eliminate the parenthesis. Since × is commutative, we can swap its arguments to put the more involved expression on the right:
100∘÷×(+/3<∘?⍴∘6)
However, now we have the problem of the monadic +/ in the middle. Observe that < sees a vector on the right and a scalar on the left. In the case of F/s G v for scalar functions F and G with scalar s and vector v the inner product s F.G v is equivalent, so we can combine the summation with the comparison as follows:
100∘÷×3+.<∘?⍴∘6
Alternatively, we can observer that summation is equivalent to evaluation in base 1 because the place values in base 1 are (…,12, 11, 10) = (…, 1, 1, 1) so if we have the list (…, c, b, a) and evaluate it as a number in base 1, we get:
(… + c×12 + b×11 + a×10) =
(… + c×1 + b×1 + a×10) =
(… + c + b×1 + a×1) =
(… + c + b + a)
That is, the sum of our list. We can write this as:
100∘÷×1⊥3<∘?⍴∘6

How to find least square fit for two combined functions

I have a curvefit problem
I have two functions
y = ax+b
y = ax^2+bx-2.3
I have one set of data each for the above functions
I need to find a and b using least square method combining both the functions
I was using fminsearch function to minimize the sum of squares of errors of these two functions.
I am unable to use this method in lsqcurvefit
Kindly help me
Regards
Ram
I think you'll need to worry less about which library routine to use and more about the math. Assuming you mean vertical offset least squares, then you'll want
D = sum_{i=1..m}(y_Li - a x_Li + b)^2 + sum_{i=j..n}(y_Pj - a x_Pj^2 - b x_Pj + 2.3)^2
where there are m points (x_Li, y_Li) on the line and n points (x_Pj, y_Pj) on the parabola. Now find partial derivatives of D with respect to a and b. Setting them to zero provides two linear equations in 2 unknowns, a and b. Solve this linear system.
y = ax+b
y = ax^2+bx-2.3
In order to not confuse y of the first equation with y of the second equation we use distinct notations :
u = ax+b
v = ax^2+bx+c
The method of linear regression combined for the two functions is shown on the joint page :
HINT : If you want to find by yourself the matrixial equation appearing above, follow the Gene's answer.

Expand product of sums to a minimum sum of products

I'm trying to write a Petrick's method, which is a technique for Quine–McCluskey algorithm.
Assume I have a math equation, which consists of + and *. For example:
(K+L)(K+M)(L+N)(M+P)(N+Q)(P+Q)
How can I exand the equation to get all of the sum of products, like this?
K*K*L*M*N*P + K*K*L*M*N*Q + .... (63 terms)
(You can see the inferred result with WolframAlpha)
I somehow doubt this is what you want, but to obtain the result as an array of characters...
w = Expand[(K + L) (K + M) (L + N) (M + P) (N + Q) (P + Q)];
x = ToString#InputForm[w];
z = StringReplace[x, y_ ~~ "^2" :> StringJoin[y, "*", y]]
K*K*L*M*N*P + K*L*L*M*N*P + K*L*M*M*N*P + ... + L*M*N*P*Q*Q
DeleteCases[Characters#z, " "]
{K,*,K,*,L,*,M,*,N,*,P,+, ... ,+,L,*,M,*,N,*,P,*,Q,*,Q}
I have got fewer terms than you expected - only five rather than 63:
As Boolean expressions:
(k+l) & (l+n) & (k+m) & (m+p) & (n+q) & (p+q)
knp + lmq + lmnp + klpq + kmnq
It might be interesting to look at tha JavaScript code behind this site. It is an implementation of Petrick's method in JavaScript.
Regarding your statement
"I'm trying to write a Petrick's method, which is a technique for Quine–McCluskey algorithm."
I will show you a
ready to use implementation of Petrick's method and
also a full fledged Quine & McCluskey Implementation and
an explanation of the algorithm that I implemented
First of all, the complete solution can be found here:
MCDC
The source code is an elegant solution using set operations for an efficient implementation:
// Functor operator for applying Petricks methhod
ProductTermVector PetricksMethod::operator ()(const CNF& cnf)
{
// We select an iterative approach. Start with the first Element of the CNF (which is a DNF)
// And we store the result of each iterative operation again in this element
DNF resultingDNF{ cnf[0] };
// We will always start with the element 1 (not element 0) because in 0 is the initial value
// or respectively the intermediate result
for (CNF::size_type dnfInCnfIndex = 1; dnfInCnfIndex < cnf.size(); ++dnfInCnfIndex)
{
// Result of multipliying out the intermediate (initial) value with the current CNF Product term
DNF intermediateCalculatedDNF;
// Now go through all elements of the intermediate (initial) product term/DNF
// For (1+2)(3+4) this would be the (1+2) part
for (const ProductTerm& productTermLeftSide : resultingDNF)
{
// Next we will iterate over all Minterms in the next DNF
// For (1+2)(3+4) this would be the (3+4) part
for (const ProductTerm& productTermRightSide : cnf[dnfInCnfIndex])
{
ProductTerm productTerm{ productTermLeftSide }; // Resulting Product term is now 1
// Add all elements from the right side
productTerm.insert(productTermRightSide.begin(), productTermRightSide.end()); // Resulting Product term is now 1,2
intermediateCalculatedDNF.insert(std::move(productTerm)); // Store this one
// And continue to add more product terms. The stl::set will ensure the idempotence law and prevent memory waste
}
}
// And now add all found terms to the result and continue with the next element of the right hand side
// Please note: also here the set will prevent double terms
resultingDNF = std::move(intermediateCalculatedDNF);
}
// Now we have the result (with 10 lines of code). The result contains all product terms in DNF
// But for our prupose we are only interested in the minimum size terms
// so, lets find the element with the minimu size (can be more than one)
uint minLength{ narrow_cast<uint>(std::min_element(resultingDNF.begin(), resultingDNF.end(), [](const ProductTerm & left, const ProductTerm & right) noexcept {return left.size() < right.size(); })->size()) };
// And from the big list of the DNF with all product terms, we copy all elements having the minimu size to the result. These are our best coverage sets
ProductTermVector cheapestVector;
// Copy result and return it to caller
std::copy_if(resultingDNF.begin(), resultingDNF.end(), std::back_inserter(cheapestVector), [&minLength](const ProductTerm& pt) noexcept {return pt.size() == minLength; });
return cheapestVector;
}
The number of net lines of code is 14. There are some additional definitions used, to make understanding and usage of types easier:
using BooleanVariable = uint_fast8_t;
using ProductTerm = std::set<BooleanVariable>;
using ProductTermVector = std::vector<ProductTerm>;
// Disjunctive Normal Form
using DNF = std::set<ProductTerm>;
// Conjunctive Normal Form
using CNF = std::vector<DNF>;
class PetricksMethod // Functor
{
public:
ProductTermVector operator()(const CNF& cnf); // Functor operator
};
Please note. The type "BooleanVariable" can also be a char, a string or whatever you like. That doesn't matter for the implementation, but will have an impact on the consumed memory.
The idea behind this algorithm is to use the "STL set" and to employ properties of set operations. If you look for example at the term (a+b)(c+d): If you want to multiply this out, then the result will be: ac+ad+bc+bd. If you treat a boolean variable as a special product term with just one member and implement this product term as a set, then the operation is to just add variables to existing sets. So, if you have a set containing "a" and if you want to multiply this with the set containing "b", then you can just add "b" to "a". The set will then contain "ab".
So, we will insert the set containing "b" to the set containing "a" and so on and so on. This we will do in a loop and will get 4 sets (product terms). These 4 sets make up a resulting DNF. The just calculated DNF can be combined further with additional terms of a CNF.
If we would have "(a+b)(c+d)(e+f)", we would treat it as "((a+b)(c+d)) (e+f)". We would first multiply out the first 2 MaxTerms, get (ac+ad+bc+bd) and apply the same algorithm on (e+f). We will always add new variables to existing sets. And this we will do iteratively, until the complete expression is evaluated.
The problem is the many many resulting subterms. But luckily, here the properties of the set, with unique sorted elements will help. For (a+b)(b+a) we would get ab+aa+bb+ba. The stl set will provide the idempotence law for us. Meaning "a" AND "a" is "a", "b" or "b" is "b". So trying to add "a" to a set containing an "a" already, will not work. The result is still an "a". Same with complete product terms like 2 times "ab". They will not be added to a DNF double. So, the result of above operation is:
ab+aa+bb+ba --> ab+ab+aa+bb --> ab+aa+bb --> a+b+ab
With that approach, there will be no double terms and in general shorter terms.
But please be aware. The calculation time and the memory consumption will grow geometrically with the number of terms. So the function can only be applied with a limited number of variables / terms.
I hope I could give an understandable explanation. If you need more info, please ask.

What does this mathcad line mean?

A is a set of real numbers. Really confused as to what this line does. The numerator looks like its taking the subset of A that does not contain the smallest value. The denominator appears to be the range. How can you divide the resulting subset by the range? Or perhaps that is not what the numerator is doing?
A <- (A - min(A)) * (max(A) - min(A))^-1
^-1 means take the matrix inverse not the reciprocal
Assuming A is an matrix of real numbers, then the expression can be broken down as follows:
let mna = min(A) : Scalar - the minimum value of A
let mxa = max(A) : Scalar - the maximum value of A
let N = (A-min(A)) = Array - Scalar - each element of A minus mna
let X = (A-max(A)) ... minus mxa
so we have
N*inverse(X)
... Which would be true if I had put my glasses on and read the expression properly instead of as A <- (A - min(A)) * (A - max(A))^-1
However, as the expression is actually A <- (A - min(A)) * (max(A) - min(A))^-1, the explanation is different.
The expression for N is the same (although I note parenthetically that an expression of the form (array - scalar/conformable-array) means subtract; it is not an array element deletion operation).
However, (max(A) - min(A)) is what it looks like, the maximum value of A minus it's minimum value, and the ^-1 in this instance does mean divide.
The expression therefore returns A with all values scaled to lie between 0 (==min(A)) and 1 (==max(A)).
The <- at the start of the expression is Mathcad's local definition operator (used to assign values in a Mathcad "program") and simply assigns the normalized value of A back to A.

Matlab: replace values in one matrix with another matrix according to their referenced locations

I have two geotiff images (saying "A" and "B") imported in Matlab as matrices with Geotiffread. One has different values, while the second has only 0 and 255s.
What I'd like to do is replacing all the 255s with the values inside the other image (or matrix), according to their positions.
A and B differs in size, but they have the same projections.
I tried this:
A (A== 255)= B;
the output is the error:
??? In an assignment A(:) = B, the number of elements in A and B must be the same.
Else, I also tried with the logical approach:
if A== 255
A= B;
end
and nothing happens.
Is there a way to replace the values of A with values of B according to a specific value and the position in the referenced space?
As darthbith put in his comment, you need to make sure that the number of entries you want to replace is the same as the number values you are putting in.
By doing A(A==255)=B you are trying to put the entire matrix B into the subset of A that equals 255.
However, if, as you said, the projections are the same, you can simply do A(A==255) = B(A==255), under the assumption that B is larger or the same size as A.
Some sample code to provide a proof of concept.
A = randi([0,10],10,10);
B = randi([0,4],15,15);
C = A % copy original A matrix for comparison later
A(A==5) = B(A==5); % replace values
C==A % compare original and new
This example code creates two matrices, A is a 10x10 and B is a 15x15 and replaces all values that equal 5 in A with the corresponding values in B. This is shown to be true by doing C==A which shows where the new matrix and the old matrix vary, proving replacement did happen.
It seems to me that you are trying to mask an image with a binary mask. You can do this:
BW = im2bw(B,0.5);
A=A.*BW;
hope it helps
Try A(A==255) = B(A==255). The error is telling you that when you try to assign values to the elements of an array, you cannot give it any more or fewer values than you are trying to assign.
Also, regarding the if statement: if A==255 means the same as if all(A==255), as in, if any elements of A are not 255, false is returned. You can check this at the command line.
If you're really desperate, you can use a pair of nested for loops to achieve this (assuming A and B are the same size and shape):
[a,b] = size(A);
for ii = 1:a
for jj = 1:b
if A(ii,jj) == 255
A(ii,jj) = B(ii,jj);
end
end
end

Resources