Mike Mc Dermott

Michael McDermott

95 Reputation

3 Badges

17 years, 281 days
Self Employed
Circuit Analysis Engineer
Kokomo, Indiana, United States

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by Mike Mc Dermott

applyGreekPrefix := proc(x)
    description
        "Accepts a number, and if it has units, a Greek prefix is added so that the coefficient is between 1 and 1000",
        "Values without units or a unit of muliple units are returned as-is"
    ;
    local prefixes, powers, coefficient, unit, exponent, new_value, idx, prefix, strUnit, newUnit, i, SIx, returnval, strSeparator, listStrUnit;

    if evalb(:-`=`(Units:-Split(x)[2], 1)) or numelems(indets(op(2, x), 'name')) > 1 then    
        # Value has no units or consists of multiple units
        returnval := x;
    else
        # Define the SI prefixes and their corresponding powers of 10
        prefixes := ["q", "r", "y", "z", "a", "f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
        powers := [seq(i, i = -30 .. 30, 3)];
    
        # Convert to SI unit w/o prefix
        SIx := convert(x, 'system', 'SI');        
        # Separate the coefficient and the unit
        coefficient := evalf(op(1, SIx));
        unit := op(2, SIx);
        strUnit := convert(unit, string);  # Convert the unit to a string representation
    
        # Calculate the exponent of 10 for the coefficient
        exponent := floor(log10(abs(coefficient)));
    
        # Find the closest power of 10 that makes the coefficient between 1 and 1000
        idx := 0;
        for i from 1 to nops(powers) do
           if exponent >= powers[i] then
               idx := i;
           end if;
        end do;
    #Unit('Omega') "Units:-Unit(`kΩ`)"
        # Adjust the coefficient based on the selected prefix
        new_value := coefficient / 10^powers[idx];
        prefix := prefixes[idx];

        # Construct the new unit using Units:-Unit if a prefix is needed
        if prefix = "" then
            newUnit := unit; # No prefix needed. Use the original unit
        else
            if StringTools:-Has(strUnit, "`") then
                # This is a greek character or other special character
                # Split the string 
                strSeparator := "(`";
            else
                strSeparator := "(";
            end if;
                
            strUnit := convert(unit, string);
            listStrUnit := StringTools:-StringSplit(strUnit, strSeparator);

            listStrUnit[2] := cat(prefix, listStrUnit[2]);
            strUnit := cat(listStrUnit[1], strSeparator, listStrUnit[2]);

            newUnit := parse(strUnit);
        end if;
        
        # Return the adjusted coefficient with the new unit
        returnval := :-`*`(new_value, newUnit);
    end if;    
    return returnval;
end proc:

if testing then 
    list_tests:=[0.0001*Unit('kV'), 10000*Unit('V'), 10*Unit('V'/'us'), 12334];
    for test in list_tests do
        print (test, "becomes", applyGreekPrefix(test));
    end do;
end if;

try Aging__CeramicCap := parse(GetProperty('TextAreaCapacitorClass2Aging', 'value')) catch: end try;

    # options for tablee displays
    optTableHeadingColor := 'fillcolor' = [153, 204, 255]:
    optMasterTableHeadingColor := 'fillcolor' = "blue":
    optsHeadingFont := 'family' = "Lucida Sans", 'bold';
    optTableFont := 'family' = "Lucida Sans";
    opTableFontSmall := 'family' = "Lucida Sans", 'size'=8;
    optTitleFont := optTableFont, 'bold', 'size'=18, 'color' = "white";    
    
ReadSpreadsheet := proc(SpreadsheetPath::string, {listHeadings := ["Description", "Min", "Nom", "Max", "Unit"], SupressOutputTable := false})
    description 
        "Reads a spreadsheet, with colums of Name, Description,    Min,    Nom,    Max,    Unit",
        "Returns a DataFrame with added columns of ""Unit"", and ""Value""",
        """Unit"" is Maple Units, and ""Value"" is a triplet of [Min, Nom, Max], where all values have units",
        "Optional Named Parameter, SupressOutputTable, suppresses display of a table of columns in 2nd parameter",
        "These columns default to [""Description"", ""Min"", ""Nom"", ""Max"", ""Unit""], if not specified";
    local df, P;
    global string2Unit, MinNomMax2Value;
    # Read the spreadseet
    try
        df := ExcelTools:-Import(SpreadsheetPath, 'output' = 'DataFrame', 'emptycell' = "-");
    catch:
        error "ReadSpreadhseet: Could not open %1", SpreadsheetPath;        
    end try;
    # Make column labels strings
    df := DataFrame(df, 'columns' = convert~(ColumnLabels(df), 'string'));
    # add column "Unit" which is maple units
    df := Append(df, DataSeries(string2Unit~(df["Unit"])), 'label' = "Maple_Unit");
    # add "Value" column for triplet
    df := Append(df, DataSeries([seq(MinNomMax2Value(df[P, () .. ()]), P in RowLabels(df))], 'labels' = RowLabels(df)), label = "Value");
     
    if not SupressOutputTable then
        CustomTabulate(df[listHeadings], _rest)
    end if;
    return df;
end proc:

I used Mathcad for several years, starting around 1985. I switched to Maple in 2016, and have been using Maple ever since. My education and experience is in Electrical Engineering, but I've developed tools for other areas such as a Go-Kart calculator, and evaluating financial data. 

@dharr 

Thanks for the reply. I'm not up on graph theory, but I think I can learn a lot studying your work.

@Carl Love 

Thanks Carl,

That's good information. I've yet to comprehend typesetting.

What I would really like is to be have a procedure accept something like and return 

@acer 

I tried to add a message to this thread with an attached worksheet yesterday, but I don't see it here.

The message from Carl Love 26292 is helpful. But I ultimately want Maple to produce results using the parallel operator using commands like the simplify function.

Here is what I am trying to do. First, I generate an expression using Maple Syrup.

* Netlist 1
I1 0 1
R1 1 2
R2 2 0
R3 1 3
R4 3 0
*RB 2 3
.end

Then I would use something like this, to simplify the expression using the parallel operator

Here is a more complicated example created from Maple Syrup and its simplification.

* More complicated expression
I1 0 1
R1 1 2
R2 2 0
R3 1 3
R4 3 0
RB 2 3
.end

Syrup produces this:

(R1*R2*R3 + R1*R2*R4 + R1*R3*R4 + R1*R3*RB + R1*R4*RB + R2*R3*R4 + R2*R3*RB + R2*R4*RB)/(R1*R2 + R1*R4 + R1*RB + R2*R3 + R2*RB + R3*R4 + R3*RB + R4*RB)

I would like to have a procedure that can simplify the above expression to this form

In this case, the expression is not only simpified by using the parallel operator, but also in a form where RB is isolated from the other variables, for ease of understanding how this variable affects the result. Because there are 5 variables, there are 5 such possible results like this, so the procedure would need to have an arguement to specify the variable to isolate. Also, this expression is written in such a way so that the result can be visually approximated as RB approaches infinity.

The expression can also be written in such a way that visual approximation can be done as RB approaches 0. Therefore, the "simplify" function would need an arguement for the desired form of the isolated variable (0 or infinity).

Thanks for the help see attachment.

@dharr 

This is what I see.

@acer 

EQ1 is an expression that can be simplified using a parallel operator, which is shown in EQ2. I see your confusion as the only way I knew to show it here is in 1D form.  I should have taken an image from my worksheet.

Ultimately, I would like the simplify function to make use of the parallel operator to simplify an expression such as EQ1 into form of EQ2. 

I need to read up on infix notation.

Your suggestion is even better.

It is my recollection that I used optimize before with what seemed to be improvement in efficiency using the cost function, but no noticable improvement in calculation speed as measured by the time[real] function. 

I will have to try again with a real-world problem.

@Carl Love 

 

with(codegen, optimize, makeproc, cost, prep2trans);
f2 := [r1 = a + b + c, r2 = a + b];
optimize(f2);
 = 
                   r1 = a + b + c, r2 = a + b

optimize(f2, tryhard);
 = 
                   r1 = a + b + c, r2 = a + b

 

@Carl Love 
That is the information I was looking for. Is is possible for maple to add more information in the error messages, like which top-level procedure produced the error?

l thought PD was a command based on the error message. 
As far as I know, i am not performing recursive calculations. That's why the error messaged confused me.

@acer 

Thanks for the answer. it's probably just as easy to create a Table from other commands. I think it would be a good feature to add to allow an optional arguement to the Tabulate command to set column widths.

1 2 Page 1 of 2